有一个应用程序可以做完全相同的事情,以下是我的见解。
首先,在编码之前您应该明智地考虑核心数据和多线程。如果您需要这方面的帮助,请告诉我。
该模型
您正在使用 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,而不是另一个对象。
--编辑结束
用户略有不同,因为他们可以参与多个对话(因为群组对话),这就是您需要多对多关系的原因。
您可以添加任意数量的属性,但这是最低要求!
- 执行
然后在你的代码中,如果你想模仿 iMessage 的行为,这就是我所做的:
在第一个控制器中,您可以在其中看到所有对话:使用 NSFetchedResultsController。查询应该仅与实体对话相关。
当单击一行时,我所做的是新视图具有对话对象和另一个 NSFtechedResultController。然后,我仅查询实体 Message,但使用谓词指定我只想要此对话。
如果您想检查我的应用程序以了解其流动性,转到此链接。 http://itunes.apple.com/us/app/klaim/id521308086
EDIT
- 用于查找对话的最后一条消息的代码片段
注意:这是在找到更好的方法之前的临时答案(即使用获取的属性时)
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