李洪强iOS开发之-环信05_EaseUI 使用指南

EaseUI 使用指南


简介

EaseUI 封装了 IM 功能常用的控件(如聊天会话、会话列表、联系人列表)。旨在帮助开发者快速集成环信 SDK。

源码地址:

快速集成

第 1 步:集成 EaseUI 前,首先需要集成环信 iOS SDK,参考:集成文档

第 2 步:参考ChatDemo3.0 导入的方式,直接将EaseUI拖入已经集成SDK的项目中

初始化

第 1 步:引入相关头文件 #import “EaseUI.h”。

第 2 步:在工程的 AppDelegate 中的以下方法中,调用 EaseUI 对应方法。

  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. {
  3. [[EaseSDKHelper shareHelper] easemobApplication:application
  4. didFinishLaunchingWithOptions:launchOptions
  5. appkey:@"douser#istore"
  6. apnsCertName:@"istore_dev"
  7. otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}];
  8. return YES;
  9. }

聊天会话

创建聊天会话、传递用户或群 ID 和会话类型(EMConversationType)。

  1. EaseMessageViewController *chatController = [[EaseMessageViewController alloc] initWithConversationChatter:@"8001" conversationType:EMConversationTypeChat];

聊天会话功能扩展

EaseUI 提供现成的聊天会话 ViewController,可以通过继承 EaseMessageViewController 方式(参考 ChatDemo-UI3.0 中 ChatViewController)实现对聊天会话的扩展。

也可以直接使用 EaseMessageViewController,通过 EaseMessageViewControllerDelegate 和 EaseMessageViewControllerDataSource 两个协议实现对 EaseMessageViewController 的扩展。

实现自定义聊天样式

EaseMessageViewControllerDelegate

获取自定义消息 cell,根据 messageModel,用户自己判断是否显示自定义消息 cell。如果返回 nil 会显示默认;如果返回 cell 会显示用户自定义消息cell。

  1. /*!
  2. @method
  3. @brief 获取消息自定义cell
  4. @discussion 用户根据messageModel判断是否显示自定义cell。返回nil显示默认cell,否则显示用户自定义cell
  5. @param tableView 当前消息视图的tableView
  6. @param messageModel 消息模型
  7. @result 返回用户自定义cell
  8. */
  9. - (UITableViewCell *)messageViewController:(UITableView *)tableView
  10. cellForMessageModel:(id<IMessageModel>)messageModel;
  11.  
  12. /*!
  13. @method
  14. @brief 获取消息cell高度
  15. @discussion 用户根据messageModel判断,是否自定义显示cell的高度
  16. @param viewController 当前消息视图
  17. @param messageModel 消息模型
  18. @param cellWidth 视图宽度
  19. @result 返回用户自定义cell
  20. */
  21. - (CGFloat)messageViewController:(EaseMessageViewController *)viewController
  22. heightForMessageModel:(id<IMessageModel>)messageModel
  23. withCellWidth:(CGFloat)cellWidth;
  24.  
  25. //具体创建自定义Cell的样例:
  26. - (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)model
  27. {
  28. //样例为如果消息是文本消息显示用户自定义cell
  29. if (model.bodyType == eMessageBodyType_Text) {
  30. NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model];
  31. //CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
  32. CustomMessageCell *cell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  33. if (cell == nil) {
  34. cell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
  35. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  36. }
  37. cell.model = model;
  38. return cell;
  39. }
  40. return nil;
  41. }
  42.  
  43. - (CGFloat)messageViewController:(EaseMessageViewController *)viewController
  44. heightForMessageModel:(id<IMessageModel>)messageModel
  45. withCellWidth:(CGFloat)cellWidth
  46. {
  47. //样例为如果消息是文本消息使用用户自定义cell的高度
  48. if (messageModel.bodyType == EMMessageBodyTypeText) {
  49. //CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
  50. return [CustomMessageCell cellHeightWithModel:messageModel];
  51. }
  52. return 0.f;
  53. }

通过自定义cell展示动态表情的效果图:

选中消息的回调

  1. /*!
  2. @method
  3. @brief 选中消息的回调
  4. @discussion 用户根据messageModel判断,是否自定义处理消息选中时间。返回YES为自定义处理,返回NO为默认处理
  5. @param viewController 当前消息视图
  6. @param messageModel 消息模型
  7. @result 是否采用自定义处理
  8. */
  9. - (BOOL)messageViewController:(EaseMessageViewController *)viewController
  10. didSelectMessageModel:(id<IMessageModel>)messageModel;
  11.  
  12. //选中消息回调的样例:
  13. - (BOOL)messageViewController:(EaseMessageViewController *)viewController
  14. didSelectMessageModel:(id<IMessageModel>)messageModel
  15. {
  16. BOOL flag = NO;
  17. //样例为如果消息是文件消息用户自定义处理选中逻辑
  18. switch (messageModel.bodyType) {
  19. case EMMessageBodyTypeImage:
  20. case EMMessageBodyTypeLocation:
  21. case EMMessageBodyTypeVideo:
  22. case EMMessageBodyTypeVoice:
  23. break;
  24. case EMMessageBodyTypeFile:
  25. {
  26. flag = YES;
  27. NSLog(@"用户自定义实现");
  28. }
  29. break;
  30. default:
  31. break;
  32. }
  33. return flag;
  34. }

用户选中头像的回调

  1. /*!
  2. @method
  3. @brief 点击消息头像
  4. @discussion 获取用户点击头像回调
  5. @param viewController 当前消息视图
  6. @param messageModel 消息模型
  7. @result
  8. */
  9. - (void)messageViewController:(EaseMessageViewController *)viewController
  10. didSelectAvatarMessageModel:(id<IMessageModel>)messageModel;
  11.  
  12. //获取用户点击头像回调的样例:
  13. - (void)messageViewController:(EaseMessageViewController *)viewController
  14. didSelectAvatarMessageModel:(id<IMessageModel>)messageModel
  15. {
  16. //UserProfileViewController用户自定义的个人信息视图
  17. //样例的逻辑是选中消息头像后,进入该消息发送者的个人信息
  18. UserProfileViewController *userprofile = [[UserProfileViewController alloc] initWithUsername:messageModel.message.from];
  19. [self.navigationController pushViewController:userprofile animated:YES];
  20. }

录音按钮状态的回调

  1. /*!
  2. @method
  3. @brief 底部录音功能按钮状态回调
  4. @discussion 获取底部录音功能按钮状态回调,根据EaseRecordViewType,用户自定义处理UI的逻辑
  5. @param viewController 当前消息视图
  6. @param recordView 录音视图
  7. @param type 录音按钮当前状态
  8. @result
  9. */
  10. - (void)messageViewController:(EaseMessageViewController *)viewController
  11. didSelectRecordView:(UIView *)recordView
  12. withEvenType:(EaseRecordViewType)type;
  13.  
  14. //录音按钮状态的回调样例:
  15. - (void)messageViewController:(EaseMessageViewController *)viewController
  16. didSelectRecordView:(UIView *)recordView
  17. withEvenType:(EaseRecordViewType)type
  18. {
  19. /*
  20. EaseRecordViewTypeTouchDown,//录音按钮按下
  21. EaseRecordViewTypeTouchUpInside,//手指在录音按钮内部时离开
  22. EaseRecordViewTypeTouchUpOutside,//手指在录音按钮外部时离开
  23. EaseRecordViewTypeDragInside,//手指移动到录音按钮内部
  24. EaseRecordViewTypeDragOutside,//手指移动到录音按钮外部
  25. */
  26. //根据type类型,用户自定义处理UI的逻辑
  27. switch (type) {
  28. case EaseRecordViewTypeTouchDown:
  29. {
  30. if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
  31. [(EaseRecordView *)self.recordView recordButtonTouchDown];
  32. }
  33. }
  34. break;
  35. case EaseRecordViewTypeTouchUpInside:
  36. {
  37. if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
  38. [(EaseRecordView *)self.recordView recordButtonTouchUpInside];
  39. }
  40. [self.recordView removeFromSuperview];
  41. }
  42. break;
  43. case EaseRecordViewTypeTouchUpOutside:
  44. {
  45. if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
  46. [(EaseRecordView *)self.recordView recordButtonTouchUpOutside];
  47. }
  48. [self.recordView removeFromSuperview];
  49. }
  50. break;
  51. case EaseRecordViewTypeDragInside:
  52. {
  53. if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
  54. [(EaseRecordView *)self.recordView recordButtonDragInside];
  55. }
  56. }
  57. break;
  58. case EaseRecordViewTypeDragOutside:
  59. {
  60. if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
  61. [(EaseRecordView *)self.recordView recordButtonDragOutside];
  62. }
  63. }
  64. break;
  65. default:
  66. break;
  67. }
  68. }

EaseMessageViewControllerDataSource

用户判断消息是否允许长按,返回布尔值;如果用户允许长按,此方法为通知用户触发长按手势,返回布尔值,如果返回 NO 默认方式处理,返回 YES 采用用户自定义的处理方式。

  1. /*!
  2. @method
  3. @brief 是否允许长按
  4. @discussion 获取是否允许长按的回调,默认是NO
  5. @param viewController 当前消息视图
  6. @param indexPath 长按消息对应的indexPath
  7. @result
  8. */
  9. - (BOOL)messageViewController:(EaseMessageViewController *)viewController
  10. canLongPressRowAtIndexPath:(NSIndexPath *)indexPath;
  11.  
  12. /*!
  13. @method
  14. @brief 触发长按手势
  15. @discussion 获取触发长按手势的回调,默认是NO
  16. @param viewController 当前消息视图
  17. @param indexPath 长按消息对应的indexPath
  18. @result
  19. */
  20. - (BOOL)messageViewController:(EaseMessageViewController *)viewController
  21. didLongPressRowAtIndexPath:(NSIndexPath *)indexPath;
  22.  
  23. //长按收拾回调样例:
  24. - (BOOL)messageViewController:(EaseMessageViewController *)viewController
  25. canLongPressRowAtIndexPath:(NSIndexPath *)indexPath
  26. {
  27. //样例给出的逻辑是所有cell都允许长按
  28. return YES;
  29. }
  30.  
  31. - (BOOL)messageViewController:(EaseMessageViewController *)viewController
  32. didLongPressRowAtIndexPath:(NSIndexPath *)indexPath
  33. {
  34. //样例给出的逻辑是长按cell之后显示menu视图
  35. id object = [self.dataArray objectAtIndex:indexPath.row];
  36. if (![object isKindOfClass:[NSString class]]) {
  37. EaseMessageCell *cell = (EaseMessageCell *)[self.tableView cellForRowAtIndexPath:indexPath];
  38. [cell becomeFirstResponder];
  39. self.menuIndexPath = indexPath;
  40. [self _showMenuViewController:cell.bubbleView andIndexPath:indexPath messageType:cell.model.bodyType];
  41. }
  42. return YES;
  43. }

Demo3.0实现的消息长按效果演示:

将EMMessage类型转换为符合<IMessageModel>协议的类型,设置用户信息,消息显示用户昵称和头像。

  1. /*!
  2. @method
  3. @brief 将EMMessage类型转换为符合<IMessageModel>协议的类型
  4. @discussion 将EMMessage类型转换为符合<IMessageModel>协议的类型,设置用户信息,消息显示用户昵称和头像
  5. @param viewController 当前消息视图
  6. @param EMMessage 聊天消息对象类型
  7. @result 返回<IMessageModel>协议的类型
  8. */
  9. - (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
  10. modelForMessage:(EMMessage *)message;
  11.  
  12. //具体样例:
  13. - (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
  14. modelForMessage:(EMMessage *)message
  15. {
  16. //用户可以根据自己的用户体系,根据message设置用户昵称和头像
  17. id<IMessageModel> model = nil;
  18. model = [[EaseMessageModel alloc] initWithMessage:message];
  19. model.avatarImage = [UIImage imageNamed:@"EaseUIResource.bundle/user"];//默认头像
  20. model.avatarURLPath = @"";//头像网络地址
  21. model.nickname = @"昵称";//用户昵称
  22. return model;
  23. }

聊天会话页面头像和昵称的效果演示:

聊天会话样式自定义

聊天样式的自定义需要在 EaseMessageViewController 中 viewDidload 结束前设置。

  1. //@property中带有UI_APPEARANCE_SELECTOR,都可以通过set的形式设置样式,具体可以参考EaseBaseMessageCell.h,EaseMessageCell.h
  2.  
  3. [[EaseBaseMessageCell appearance] setSendBubbleBackgroundImage:[[UIImage imageNamed:@"chat_sender_bg"] stretchableImageWithLeftCapWidth:5 topCapHeight:35]];//设置发送气泡
  4. [[EaseBaseMessageCell appearance] setRecvBubbleBackgroundImage:[[UIImage imageNamed:@"chat_receiver_bg"] stretchableImageWithLeftCapWidth:35 topCapHeight:35]];//设置接收气泡
  5.  
  6. [[EaseBaseMessageCell appearance] setAvatarSize:40.f];//设置头像大小
  7. [[EaseBaseMessageCell appearance] setAvatarCornerRadius:20.f];//设置头像圆角

消息发送

EaseSDKHelper 封装了发送消息的方法。

具体发送消息样例:

  1. /*
  2. EMChatTypeChat 单聊消息
  3. EMChatTypeGroupChat 群聊消息
  4. EMChatTypeChatRoom 聊天室消息
  5. */
  6.  
  7. //发送文字消息
  8. EMMessage *message = [EaseSDKHelper sendTextMessage:@"要发送的消息"
  9. to:@"6001"//接收方
  10. messageType:EMChatTypeChat//消息类型
  11. messageExt:nil]; //扩展信息
  12. //发送位置消息
  13. EMMessage *message = [EaseSDKHelper sendLocationMessageWithLatitude:35.1//经度
  14. longitude:35.1//纬度
  15. address:"地址"
  16. to:@"6001"//接收方
  17. messageType:EMChatTypeChat//消息类型
  18. messageExt:nil];//扩展信息
  19.  
  20. //发送图片消息
  21. EMMessage *message = [EaseSDKHelper sendImageMessageWithImageData:imageData//发送的图片数据NSData
  22. to:@"6001"//接收方
  23. messageType:EMChatTypeChat//消息类型
  24. messageExt:nil];//扩展信息
  25.  
  26. //发送音频消息
  27. EMMessage *message = [EaseSDKHelper sendVoiceMessageWithLocalPath:localPath//音频本地地址
  28. duration:duration//语音的时长,单位是秒
  29. to:@"6001"//接收方
  30. messageType:EMChatTypeChat//消息类型
  31. messageExt:nil];//扩展信息
  32.  
  33. //发送视频文件消息
  34. EMMessage *message = [EaseSDKHelper sendVideoMessageWithURL:url//发送的视频地址
  35. to:@"6001"//接收方
  36. messageType:EMChatTypeChat//消息类型
  37. messageExt:nil];//扩展信息
  38.  
  39. //发送构造成功的消息
  40. [[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
  41.  
  42. }];

会话列表

 

会话列表初始化

  1. EaseConversationListViewController *chatListVC = [[EaseConversationListViewController alloc] init];

会话列表扩展

EaseConversationListViewControllerDataSource

用户根据 conversationModel 实现,实现自定义会话中最后一条消息文案的显示内容。

  1. /*!
  2. @method
  3. @brief 获取最后一条消息显示的内容
  4. @discussion 用户根据conversationModel实现,实现自定义会话中最后一条消息文案的显示内容
  5. @param conversationListViewController 当前会话列表视图
  6. @param IConversationModel 会话模型
  7. @result 返回用户最后一条消息显示的内容
  8. */
  9. - (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
  10. latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel;
  11.  
  12.  
  13. /*!
  14. @method
  15. @brief 获取最后一条消息显示的时间
  16. @discussion 用户可以根据conversationModel,自定义实现会话列表中时间文案的显示内容
  17. @param conversationListViewController 当前会话列表视图
  18. @param IConversationModel 会话模型
  19. @result 返回用户最后一条消息时间的显示文案
  20. */
  21. - (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
  22. latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel;
  23.  
  24. //最后一条消息展示内容样例
  25. - (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
  26. latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel
  27. {
  28. NSString *latestMessageTitle = @"";
  29. EMMessage *lastMessage = [conversationModel.conversation latestMessage];
  30. if (lastMessage) {
  31. EMMessageBody *messageBody = lastMessage.body;
  32. switch (messageBody.type) {
  33. case EMMessageBodyTypeImage:{
  34. latestMessageTitle = NSLocalizedString(@"message.image1", @"[image]");
  35. } break;
  36. case EMMessageBodyTypeText:{
  37. // 表情映射。
  38. NSString *didReceiveText = [EaseConvertToCommonEmoticonsHelper
  39. convertToSystemEmoticons:((EMTextMessageBody *)messageBody).text];
  40. latestMessageTitle = didReceiveText;
  41. if ([lastMessage.ext objectForKey:MESSAGE_ATTR_IS_BIG_EXPRESSION]) {
  42. latestMessageTitle = @"[动画表情]";
  43. }
  44. } break;
  45. case EMMessageBodyTypeVoice:{
  46. latestMessageTitle = NSLocalizedString(@"message.voice1", @"[voice]");
  47. } break;
  48. case EMMessageBodyTypeLocation: {
  49. latestMessageTitle = NSLocalizedString(@"message.location1", @"[location]");
  50. } break;
  51. case EMMessageBodyTypeVideo: {
  52. latestMessageTitle = NSLocalizedString(@"message.video1", @"[video]");
  53. } break;
  54. case EMMessageBodyTypeFile: {
  55. latestMessageTitle = NSLocalizedString(@"message.file1", @"[file]");
  56. } break;
  57. default: {
  58. } break;
  59. }
  60. }
  61.  
  62. return latestMessageTitle;
  63. }
  64.  
  65. //最后一条消息展示时间样例
  66. - (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
  67. latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel
  68. {
  69. NSString *latestMessageTime = @"";
  70. EMMessage *lastMessage = [conversationModel.conversation latestMessage];;
  71. if (lastMessage) {
  72. latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp];
  73. }
  74. return latestMessageTime;
  75. }

会话列表最后一条消息和时间显示的效果演示:

EaseConversationListViewControllerDelegate

点击会话列表用户可以根据 conversationModel 自定义处理逻辑。

  1. /*!
  2. @method
  3. @brief 获取点击会话列表的回调
  4. @discussion 获取点击会话列表的回调后,点击会话列表用户可以根据conversationModel自定义处理逻辑
  5. @param conversationListViewController 当前会话列表视图
  6. @param IConversationModel 会话模型
  7. @result
  8. */
  9. - (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
  10. didSelectConversationModel:(id<IConversationModel>)conversationModel;
  11.  
  12. //会话列表点击的回调样例
  13. - (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
  14. didSelectConversationModel:(id<IConversationModel>)conversationModel
  15. {
  16. //样例展示为根据conversationModel,进入不同的会话ViewController
  17. if (conversationModel) {
  18. EMConversation *conversation = conversationModel.conversation;
  19. if (conversation) {
  20. if ([[RobotManager sharedInstance] isRobotWithUsername:conversation.conversationId]) {
  21. RobotChatViewController *chatController = [[RobotChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
  22. chatController.title = [[RobotManager sharedInstance] getRobotNickWithUsername:conversation.conversationId];
  23. [self.navigationController pushViewController:chatController animated:YES];
  24. } else {
  25. ChatViewController *chatController = [[ChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
  26. chatController.title = conversationModel.title;
  27. [self.navigationController pushViewController:chatController animated:YES];
  28. }
  29. }
  30. [[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil];
  31. [self.tableView reloadData];
  32. }
  33. }

联系人列表

 

联系人列表初始化

  1. EaseUsersListViewController *listViewController = [[EaseUsersListViewController alloc] init];

联系人列表扩展

需要实现 EMUserListViewControllerDataSource。

根据 buddy 获取用户自定信息,联系人列表里展示昵称和头像。

  1. /*!
  2. @method
  3. @brief 获取用户模型
  4. @discussion 根据buddy获取用户自定信息,联系人列表里展示昵称和头像
  5. @param userListViewController 当前联系人视图
  6. @param buddy 好友的信息描述类
  7. @result 返回用户模型
  8. */
  9. - (id<IUserModel>)userListViewController:(EaseUsersListViewController *)userListViewController
  10. modelForBuddy:(NSString *)buddy;
  11.  
  12. //联系人列表扩展样例
  13. - (id<IUserModel>)userListViewController:(EaseUsersListViewController *)userListViewController
  14. modelForBuddy:(NSString *)buddy
  15. {
  16. //用户可以根据自己的用户体系,根据buddy设置用户昵称和头像
  17. id<IUserModel> model = nil;
  18. model = [[EaseUserModel alloc] initWithBuddy:buddy];
  19. model.avatarURLPath = @"";//头像网络地址
  20. model.nickname = @"昵称";//用户昵称
  21. return model;
  22. }

联系人列表头像和昵称的效果演示:

李洪强iOS开发之-环信05_EaseUI 使用指南的更多相关文章

  1. 李洪强iOS开发之-环信04_消息

    李洪强iOS开发之-环信04_消息 消息:IM 交互实体,在 SDK 中对应的类型是 EMMessage.EMMessage 由 EMMessageBody 组成. 构造消息   构造文字消息 EMT ...

  2. 李洪强iOS开发之-环信03_集成 SDK 基础功能

    李洪强iOS开发之-环信03_集成 SDK 基础功能 集成 SDK 基础功能 在您阅读此文档时,我们假定您已经具备了基础的 iOS 应用开发经验,并能够理解相关基础概念. SDK 同步/异步方法区分 ...

  3. 李洪强iOS开发之-环信02.2_环信官网下载环信 SDK

    李洪强iOS开发之-环信02.2_环信官网下载环信 SDK 移动客服即时通讯云 iOS SDK 当前版本:V3.1.4 2016-07-08 [ 版本历史 ] | 开发指南 | 知识库 | Demo源 ...

  4. 李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档

    李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档 SDK 2.x 至 3.0 升级指南 环信 SDK 3.0 升级文档 3.0 中的核心类为 EMClient 类,通过 EMCl ...

  5. 李洪强iOS开发之-环信02_iOS SDK 介绍及导入

    李洪强iOS开发之-环信02_iOS SDK 介绍及导入 iOS SDK 介绍及导入 iOS SDK 介绍 环信 SDK 为用户开发 IM 相关的应用提供的一套完善的开发框架.包括以下几个部分: SD ...

  6. 李洪强iOS开发之-环信01_iOS SDK 前的准备工作

    李洪强iOS开发之-环信01_iOS SDK 前的准备工作 1.1_注册环信开发者账号并创建后台应用 详细步骤:  注册并创建应用 注册环信开发者账号 第 1 步:在环信官网上点击“即时通讯云”,并点 ...

  7. 李洪强iOS开发之-环信02.3_具体接口讲解 - Apple Docs

    http://www.easemob.com/apidoc/ios/chat3.0/annotated.html Apple Docs.

  8. 李洪强iOS开发本人集成环信的经验总结_01环信SDK的导入

    李洪强iOS开发本人集成环信的经验总结_01环信SDK的导入 01 - 直接在项目中导入SDK和一些静态库 这个时候,没有错误的编译没有错误的话,就说明SDK已经配置成功 还有一种方法是用cocoap ...

  9. 李洪强iOS开发本人集成环信的经验总结_03_注册

    李洪强iOS开发本人集成环信的经验总结_03_注册 环信一共提供了三种注册的方法:  01 同步注册:  02 异步注册:  03 - 使用代理回调进行注册,但是3.0没有了,3.0之前有  调用注册 ...

随机推荐

  1. Oracle12c创建新用户提示公共用户名或角色无效

    今天将备份的数据库还原到一台新的电脑上,首先要创建用户,执行如下语句: create user fxhy identified " default tablespace USERS temp ...

  2. HW--字符串加解密

    package t0817; import java.util.Scanner; public class StringEncrypt { public static void main(String ...

  3. <转载>国外程序员推荐的免费编程书籍资源

    一.George Stocker 提供了一大串,分类如下: How to Design Programs: An Introduction to Computing and Programming 2 ...

  4. asp.net连接mysql数据库

    方法一:使用MySQL推出的MySQL Connector/Net组件, 该组件是MySQL为ADO.NET访问MySQL数据库设计的.NET专用访问组件.完成该组件后,需要在项目中引用这个组件,也可 ...

  5. DIV+CSS相对IE8的兼容问题

    CSS技巧: 1.div的垂直居中问题 vertical-align:middle; 将行距增加到和整个DIV一样高 line-height:200px; 然后插入文字,就垂直居中了.缺点是要控制内容 ...

  6. WPF 中,动态创建Button,并使Button得样式按照自定义的Resource样式显示

    第一步:自定义一个Button的样式 1.新建一个xaml文件,在其中自定义好自己的Resources 这个Resource 的根节点是 <ResourceDictionary xmlns=&q ...

  7. C++ IO 详细用法

    http://www.cnblogs.com/keam37/ keam所有 转载请注明出处 本文将分别从<iostream>,<sstream>,<fstream> ...

  8. 【nodemailer】之 work with mustache

    之前对nodemailer做了简要的研究,基本上是搞定了发邮件的问题.但很多情况下邮件的内容不是固定的,然后又需要有一个合适的样式,这就需要使用模板了.nodemailer有nodemailer-ma ...

  9. C++学习 (转)

    1.把C++当成一门新的语言学习: 2.看<Thinking In C++>: 3.看<The C++ Programming Language>和<Inside The ...

  10. ACE_linux:读写锁

    1.涉及类 ACE_RW_Thread_Mutex //ACE读写锁ACE_Read_Guard //ACE加读锁ACE_Write_Guard //ACE加写锁ACE_Thread_Manager ...