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,而不是另一个对象.
- 编辑结束
用户略有不同,因为它们可以成为多个对话的一部分(因为群组对话),这就是您需要多对多关系的原因.
您可以根据需要添加任意数量的属性,但这是最低要求!
然后在你的代码中,如果你想模仿iMessage的行为,这就是我所做的:
在第一个控制器中,您可以看到所有对话:使用NSFetchedResultController.查询应仅与实体对话有关.
单击一行时,我所做的是新视图具有会话对象和另一个NSFtechedResultController.然后,我只查询实体Message,但使用谓词指定我只想要这个对话.
如果您想检查我的应用程序以查看流动性,请转到此链接.
编辑
注意:这是一个临时的答案,然后才能找到更好的方法(即使用获取的属性时)
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)
- 编辑结束
希望这有帮助!
皮埃尔