其实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里。同理,发消息的时候也需要在本地保存一份。
好了,先分享这么多,计划明天继续讲消息列表以及发消息的实现。