使用 Core Data 设计聊天应用程序

2024-03-31

我正在编写一个聊天应用程序,并且正在更改我的数据库以使用核心数据。我目前直接使用 sqlite,但我想利用 iCloud 功能,所以我要切换引擎。

我的主表称为 Entry ,具有以下属性:

NSInteger type;
NSDate* timestamp;
NSString* username;
NSString* session;
NSString* body;

其中“类型”可以是:

1 - message
2 - file transfer (which then 'body' represents a file name in the documents folder)
3 - user joined
4 - user left

我的应用程序还支持多用户聊天(这就是为什么“用户加入”/“用户离开”类型)。所有消息都属于同一个对话(仅限多聊天),将具有有效的“会话”属性。

在我的聊天记录中,我的问题是如何实现“加载更多”,就像苹果在短信应用程序中所做的那样:我将根据'username=%@ AND session IS NULL' or 'session=%@'显示该历史记录并使用按反向“时间戳”排序的 LIMIT 50。 然后我想要一个“加载更多”按钮来加载接下来的 50 条消息 - 我不知道如何使用 Core Data 来做到这一点。

我的下一个问题是如何显示对话列表。现在,使用原始 sqlite,我对 2 个查询执行联接:第一个是每个用户的最后一条消息,第二个是每个多用户对话的最后一条消息。然后我按日期对它们进行排序。 由于核心数据不支持联接,我不确定如何执行此查询。

Thanks


有一个应用程序可以做完全相同的事情,以下是我的见解。

首先,在编码之前您应该明智地考虑核心数据和多线程。如果您需要这方面的帮助,请告诉我。

该模型

您正在使用 Coredata 中的实体,可以将其视为 sqlite 中的表,但以更抽象的方式。你应该查看苹果的文档 http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/coredata/Articles/cdBasics.html#//apple_ref/doc/uid/TP40001650-TP1为了那个原因。

我们可以在您的案例中找到至少三个不同的实体:用户、对话和消息。 (要小心最后一个,我在导入 SMS 框架时遇到了名为 Message 的实体的问题,您应该考虑为实体名称添加前缀..)

coredata 的一个问题是你不能直接存储数组(可能是某种未知类型),但无论如何。因此,有两种存储用户的解决方案:要么在 NSString 中,当它们用逗号分隔时,一个简单的正则表达式或 split 将为您提供用户数量。

所以你的模型可能看起来像:

Conversation{
     messages<-->>Message.conversation
     lastMessage<-->Message.whateverName
     //optional
     users<<-->>User.conversation
}

Message{
    conversation<<-->Conversation.messages
    whatevername<-->Conversation.lastmessage // "whatever as it does not really matter"
}

User{
    conversations<<-->>Conversation.users
}

对话必须与消息具有一对多关系,并且消息与对话必须具有一对一关系。

--EDIT

如果您想像消息应用程序(或我的应用程序)一样显示对话的最后一条消息,您可以添加与消息的关系。它不会在数据库/核心数据中存储两次消息。事实上,您创建了一个 coredata 对象(在本例中是一条消息)并将其添加到对话中,其中发生的情况是对话存储该对象的 coredata ID。为此消息(lastMessage)添加一个关系只会存储另一个 ID,而不是另一个对象。

--编辑结束

用户略有不同,因为他们可以参与多个对话(因为群组对话),这就是您需要多对多关系的原因。

您可以添加任意数量的属性,但这是最低要求!

  1. 执行

然后在你的代码中,如果你想模仿 iMessage 的行为,这就是我所做的:

在第一个控制器中,您可以在其中看到所有对话:使用 NSFetchedResultsController。查询应该仅与实体对话相关。

当单击一行时,我所做的是新视图具有对话对象和另一个 NSFtechedResultController。然后,我仅查询实体 Message,但使用谓词指定我只想要此对话。

如果您想检查我的应用程序以了解其流动性,转到此链接。 http://itunes.apple.com/us/app/klaim/id521308086

EDIT

  1. 用于查找对话的最后一条消息的代码片段

注意:这是在找到更好的方法之前的临时答案(即使用获取的属性时)

NSFetchRequest * req = [[NSFetchRequest alloc] init];
[req setEntity:[NSEntityDescription entityForName:@"Message" inManagedObjectContext:context]];
[req setPredicate:[NSPredicate predicateWithFormat:@"conversation == %@", self]]; /* did that from a Conversation object.. */
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"sent_date" ascending:NO];
[req setSortDescriptors:[NSArray arrayWithObject:sort]];

[sort release];
NSError * error = nil;
NSArray * messages = [context executeFetchRequest:req error:&error];
[req release];
if ([messages count] > 0) { /* sanity check */
    return [messages objectAtIndex:0];
}
return nil;

--编辑结束

希望这有帮助!

Pierre

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Core Data 设计聊天应用程序 的相关文章

  • 如何获取 UIWebView 中元素的位置?

    我在 iPad 程序中加载了 html 的 UIWebView 通过使用 webkit column width 我将 html 分为几列 padding 0px height 1024px webkit column gap 0px we
  • [UIScreen mainScreen].bounds.size 在 iOS8 中变得依赖于方向吗?

    我在 iOS 7 和 iOS 8 中运行了以下代码 UIInterfaceOrientation orientation UIApplication sharedApplication statusBarOrientation BOOL l
  • iPhone,如何隐藏标签栏按钮?

    如何隐藏单个标签栏按钮 我已经搜索过 但什么也没找到 只找到了完整的栏 我已经取得了一些进展 但仍然遇到问题 此代码位于我的应用程序委托中 带有选项卡栏的出口 我在其中调用它viewDidLoad选项卡栏中显示的第一个视图的视图 void
  • Obj-C / Swift 项目中的致命陷阱异常

    我开始将 Swift 代码集成到我的 Obj C 项目中 一切都进展顺利 但今天 当我更新到 Xcode 6 1 时 事情变得很糟糕 我从之前运行良好的 Swift 代码中收到了许多 陷阱 异常 第一次崩溃位于我的 UIFont 扩展中 这
  • 如何消除禁用的 UIButton 的灰色外观

    我有一个 UIButton 我希望它处于禁用状态时与处于正常状态时看起来完全相同 现在它看起来有点灰色 不要使用enabled属性或setEnabled NO方法 而是使用 myButton setUserInteractionEnable
  • 如何使用 Objective-C 协议

    我需要将 Picker 选择的值继承到其他地方 我正在尝试下面的代码 但空值即将到来 请检查我哪里出错了 我必须继承在中传递的字符串值PickerView 请检查代码 选取器1 h import
  • 如何从通讯录 ios 以编程方式编辑电话号码值

    我正在尝试在 iOS 中以编程方式替换特定联系人的特定电话号码 获取联系人表单地址簿 我不知道为什么我无法保存新的电话号码并刷新地址簿以显示更改 我正在这样做 BOOL changeContactPhoneNumber NSString p
  • 如何将设备令牌和应用程序版本发送到服务器

    我已经实现将设备令牌和应用程序版本发送到 serverm 它在模拟器 硬编码数据 中工作正常 但在设备中无法工作 任何形式的帮助将不胜感激 先感谢您 这是代码 void application UIApplication applicati
  • 就SQL注入而言,哪种sql查询更安全

    我有两个 SQL 查询正在尝试更新sup and opp每次调用查询时 值分别为 1 和 1 第一个查询 query update disc set sup sup opp opp where did did int sup getnoof
  • MySQL 中的创建/写入权限

    我的设备遇到一些权限问题SELECT INTO OUTFILE陈述 当我登录数据库并执行简单的导出命令时 例如 mysql gt select from XYZ into outfile home mropa Photos Desktop
  • iOS崩溃核心位置CFBasicHashCreateCopy?

    我已经通过 Crashlytics 报告了这个问题 尽管我无法在本地复制它 所以除了下面的堆栈跟踪之外我没有什么可做的 不确定堆栈跟踪中是否引用了 CoreLocation与它有任何关系 但我不确定可能是什么原因 我的项目使用的是ARC 有
  • NSURLConnection 的 URL 文件大小 - Swift

    我想在下载之前从 url 获取文件大小 这是 obj c 代码 NSURL URL NSURL URLWithString ExampleURL NSMutableURLRequest request NSMutableURLRequest
  • 如何在 Swift 中调用 Objective-C 实例类型方法?

    我有一个 Objective C 类 如下所示 interface CustomObjectHavingData NSObject property nonatomic strong NSData objWithData instancet
  • CoreBluetooth:如何为许多特性(30 - 40)设计代码?

    我搜索了一下 发现这是一个可能重复的问题 同一设备的多个 CBPeripheral https stackoverflow com questions 10836703 multiple cbperipherals for same dev
  • APNS(Apple 推送通知服务器)的反馈服务

    我们正在使用Java作为推送通知提供商APNS I我能够将消息发送到APNS但我不知道如何获得该消息的反馈 请帮忙 反馈服务具有类似于用于发送推送通知的接口的二进制接口 您可以通过以下方式访问生产反馈服务feedback push appl
  • 每次 UIScrollView 释放时都会发生内存泄漏

    在我的应用程序中 我有一个滚动视图和四个表格视图 每次拖动然后释放时 我都会泄漏 48 字节 这确实很重要 正如您所看到的 两组泄漏都有相同的来源 有人见过这样的泄漏吗 Edit 1 当我单击泄漏旁边的箭头时 我会得到泄漏的以下信息 您所看
  • 客户端应用程序立即对数据库中的更新做出反应的最佳方式是什么?

    对数据库中的数据更新做出立即反应的最佳方法是什么 我能立即想到的最简单的方法是一个线程 它检查数据库中某些数据的特定更改 并持续等待在某个预定义的时间长度内再次检查它 这个解决方案对我来说似乎是浪费和次优的 所以我想知道是否有更好的方法 我
  • 如何在 iOS Swift 中获取来电的电话号码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想在我的应用程序中获取来电者的电话号码 请有人迅速为我提供这个问题的解决方案 您将永远无法获得来电的电话号码 因为这是用户的私人数据
  • 如何判断handleOpenURL是在应用程序启动时调用还是在应用程序运行时调用?

    由于事件的顺序略有不同 具体取决于这两个场景中的哪一个正在进行 我希望能够区分出区别 有什么建议么 你不应该使用handleOpenURL因为它已被弃用 相反 使用application openURL sourceApplication
  • iTunes Connect 中缺少应用内购买部分

    我有一个应用程序处于准备提交状态 我还有该应用程序的应用程序内购买项目 上周我将它们链接到我的应用程序并提交以供审核 周末 开发商拒绝了它 现在我想重新提交修复后的版本 但 IAP 部分完全丢失 我怎样才能让它再次可见 我遇到过同样的问题

随机推荐