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

其实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里。同理,发消息的时候也需要在本地保存一份。

好了,先分享这么多,计划明天继续讲消息列表以及发消息的实现。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值