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

Gil*_*vik 8 database iphone core-data ios

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

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

NSInteger type;
NSDate* timestamp;
NSString* username;
NSString* session;
NSString* body;
Run Code Online (Sandbox Code Playgroud)

'type'可以是:

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

我的应用程序还支持多用户聊天(因此'用户加入'/'用户离开'类型的原因).所有消息属于同一个对话(仅限多个聊天),将具有有效的"会话"属性.

在我的聊天历史中,我的问题是如何实现像苹果在短信应用程序中所做的那样"加载更多":我将根据'username=%@ AND session IS NULL''session=%@'显示该历史进行查询,并使用由反向'时间戳'排序的限制为50.然后我想要一个"加载更多"按钮,它将加载接下来的50条消息 - 我不知道如何使用Core Data.

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

谢谢

Pie*_*rre 14

有一个完全相同的应用程序,这是我的见解.

首先,您应该在编码之前明智地考虑coredata和多线程.如果您需要帮助,请告诉我.

该模型

您正在使用Coredata中的实体,它们可以被视为sqlite中的表,但是以更抽象的方式.您应该查看Apple的文档.

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

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

所以你的模型看起来像:

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
}
Run Code Online (Sandbox Code Playgroud)

对话必须与Message和Message具有to-many关系,以及与Conversation的一对一关系.

- 编辑

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

- 编辑结束

用户略有不同,因为它们可以成为多个对话的一部分(因为群组对话),这就是您需要多对多关系的原因.

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

  1. 履行

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

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

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

如果您想检查我的应用程序以查看流动性,请转到此链接.

编辑

  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;
Run Code Online (Sandbox Code Playgroud)

- 编辑结束

希望这有帮助!

皮埃尔