环信SDK 头像、昵称、表情自定义和群聊设置的实现 一(附源码)

来源:互联网 发布:债券行情软件 编辑:程序博客网 时间:2024/05/16 02:08

前言:

      环信的SDK在公司的项目中有用到,现在用到的是群聊的部分,这里我们分析总结一下自己对环信给的DEMO大概的拆解一下,说说我们怎么样充分的利用这个demo来写我们所需要的业务。这个也由于篇幅的原因,实在没办法写成一篇博客,我们今天先说说它的一个文件解析昵称头像的实现。写这篇博客环信也是更新到3.0版本了,我们就按照3.0的版本分析一下,先看看这整个Demo的大概的文件;

刚开始,使用这个Demo的时候,有些人不知道自己需要的到底是什么文件,一个劲的恨不得连整个Demo全都拉进来,建议大家千万不要这样子做,你花点时间好好研究一些,看一下整个Demo有哪些你是用的着的,有哪些你是用不着的,找有用的拉进自己的项目中!给大家看看我觉得你用的着的一下文件,先看这整个大文件夹EaseUI,环信的文件我用到的全都在这里了。

我自己拉到项目中的就这么多,当然这个也因需求有个具体的不同,说两个地方:

一: 关于3rdparty这个文件,这里面是第三方的文件,有些事环信二次封装的,你一定要看清楚,已经在你项目中的,建议不要再拉进来!!环信封装的一些,比如图片浏览三方这些,你要自己项目中已经存在这样功能的第三方就不要再重复拉进来。保持整个项目代码的整洁,避免混乱和一些不懂也没用的代码出现,给以后造成困难! 

二:Resources这个文件,这里面的图片我几乎是已经删除干净了,我们自己项目中的UI肯定是要自己重新写的,不能直接连图片就不改动的用环信的Demo,建议这里这样做,等你们的设计师做好相应的UI切图之后,你拿到图片再找环信对应的是那张,全局搜索这张图片的名字,找到位置,看清楚了再把自己的UI切图名称换上去!

三:说说环信SDK,因为自己的项目中还是有网易云直播SDK和支付宝微信的SDK,比较的多,这时候你一定要注意静态文件!避免这里面出现冲突!其实只要仔细点,集成环信这一步我相信大部分人都没啥问题,集成这个也不是我们今天说的重点,我们把重点放在功能解析Demo上面!

重点是这两个文件:Class 和 EaseUI 

      恩,是的,重点就是这个文件,重点都在这个文件夹当中,我们先看看Class这个文件夹当中的内容:

    说这么几点,先看到这里的话,我的给大家说一下,

一:这里的三个文件CoreData文件就是本地化的一些存储,ChatGroup是关于群聊的一些文件,剩下的几乎都在Chat这个文件夹当中了。

二:APPDelegate的几个类别,写的还是不错的,这说的不是说代码多精简,看着这里我也真的是学习到了,以后这样的话我们的支付,聊天,推送等等都可以一个功能一个功能的区分开了,简单,明了!!看看下面我们项目中的真实按照这思路写的,希望大家看了都可以学到思路,具体怎么写的,你可以看看Demo里面的代码,有问题也可以来找我!我尽我所能!

 

在说说这个 EaseUI,这么说吧,只要和界面相关的东西都在这个文件夹里面!!EaseUI这里面最重要的是ViewController这个文件夹了:

 

箭头标注出来的地方,大家注意这个继承关系!

仔细说说下面的功能:

一:头像和昵称

       给大家看看下面的效果图,这是自己我们项目中的界面截图:

好,我们说说这个昵称和头像,官方有给出这两个方法来处理头像;

方法一 从APP服务器获取昵称和头像

  • 昵称和头像的获取:当收到一条消息(群消息)时,得到发送者的用户ID,然后查找手机本地数据库是否有此用户ID的昵称和头像,如没有则调用APP服务器接口通过用户ID查询出昵称和头像,然后保存到本地数据库和缓存,下次此用户发来信息即可直接查询缓存或者本地数据库,不需要再次向APP服务器发起请求

  • 昵称和头像的更新:当点击发送者头像时加载用户详情时从APP服务器查询此用户的具体信息然后更新本地数据库和缓存。当用户自己更新昵称或头像时,也可以发送一条透传消息到其他用户和用户所在的群,来更新该用户的昵称和头像。

方法二 从消息扩展中获取昵称和头像

  • 昵称和头像的获取:把用户基本的昵称和头像的URL放到消息的扩展中,通过消息传递给接收方,当收到一条消息时,则能通过消息的扩展得到发送者的昵称和头像URL,然后保存到本地数据库和缓存。当显示昵称和头像时,请从本地或者缓存中读取,不要直接从消息中把赋值拿给界面(否则当用户昵称改变后,同一个人会显示不同的昵称)。

  • 昵称和头像的更新:当扩展消息中的昵称和头像URI与当前本地数据库和缓存中的相应数据不同的时候,需要把新的昵称保存到本地数据库和缓存,并下载新的头像并保存到本地数据库和缓存。

       这里项目采用的是方法二,通过扩展消息来添加头像和昵称:我们一句一句的实现上面的话,先实现这一条:当收到一条消息时,则能通过消息的扩展得到发送者的昵称和头像URL,然后保存到本地数据库和缓存。

     下面的两个文件是通过FMDB缓存的,通过CoreData肯定也是没有问题的,下面是缓存文件的源码文件ChatUserDataManagerHelper.h

[objc] view plain copy
  1. #import <Foundation/Foundation.h>  
  2. #import "UserInfoModel.h"  
  3. #import "FMDB.h"  
  4.   
  5. @interface ChatUserDataManagerHelper : NSObject  
  6.   
  7. /** 
  8.  保存用户数据,登录创建Model保存 
  9.   
  10.  @param userinfoDic 用户数据字典 
  11.  */  
  12. +(void)saveUserInfoModel:(UserInfoModel*)userInfo;  
  13.   
  14. /** 
  15.  保存用户数据,收到消息的扩展是字典类型,用这个方法直接保存。 
  16.   
  17.  @param userinfoDic 用户数据字典 
  18.  */  
  19. +(void)saveUserInfoDictionary:(NSDictionary *)userinfoDic;  
  20.   
  21. /** 
  22.  根据一个userID 查询一个用户数据 
  23.   
  24.  @param  userid         用户id 
  25.  @return UserInfoModel  返回一个用户Model 
  26.  */  
  27. +(UserInfoModel *)queryByuserEaseMobId:(NSString *)userid;  
  28.   
  29. @end  

 还有就是ChatUserDataManagerHelper.m文件了:

[objc] view plain copy
  1. #import "ChatUserDataManagerHelper.h"  
  2.   
  3. #define DBNAME @"cache_data.db"  
  4.   
  5. @implementation ChatUserDataManagerHelper  
  6.   
  7. /** 
  8.  类方法创建一张表单 
  9.   
  10.  @param FMDBTable FMDBTable表 
  11.  */  
  12.   
  13. +(void)createTable:(FMDatabase *)Database  
  14. {  
  15.     // 打开  
  16.     if ([Database open]) {  
  17.           
  18.         // 要是不存在UserInfo表单  
  19.         if (![Database tableExists :@"userinfo"]) {  
  20.               
  21.             // 创建这张表单,参数(用户ID,用户名称,用户头像)  
  22.             if ([Database executeUpdate:@"create table userinfo (userid text, username text, userimage text)"]) {  
  23.                   
  24.                 // NSLog(@"create table success");  
  25.                   
  26.             }else{  
  27.                   
  28.                // NSLog(@"fail to create table");  
  29.             }  
  30.               
  31.         }else {  
  32.               
  33.                // NSLog(@"table is already exist");  
  34.         }  
  35.           
  36.     // 打开失败  
  37.     }else{  
  38.           
  39.       // NSLog(@"fail to open");  
  40.     }  
  41. }  
  42.   
  43.   
  44. /** 
  45.  从userinfo清除所有信息 
  46.  
  47.  @param FMDBTable FMDBTable表 
  48.  */  
  49. + (void)clearTableData:(FMDatabase *)Database  
  50. {  
  51.     if ([Database executeUpdate:@"DELETE FROM userinfo"]) {  
  52.           
  53.         //NSLog(@"clear successed");  
  54.           
  55.     }else{  
  56.           
  57.         // NSLog(@"fail to clear");  
  58.     }  
  59. }  
  60.   
  61.   
  62. /** 
  63.  获取FMDatabase 
  64.   
  65.  @return FMDatabase 
  66.  */  
  67. +(FMDatabase*)getFMDB{  
  68.       
  69.     NSString   *  docsPath   = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];  
  70.     NSString   *  FMDBPath   = [docsPath stringByAppendingPathComponent:DBNAME];  
  71.     FMDatabase *  Database   = [FMDatabase databaseWithPath:FMDBPath];  
  72.     [self createTable:Database];  
  73.     return Database;  
  74. }  
  75.   
  76.   
  77. /** 
  78.  保存用户Model 
  79.  
  80.  @param userInfo userInfo description 
  81.  */  
  82. +(void)saveUserInfoModel:(UserInfoModel*)userInfo{  
  83.       
  84.     [ChatUserDataManagerHelper SaveUserInfoWithUserEaseMobId:userInfo.userEaseMobId andUserHeaderImageUrl:userInfo.userHeaderImageUrl andUserNickName:userInfo.usernickName];  
  85. }  
  86.   
  87.   
  88. /** 
  89.  根据创建的用户数据Model,保存用户信息 
  90.  
  91.  @param easeMobId 用户ID 
  92.  @param imageUrl  用户头像 
  93.  @param nickName  用户昵称 
  94.  */  
  95.   
  96. +(void)SaveUserInfoWithUserEaseMobId:(NSString *)easeMobId andUserHeaderImageUrl:(NSString*)imageUrl andUserNickName:(NSString*)nickName{  
  97.       
  98.       
  99.     NSMutableDictionary * userDic = [NSMutableDictionary dictionary];  
  100.       
  101.     [userDic setValue:easeMobId forKey:CHATUSERID];  
  102.     [userDic setValue:imageUrl  forKey:CHATUSRTHEADIMAGE];  
  103.     [userDic setValue:nickName  forKey:CHATUSERNICK];  
  104.       
  105.     [ChatUserDataManagerHelper saveUserInfoDictionary:userDic];  
  106. }  
  107.   
  108.   
  109. /** 
  110.  保存用户数据 
  111.  
  112.  @param userinfoDic 用户数据字典 
  113.  */  
  114. +(void)saveUserInfoDictionary:(NSDictionary *)userinfoDic{  
  115.       
  116.     FMDatabase *  dataBase = [self getFMDB];  
  117.       
  118.     NSString   *  userid   = [userinfoDic objectForKey:CHATUSERID];  
  119.       
  120.     if ([dataBase executeUpdate:@"DELETE FROM userinfo where userid = ?", userid]) {  
  121.           
  122.         debugLog(@"删除成功");  
  123.           
  124.     }else{  
  125.           
  126.         debugLog(@"删除失败");  
  127.     }  
  128.       
  129.     NSString *username  = [userinfoDic objectForKey:CHATUSERNICK];  
  130.     NSString *userimage = [userinfoDic objectForKey:CHATUSRTHEADIMAGE];  
  131.     if ([dataBase executeUpdate:@"INSERT INTO userinfo (userid, username, userimage) VALUES (?, ?, ?)", userid,username,userimage]) {  
  132.           
  133.         debugLog(@"插入成功");  
  134.           
  135.     }else{  
  136.           
  137.         debugLog(@"插入失败");  
  138.     }  
  139.       
  140.     //  NSLog(@"%d: %@", [db lastErrorCode], [db lastErrorMessage]);  
  141.     FMResultSet *rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo where userid = ?",userid];  
  142.       
  143.     if ([rs next]) {  
  144.           
  145.         NSString * userid    = [rs stringForColumn:@"userid"];  
  146.         NSString * username  = [rs stringForColumn:@"username"];  
  147.         NSString * userimage = [rs stringForColumn:@"userimage"];  
  148.         debugLog(@"查询一个 %@ %@ %@",userid,username,userimage);  
  149.     }  
  150.       
  151.     rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo"];  
  152.     while ([rs next]) {  
  153.         NSString * userid    = [rs stringForColumn:@"userid"];  
  154.         NSString * username  = [rs stringForColumn:@"username"];  
  155.         NSString * userimage = [rs stringForColumn:@"userimage"];  
  156.           
  157.         debugLog(@"查询所有 %@ %@ %@",userid,username,userimage);  
  158.     }  
  159.       
  160.     [rs close];  
  161.       
  162.     // NSLog(@"%d: %@", [db lastErrorCode], [db lastErrorMessage]);  
  163.     [dataBase close];  
  164. }  
  165.   
  166.   
  167. /** 
  168.  根据一个userID 查询一个用户数据 
  169.  
  170.  @param  userid         用户id 
  171.  @return UserInfoModel  返回一个用户Model 
  172.  */  
  173.   
  174. +(UserInfoModel *)queryByuserEaseMobId:(NSString *)userid {  
  175.       
  176.     FMDatabase * dataBase     = [self getFMDB];  
  177.       
  178.     if ([dataBase open]) {  
  179.           
  180.         FMResultSet *rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo where userid = ?",userid];  
  181.           
  182.         if ([rs next]) {  
  183.               
  184.             UserInfoModel * userInfo = [[UserInfoModel alloc] init];  
  185.               
  186.             userInfo.userEaseMobId      = [rs stringForColumn:@"userid"];  
  187.             userInfo.usernickName       = [rs stringForColumn:@"username"];  
  188.             userInfo.userHeaderImageUrl = [rs stringForColumn:@"userimage"];  
  189.               
  190.             debugLog(@"查询一个 %@",userInfo);  
  191.             return userInfo;  
  192.               
  193.         }else{  
  194.               
  195.             return nil;  
  196.         }  
  197.     }else{  
  198.           
  199.         return nil;  
  200.     }  
  201. }  
  202.   
  203. @end  

注意: 通过上面的代码,你就实现了存储的功能。不过你的记着,在登录成功之后你得先把自己的信息存储起来,在更改了个人资料之后,你要更新这里的存储信息。

我们再说这个发送消息的时候,把自己的个人信息附加在扩展消息当中发送出去,这里我们就用发送文本消息为例子,其他的都一样:

你找到EaseSDKHelper.m这个文件,这里面有这个方法

+(EMMessage *)sendTextMessage:(NSString *)text  to:(NSString *)toUser  messageType:(EMChatType)messageType  messageExt:(NSDictionary *)messageExt

说说这里,这个你看看Demo的话你就可以看到,所有的信息发送都是EaseSDKHelper这个类发送的,由于这个EaseMessageViewController控制器已经代码行数够多了,就不要再在这里添加了,写在EaseSDKHelper,在EaseMessageViewController中有下面这个方法,这个方法就是发送消息的

- (void)_sendMessage:(EMMessage *)message

看看EaseSDKHelper.m中我们怎样添加扩展消息发送的

[objc] view plain copy
  1. #pragma mark - send message  
  2. +(EMMessage *)sendTextMessage:(NSString *)text  
  3.                             to:(NSString *)toUser  
  4.                    messageType:(EMChatType)messageType  
  5.                     messageExt:(NSDictionary *)messageExt{  
  6.   
  7.     NSMutableDictionary * extDictionary = nil;  
  8.     // 这里要加判断,因为群聊消息的扩展和直播聊天室的扩展会冲突  
  9.     if (messageType == EMChatTypeGroupChat) {  
  10.           
  11.        //这是为了区分一下表情的扩展消息  
  12.         if (!messageExt) {  
  13.               
  14.             extDictionary = [self reGetMessageExt];  
  15.               
  16.         }else{  
  17.   
  18.             //扩展消息字典  
  19.             extDictionary = [[NSMutableDictionary alloc]initWithDictionary:messageExt];  
  20.             [extDictionary addEntriesFromDictionary:[self reGetMessageExt]];  
  21.        
  22.         }  
  23.     }  
  24.   
  25.     NSString *willSendText = [EaseConvertToCommonEmoticonsHelper convertToCommonEmoticons:text];  
  26.     EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:willSendText];  
  27.     NSString *from = [[EMClient sharedClient] currentUsername];  
  28.     EMMessage *message = [[EMMessage alloc] initWithConversationID:toUser from:from to:toUser body:body ext:extDictionary];  
  29.     message.chatType = messageType;  
  30.     return message;  
  31. }  
  32.   
  33. // 获取消息扩展,这里不要纠结,我这里只是去了一下自己本地存储的个人信息,你把自己的取出来拼成一个字 // 典返回就可以了  
  34. +(NSMutableDictionary*)reGetMessageExt{  
  35.       
  36.     NSMutableDictionary *extDic = [NSMutableDictionary dictionary];  
  37.     NSString * userId = [NSString stringWithFormat:@"%@",READUSERDEFAULTS(UserId)];  
  38.     [extDic setValue:userId forKey:CHATUSERID];  
  39.     [extDic setValue:READUSERDEFAULTS(UserName) forKey:CHATUSERNICK];  
  40.     [extDic setValue:READUSERDEFAULTS(UserHeadImage) forKey:CHATUSRTHEADIMAGE];  
  41.     return extDic;  
  42. }  

最后就是接收到之后的赋值了,在这里进行ChatViewController.m中来写,这里面又有一个方法

- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController  modelForMessage:(EMMessage *)message

看下面这个方法的完整代理:

[objc] view plain copy
  1. #pragma mark - EaseMessageViewControllerDataSource  
  2. // 数据源方法  
  3. - (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController  
  4.                            modelForMessage:(EMMessage *)message{  
  5.       
  6.     id<IMessageModel> model = nil;  
  7.     // 根据聊天消息生成一个数据源Model  
  8.     //NSLog(@"-======%@",message.from);  
  9.     //debugObj(message.ext);  
  10.       
  11.     model = [[EaseMessageModel alloc] initWithMessage:message];  
  12.     NSDictionary * messageDic = message.ext;  
  13.       
  14.     UserInfoModel * userinfoModel = [ChatUserDataManagerHelper queryByuserEaseMobId:messageDic[CHATUSERID]];  
  15.       
  16.     if (userinfoModel != nil) {  
  17.           
  18.         model.nickname      = userinfoModel.usernickName;  
  19.         model.avatarURLPath = userinfoModel.userHeaderImageUrl;  
  20.     }  
  21.     // 默认头像  
  22.     //model.avatarImage = [UIImage imageNamed:@"EaseUIResource.bundle/user"];  
  23.     //Placeholder image for network error  
  24.     //项目图片取出错误的时候就用这张代替  
  25.     model.failImageName = @"icon_Default-Avatar";  
  26.     return model;  
  27. }  
阅读全文
0 0