您的位置:首页 > 移动开发 > 微信开发

仿微信/QQ 开发基于XMPP的iPhone/iOS聊天客户端(三)CoreData

2014-02-23 00:09 691 查看
其实CoreData也不是什么新东西的了,会的同学可以忽略本文,只是小弟一直比较习惯直接操作sqlite(或使用FMDB),一下子不习惯用CoreData,也就粗略把自己一些体会分享一下而已。

关于CoreData,小弟觉得写的比较浅显易懂的一篇文章
http://www.cnblogs.com/xiaodao/archive/2012/10/08/2715477.html
至于在XMPPFramwork里面,使用了CoreData来临时保存Roster花名册(好友列表),个人信息等东西。

为什么说“临时”呢?因为貌似木有做持久化操作,也就是没有写入客户端sqlite里。

小弟对XMPPFramework进行二次开发,需要实现消息收发功能,肯定要做数据持久化操作。

首先,为Message建实体,打开XMPPFramework-Extensions-Roster-CoreDataStorage的XMPPRoster,增加个实体XMPPMessageCoreDataStorageObject,增加字段如下



然后在AppDelegate.h加上

//持久性存储区
@property(strong,nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;


在.m加上

-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}

//得到数据库的路径
NSString *docs = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
//CoreData是建立在SQLite之上的,数据库名称需与Xcdatamodel文件同名
NSURL *storeUrl = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite", @"XMPPMessage"]]];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:[self managedObjectModel]];

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
NSLog(@"Error: %@,%@",error,[error userInfo]);
}

return persistentStoreCoordinator;
}


然后在消息接受的方法

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage
*)message
加上

if ([message isChatMessageWithBody])
{
//added by cyrus
XMPPMessageCoreDataStorageObject *messageObj = (XMPPMessageCoreDataStorageObject *)[NSEntityDescription insertNewObjectForEntityForName:@"XMPPMessageCoreDataStorageObject" inManagedObjectContext:[self managedObjectContext_message]];

[messageObj setMessageFrom:[self getJidStrWithoutResource:message.fromStr]];
[messageObj setMessageTo:[self getJidStrWithoutResource:message.toStr]];
[messageObj setMessageContent:message.body];
[messageObj setMessageType:[NSNumber numberWithInt:0]];
//离线消息取时间戳,在线消息取本地时间
NSDate *date=[self getDelayStampTime:message];
if (date) {
[messageObj setMessageDate:date];
}else{
[messageObj setMessageDate:[NSDate date]];
}
//判断消息类型是文本、图片还是语音
[messageObj setMessageType:[NSNumber numberWithInt:[self getMessageType:message.body]]];

NSError *error;

//托管对象准备好后,调用托管对象上下文的save方法将数据写入数据库
BOOL isSaveSuccess = [[self managedObjectContext_message] save:&error];

if (!isSaveSuccess) {
NSLog(@"保存聊天记录失败: %@,%@",error,[error userInfo]);
}else {
NSLog(@"保存聊天记录成功");
}
}


其中自定义方法

-(NSString *)getJidStrWithoutResource:(NSString *)target;
{
NSRange range=[target rangeOfString:@"/"];
if(range.location!=NSNotFound)
{
target=[target substringToIndex:range.location];
}
return target;
}

-(NSDate *)getDelayStampTime:(XMPPMessage *)message
{
XMPPElement *delay=(XMPPElement *)[message elementForName:@"delay"];
if (delay) {
NSString *timeString=[[(XMPPElement *)[message elementForName:@"delay"] attributeForName:@"stamp"] stringValue];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSArray *arr=[timeString componentsSeparatedByString:@"T"];
NSString *dateStr=[arr objectAtIndex:0];
NSString *timeStr=[[[arr objectAtIndex:1] componentsSeparatedByString:@"."] objectAtIndex:0];
NSDate *localDate = [dateFormatter dateFromString:[NSString stringWithFormat:@"%@T%@+0000",dateStr,timeStr]];
return localDate;
}else{
return nil;
}
}


至于getMessageType,就要看你们协议规定的格式了,这里就不具体列出了。

这样在每收到消息的时候,都能通过CoreData把数据存进sqlite里。同理,发消息的时候也需要在本地保存一份。

好了,先分享这么多,计划明天继续讲消息列表以及发消息的实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: