前言:

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

还有就是ChatUserDataManagerHelper.m文件了:

[objc] view plaincopy
  1. #import "ChatUserDataManagerHelper.h"
  2. #define DBNAME @"cache_data.db"
  3. @implementation ChatUserDataManagerHelper
  4. /**
  5. 类方法创建一张表单
  6. @param FMDBTable FMDBTable表
  7. */
  8. +(void)createTable:(FMDatabase *)Database
  9. {
  10. // 打开
  11. if ([Database open]) {
  12. // 要是不存在UserInfo表单
  13. if (![Database tableExists :@"userinfo"]) {
  14. // 创建这张表单,参数(用户ID,用户名称,用户头像)
  15. if ([Database executeUpdate:@"create table userinfo (userid text, username text, userimage text)"]) {
  16. // NSLog(@"create table success");
  17. }else{
  18. // NSLog(@"fail to create table");
  19. }
  20. }else {
  21. // NSLog(@"table is already exist");
  22. }
  23. // 打开失败
  24. }else{
  25. // NSLog(@"fail to open");
  26. }
  27. }
  28. /**
  29. 从userinfo清除所有信息
  30. @param FMDBTable FMDBTable表
  31. */
  32. + (void)clearTableData:(FMDatabase *)Database
  33. {
  34. if ([Database executeUpdate:@"DELETE FROM userinfo"]) {
  35. //NSLog(@"clear successed");
  36. }else{
  37. // NSLog(@"fail to clear");
  38. }
  39. }
  40. /**
  41. 获取FMDatabase
  42. @return FMDatabase
  43. */
  44. +(FMDatabase*)getFMDB{
  45. NSString   *  docsPath   = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
  46. NSString   *  FMDBPath   = [docsPath stringByAppendingPathComponent:DBNAME];
  47. FMDatabase *  Database   = [FMDatabase databaseWithPath:FMDBPath];
  48. [self createTable:Database];
  49. return Database;
  50. }
  51. /**
  52. 保存用户Model
  53. @param userInfo userInfo description
  54. */
  55. +(void)saveUserInfoModel:(UserInfoModel*)userInfo{
  56. [ChatUserDataManagerHelper SaveUserInfoWithUserEaseMobId:userInfo.userEaseMobId andUserHeaderImageUrl:userInfo.userHeaderImageUrl andUserNickName:userInfo.usernickName];
  57. }
  58. /**
  59. 根据创建的用户数据Model,保存用户信息
  60. @param easeMobId 用户ID
  61. @param imageUrl  用户头像
  62. @param nickName  用户昵称
  63. */
  64. +(void)SaveUserInfoWithUserEaseMobId:(NSString *)easeMobId andUserHeaderImageUrl:(NSString*)imageUrl andUserNickName:(NSString*)nickName{
  65. NSMutableDictionary * userDic = [NSMutableDictionary dictionary];
  66. [userDic setValue:easeMobId forKey:CHATUSERID];
  67. [userDic setValue:imageUrl  forKey:CHATUSRTHEADIMAGE];
  68. [userDic setValue:nickName  forKey:CHATUSERNICK];
  69. [ChatUserDataManagerHelper saveUserInfoDictionary:userDic];
  70. }
  71. /**
  72. 保存用户数据
  73. @param userinfoDic 用户数据字典
  74. */
  75. +(void)saveUserInfoDictionary:(NSDictionary *)userinfoDic{
  76. FMDatabase *  dataBase = [self getFMDB];
  77. NSString   *  userid   = [userinfoDic objectForKey:CHATUSERID];
  78. if ([dataBase executeUpdate:@"DELETE FROM userinfo where userid = ?", userid]) {
  79. debugLog(@"删除成功");
  80. }else{
  81. debugLog(@"删除失败");
  82. }
  83. NSString *username  = [userinfoDic objectForKey:CHATUSERNICK];
  84. NSString *userimage = [userinfoDic objectForKey:CHATUSRTHEADIMAGE];
  85. if ([dataBase executeUpdate:@"INSERT INTO userinfo (userid, username, userimage) VALUES (?, ?, ?)", userid,username,userimage]) {
  86. debugLog(@"插入成功");
  87. }else{
  88. debugLog(@"插入失败");
  89. }
  90. //  NSLog(@"%d: %@", [db lastErrorCode], [db lastErrorMessage]);
  91. FMResultSet *rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo where userid = ?",userid];
  92. if ([rs next]) {
  93. NSString * userid    = [rs stringForColumn:@"userid"];
  94. NSString * username  = [rs stringForColumn:@"username"];
  95. NSString * userimage = [rs stringForColumn:@"userimage"];
  96. debugLog(@"查询一个 %@ %@ %@",userid,username,userimage);
  97. }
  98. rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo"];
  99. while ([rs next]) {
  100. NSString * userid    = [rs stringForColumn:@"userid"];
  101. NSString * username  = [rs stringForColumn:@"username"];
  102. NSString * userimage = [rs stringForColumn:@"userimage"];
  103. debugLog(@"查询所有 %@ %@ %@",userid,username,userimage);
  104. }
  105. [rs close];
  106. // NSLog(@"%d: %@", [db lastErrorCode], [db lastErrorMessage]);
  107. [dataBase close];
  108. }
  109. /**
  110. 根据一个userID 查询一个用户数据
  111. @param  userid         用户id
  112. @return UserInfoModel  返回一个用户Model
  113. */
  114. +(UserInfoModel *)queryByuserEaseMobId:(NSString *)userid {
  115. FMDatabase * dataBase     = [self getFMDB];
  116. if ([dataBase open]) {
  117. FMResultSet *rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo where userid = ?",userid];
  118. if ([rs next]) {
  119. UserInfoModel * userInfo = [[UserInfoModel alloc] init];
  120. userInfo.userEaseMobId      = [rs stringForColumn:@"userid"];
  121. userInfo.usernickName       = [rs stringForColumn:@"username"];
  122. userInfo.userHeaderImageUrl = [rs stringForColumn:@"userimage"];
  123. debugLog(@"查询一个 %@",userInfo);
  124. return userInfo;
  125. }else{
  126. return nil;
  127. }
  128. }else{
  129. return nil;
  130. }
  131. }
  132. @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 plaincopy
  1. #pragma mark - send message
  2. +(EMMessage *)sendTextMessage:(NSString *)text
  3. to:(NSString *)toUser
  4. messageType:(EMChatType)messageType
  5. messageExt:(NSDictionary *)messageExt{
  6. NSMutableDictionary * extDictionary = nil;
  7. // 这里要加判断,因为群聊消息的扩展和直播聊天室的扩展会冲突
  8. if (messageType == EMChatTypeGroupChat) {
  9. //这是为了区分一下表情的扩展消息
  10. if (!messageExt) {
  11. extDictionary = [self reGetMessageExt];
  12. }else{
  13. //扩展消息字典
  14. extDictionary = [[NSMutableDictionary alloc]initWithDictionary:messageExt];
  15. [extDictionary addEntriesFromDictionary:[self reGetMessageExt]];
  16. }
  17. }
  18. NSString *willSendText = [EaseConvertToCommonEmoticonsHelper convertToCommonEmoticons:text];
  19. EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:willSendText];
  20. NSString *from = [[EMClient sharedClient] currentUsername];
  21. EMMessage *message = [[EMMessage alloc] initWithConversationID:toUser from:from to:toUser body:body ext:extDictionary];
  22. message.chatType = messageType;
  23. return message;
  24. }
  25. // 获取消息扩展,这里不要纠结,我这里只是去了一下自己本地存储的个人信息,你把自己的取出来拼成一个字 // 典返回就可以了
  26. +(NSMutableDictionary*)reGetMessageExt{
  27. NSMutableDictionary *extDic = [NSMutableDictionary dictionary];
  28. NSString * userId = [NSString stringWithFormat:@"%@",READUSERDEFAULTS(UserId)];
  29. [extDic setValue:userId forKey:CHATUSERID];
  30. [extDic setValue:READUSERDEFAULTS(UserName) forKey:CHATUSERNICK];
  31. [extDic setValue:READUSERDEFAULTS(UserHeadImage) forKey:CHATUSRTHEADIMAGE];
  32. return extDic;
  33. }

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

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

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

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

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

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

    前言: 环信SDK 头像.昵称.表情自定义和群聊设置的实现 一(附源码) 接着上面说的,我们来说说表情,它在哪里可以自定义,怎么写,那个方法是添加表情的我们都说说,找到 ChatViewControl ...

  2. android 自定义表情包,android基于环信的聊天和表情自定义

    环信sdk的导入 自定义聊天界面 此处只有静态图,请谅解. 自定义表情发送 自定义聊天界面 简单说下自定义的聊天界面,一个带有recyclerview和的xml文件,和对应的adapter即可.rec ...

  3. android 环信客服 自动登出,Android环信聊天头像昵称显示解决方案

    从消息扩展中获取昵称和头像 昵称和头像的获取:把用户基本的昵称和头像的URL放到消息的扩展中,通过消息传递给接收方,当收到一条消息时,则能通过消息的扩展得到发送者的昵称和头像URL,然后保存到本地数据 ...

  4. 【C#+SQL Server+打印组件】实现电商快递单打印系统 五:自定义组件和快递单模板设计(附源码和资源)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 一.自定义组件(扩展TextBox) 由于快递单种类较多,所以在设计系统时考虑开发一个通用模板,由用户根据自己使用的快递单样式自行定义快递单的文本输 ...

  5. cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 该 ...

  6. 即时通信---环信SDK(IOS)使用教程

    一. 提前准备 注册环信即时通讯云账号 下载iOS的环信SDK 登陆到管理后台 在我的应用中创建一个应用 在苹果的个人开发中心创建一个推送证书(当然不创建也没用关系,只是不能推送消息而已) 创建完证书 ...

  7. 基于环信sdk在uni-app框架中快速开发一款多平台社交Demo

    说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊.群聊.聊天室.音视频等功能的应用.在此之前我们已经开发完 Vue.react(web端).微信小程序.这三个热门领域的版本,如有需要源 ...

  8. android 头像简称,Android环信显示头像及昵称的简单方法

    在我们日常应用开发中,很多时候产品需要IM聊天功能.考虑到时间.难度等问题一般会选择集成一些比较稳定的第三方SDK来实现功能.最近的项目也有IM需求,因为之前用过环信,感觉还不错,所以就再次使用了环信 ...

  9. 解决Android设置环信显示头像和昵称问题

    1.问题 在使用环信进行及时聊天时或者群聊时,显示用户名称的往往是其环信username(例如165983547),但我们真正希望显示的是用户的昵称(例如 张三),而聊天时候的头像默认是环信默认头像而 ...

最新文章

  1. 图的遍历DFS与BFS(邻接表)
  2. java 连接不上hbase_无法远程连接到Hbase
  3. javascript原生事件句柄、BOM、DOM对象属性方法总结
  4. Codeforces Round #716 (Div. 2) D. Cut and Stick 主席树 + 思维
  5. SAP ABAP 打印(smartforms方式)
  6. 简易正则表达式引擎源码阅读
  7. php属性赋值吗,php – 设置类中属性的默认值
  8. 计算机开机无法定位,开机提示无法定位程序输入点...于动态链接库CommFunc.dll上...
  9. 微型计算机原理 考试试题,微机原理期末考试试题及答案
  10. IAST技术进阶系列(四):DevOps流水线敏捷实践
  11. Linux系统安装(超级详细教程)
  12. 中国互联网史就是一部流氓史!
  13. TJA1042T/3与国产CAN芯片SIT1042T/3性能对比
  14. html表格数据填充,bootstrap table.js动态填充单元格数据的多种方法
  15. Java 8 effectively final
  16. 使用rpc(thrift或protobuf)进行前后端交互的若干种方式
  17. 青岛VR全景制作免费方法教程
  18. 网易云音乐导出歌单-速食版
  19. 信创操作系统--统信UOS桌面版(使用终端:bash、tty、基本shell操作)
  20. 类的成员函数指针和静态成员函数指针 调用成员函数***

热门文章

  1. Windows10磁盘占用率100%(ntoskrnl占用资源)导致系统卡顿
  2. 希捷硬盘1T挂了(2)
  3. 一个整数有几个奇数几个偶数字
  4. C语言---求符合给定条件的整数集
  5. 长沙理工计算机竞赛黑马,从“清北摇篮”到学科竞赛全国200强,安居育才成为最大黑马!...
  6. 实用性高流程图模板分享
  7. 克拉默法则C语言编程,FORTRAN编程:克拉默法则解线性方程组
  8. 蓝桥杯算法提高-质数的后代 Java实现
  9. 你今天听见《风声》了吗“ 学习无处不在继潜伏后《风声》观后感
  10. 计算机默认快捷键怎么修改,怎样修改电脑快捷键设置知道的能告诉下吗