使用 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 设计聊天应用程序 的相关文章

随机推荐