http://www.ox-holdings.com

避免 babel新匍京娱乐场手机版 二次打包引起的错误,更新内容新增智能机器人功能

摘要即时通讯云网易云信于2017年09月12日发布4.2版,本次更新为主要版本更新,详情见文章内容。发布的版本本次发布的版本号为 4.2版,更新时间为:2017年09月12日。iOS 更新内容新增聊天室支持 bot 机器人,使用方式与普通消息一致。添加是否将群通知计入未读的开关@interface NIMSDKConfig : NSObject/** * @discusssion 默认为 NO。设置成 YES 的情况下,收到的群通知也会计入未读数 */@property (nonatomic,assign) BOOL shouldCountTeamNotification;@end添加日志最大存在天数设置@interface NIMSDKConfig : NSObject/** * @discusssion 默认为 7 天。即超过 7 天的 log 将被清除。只能设置大于等于 2 的值。 */@property (nonatomic,assign) NSInteger maximumLogDays;@end变更创建群接口变更/** * 创建群组 * * @param option 创建群选项 * @param users 用户ID列表 * @param completion 完成后的回调 */- (void)createTeam:(NIMCreateTeamOption *)option users:(NSArray<NSString *> *)users completion:(nullable NIMTeamCreateHandler)completion;创建群完成的回调由/** * 创建群组block * * @param error 错误,如果成功则error为nil * @param teamId 群组ID */typedef void(^NIMTeamCreateHandler)(NSError * __nullable error,NSString * __nullable teamId);变更为/** * 创建群组block * * @param error 错误,如果成功则error为nil * @param teamId 群组ID * @param failedUserIds 邀请失败的群成员ID */typedef void(^NIMTeamCreateHandler)(NSError * __nullable error, NSString * __nullable teamId, NSArray<NSString *> * __nullable failedUserIds);现在创建群可能会出现建群成功,建群同时邀请的用户部分成功的情况。此时建群依然成功,error 信息为 nil ,并返回邀请失败的群成员 ID 集合。Android 更新内容新增1. 添加聊天室 bot 机器人功能,添加机器人上行消息构建接口:ChatRoomMessageBuilder#createRobotMessage。2. 登录选项添加群通知消息是否计入未读数开关:SDKOptions#teamNotificationMessageMarkUnread。变更1. 对单个用户所在群的数量添加限制,影响到接口:TeamService#createTeam, 返回结果CreateTeamResult,包含邀请失败账号列表TeamService#addMembers, 返回结果 List,即邀请失败账号列表如果邀请成员中有群数量超过限制,返回码仍然是成功,并且同时返回这部分超限的账号。2. 解决登录偶现登录 417 问题。3. 添加登录同步失败情况处理。4. 添加 IPC ACK 机制,解决极端情况下群消息丢失的问题。5. 解决 HttpDownload 安全警告问题。Windows(PC) SDK 更新内容新增群通知消息是否计为未读数增加开关配置 nim_client.h聊天室支持机器人修复修复某些场景下群成员同步bugWeb SDK 更新内容新增聊天室匿名登录聊天室机器人及其发生消息接口聊天室获取机器人接口下载地址请从以下官网地址下载:

摘要即时通讯云网易云信于2017年07月06日发布4.0版,本次更新为主要版本更新,详情见文章内容。发布的版本本次发布的版本号为 4.0版,更新时间为:2017年07月06日。iOS 更新内容新增智能机器人功能,增加新的机器人管理器NIMRobotManager。聊天室连麦队列变更后数据同步,现在可以从NIMChatroomNotificationContent中的ext字段读取到具体的变更数据了。发送聊天室消息时,可以通过设置消息中NIMMessageSetting的historyEnabled字段来控制是否存服务器历史记录。Android 更新内容新增1. 接入华为推送服务。2. 接入网易Bot(智能机器人)功能,增加RobotService、RobotServiceObserve接口。3. 新增聊天室发消息是否存历史记录的开关,发送聊天室消息时可以选择是否存入历史记录。4. 聊天室连麦队列变更后数据同步。变更1. 被叫语音、视频通话未接听计入未读数。2. 修复接收聊天室 tip 消息获取 content 为空的问题。Windows(PC) SDK 更新内容新增机器人模块, nim_robot.h聊天室消息不存历史记录开关聊天室队列变更通知增加变更内容支持Https(默认Http)修复修复管理后台创建群(不需要用户同意)时,在线客户端无法同步该群信息到本地的问题修复申请加入群(不需要管理员同意)时,本地群列表里没有该群信息的问题Web SDK 更新内容新增新增机器人消息收发接口新增机器人默认bot类型消息的xml解析方法新增聊天室发送消息可选不保存历史消息配置变更修复部分iPhone机型断网重连后协议解析问题修复转发消息数据库记录有误的问题下载地址请从以下官网地址下载:

点击查看原文

iOS开发之第三方分享微信分享、朋友圈分享,史上最新最全,ios朋友圈

微信分享前提:

  1.需要成功在微信开发者平台注册了账号, 并取的对应的 appkey appSecret。

        2. 针对iOS9 添加了微信的白名单,以及设置了 scheme url 。 这都可以参照上面的链接,进行设置好。 

  3. 分享不跳转的时候原因总结, 具体方法如下:

             1. 首先检查下是否有向微信注册应用。

       2. 分享参数是否拼接错误。 监听下面 isSuccess  yes为成功, no为是否, 看看是否是分享的对象弄错了。 文本对象与多媒体对象只能选一种。

[objc] view plain copy  

  1. BOOL isSuccess = [WXApi sendReq:sentMsg];  

 

 

[objc] view plain copy  

  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
  2.       
  3.     //向微信注册应用。  
  4.     [WXApi registerApp:URL_APPID withDescription:@"wechat"];  
  5.     return YES;  
  6. }  
  7.   
  8. -(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{  
  9.       
  10.     /*! @brief 处理微信通过URL启动App时传递的数据 
  11.      * 
  12.      * 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。 
  13.      * @param url 微信启动第三方应用时传递过来的URL 
  14.      * @param delegate  WXApiDelegate对象,用来接收微信触发的消息。 
  15.      * @return 成功返回YES,失败返回NO。 
  16.      */  
  17.       
  18.     return [WXApi handleOpenURL:url delegate:self];  
  19. }  
  20.   
  21.   
  22. - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{  
  23.     return [WXApi handleOpenURL:url delegate:self];  
  24. }  
  25.   
  26. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{  
  27.     return [WXApi handleOpenURL:url delegate:self];  
  28. }  

 

 

微信分享的核心代码;

 

[objc] view plain copy  

  1. #pragma mark 微信好友分享  
  2. /** 
  3.  *  微信分享对象说明 
  4.  * 
  5.  *  @param sender  
  6. WXMediaMessage    多媒体内容分享 
  7. WXImageObject      多媒体消息中包含的图片数据对象 
  8. WXMusicObject      多媒体消息中包含的音乐数据对象 
  9. WXVideoObject      多媒体消息中包含的视频数据对象 
  10. WXWebpageObject    多媒体消息中包含的网页数据对象 
  11. WXAppExtendObject  返回一个WXAppExtendObject对象 
  12. WXEmoticonObject   多媒体消息中包含的表情数据对象 
  13. WXFileObject       多媒体消息中包含的文件数据对象 
  14. WXLocationObject   多媒体消息中包含的地理位置数据对象 
  15. WXTextObject       多媒体消息中包含的文本数据对象 
  16.   
  17.  */  
  18.   
  19. -(void)isShareToPengyouquan:(BOOL)isPengyouquan{  
  20.     /** 标题 
  21.      * @note 长度不能超过512字节 
  22.      */  
  23.     // @property (nonatomic, retain) NSString *title;  
  24.     /** 描述内容 
  25.      * @note 长度不能超过1K 
  26.      */  
  27.     //@property (nonatomic, retain) NSString *description;  
  28.     /** 缩略图数据 
  29.      * @note 大小不能超过32K 
  30.      */  
  31.     //  @property (nonatomic, retain) NSData   *thumbData;  
  32.     /** 
  33.      * @note 长度不能超过64字节 
  34.      */  
  35.     // @property (nonatomic, retain) NSString *mediaTagName;  
  36.     /** 
  37.      * 多媒体数据对象,可以为WXImageObject,WXMusicObject,WXVideoObject,WXWebpageObject等。 
  38.      */  
  39.     // @property (nonatomic, retain) id        mediaObject;  
  40.       
  41.     /*! @brief 设置消息缩略图的方法 
  42.      * 
  43.      * @param image 缩略图 
  44.      * @note 大小不能超过32K 
  45.      */  
  46.     //- (void) setThumbImage:(UIImage *)image;  
  47.     //缩略图  
  48.     UIImage *image = [UIImage imageNamed:@"消息中心 icon"];  
  49.     WXMediaMessage *message = [WXMediaMessage message];  
  50.     message.title = @"微信分享测试";  
  51.     message.description = @"微信分享测试----描述信息";  
  52.     //png图片压缩成data的方法,如果是jpg就要用 UIImageJPEGRepresentation  
  53.     message.thumbData = UIImagePNGRepresentation(image);  
  54.     [message setThumbImage:image];  
  55.       
  56.   
  57.     WXWebpageObject *ext = [WXWebpageObject object];  
  58.     ext.webpageUrl = @"";  
  59.     message.mediaObject = ext;  
  60.     message.mediaTagName = @"ISOFTEN_TAG_JUMP_SHOWRANK";  
  61.       
  62.     SendMessageToWXReq *sentMsg = [[SendMessageToWXReq alloc]init];  
  63.     sentMsg.message = message;  
  64.     sentMsg.bText = NO;  
  65.     //选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)  
  66.     if (isPengyouquan) {  
  67.         sentMsg.scene = WXSceneTimeline;  //分享到朋友圈  
  68.     }else{  
  69.         sentMsg.scene =  WXSceneSession;  //分享到会话。  
  70.     }  
  71.       
  72.     //如果我们想要监听是否成功分享,我们就要去appdelegate里面 找到他的回调方法  
  73.     // -(void) onResp:(BaseResp*)resp .我们可以自定义一个代理方法,然后把分享的结果返回回来。  
  74.     appdelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;  
  75.     appdelegate.wxDelegate = self;                <span style="font-family: Arial, Helvetica, sans-serif;"> //添加对appdelgate的微信分享的代理</span>  
  76.     BOOL isSuccess = [WXApi sendReq:sentMsg];  
  77.    
  78. }  

 

完整的代码如下:

appDelegate.h

 

[objc] view plain copy  

  1. #import <UIKit/UIKit.h>  
  2.   
  3. @protocol WXDelegate <NSObject>  
  4.   
  5. -(void)loginSuccessByCode:(NSString *)code;  
  6. -(void)shareSuccessByCode:(int) code;  
  7. @end  
  8.   
  9. @interface AppDelegate : UIResponder <UIApplicationDelegate>  
  10.   
  11. @property (strong, nonatomic) UIWindow *window;  
  12. @property (nonatomic, weak) id<WXDelegate> wxDelegate;  
  13. @end  

 

appDelegate.m

 

[objc] view plain copy  

  1. #import "AppDelegate.h"  
  2. #import "WXApi.h"  
  3.   
  4. //微信开发者ID  
  5. #define URL_APPID @"app id"  
  6.   
  7.   
  8.   
  9.   
  10. @interface AppDelegate ()<WXApiDelegate>  
  11.   
  12.   
  13. @end  
  14.   
  15.   
  16.   
  17. @implementation AppDelegate  
  18.   
  19.   
  20. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
  21.       
  22.     //向微信注册应用。  
  23.     [WXApi registerApp:URL_APPID withDescription:@"wechat"];  
  24.     return YES;  
  25. }  
  26.   
  27. -(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{  
  28.       
  29.     /*! @brief 处理微信通过URL启动App时传递的数据 
  30.      * 
  31.      * 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。 
  32.      * @param url 微信启动第三方应用时传递过来的URL 
  33.      * @param delegate  WXApiDelegate对象,用来接收微信触发的消息。 
  34.      * @return 成功返回YES,失败返回NO。 
  35.      */  
  36.       
  37.     return [WXApi handleOpenURL:url delegate:self];  
  38. }  
  39.   
  40.   
  41. - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{  
  42.     return [WXApi handleOpenURL:url delegate:self];  
  43. }  
  44.   
  45. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{  
  46.     return [WXApi handleOpenURL:url delegate:self];  
  47. }  
  48.   
  49. /*! 微信回调,不管是登录还是分享成功与否,都是走这个方法 @brief 发送一个sendReq后,收到微信的回应 
  50.  * 
  51.  * 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。 
  52.  * 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。 
  53.  * @param resp具体的回应内容,是自动释放的 
  54.  */  
  55. -(void) onResp:(BaseResp*)resp{  
  56.     NSLog(@"resp %d",resp.errCode);  
  57.       
  58.     /* 
  59.     enum  WXErrCode { 
  60.         WXSuccess           = 0,    成功 
  61.         WXErrCodeCommon     = -1,  普通错误类型 
  62.         WXErrCodeUserCancel = -2,    用户点击取消并返回 
  63.         WXErrCodeSentFail   = -3,   发送失败 
  64.         WXErrCodeAuthDeny   = -4,    授权失败 
  65.         WXErrCodeUnsupport  = -5,   微信不支持 
  66.     }; 
  67.     */  
  68.     if ([resp isKindOfClass:[SendAuthResp class]]) {   //授权登录的类。  
  69.         if (resp.errCode == 0) {  //成功。  
  70.             //这里处理回调的方法 。 通过代理吧对应的登录消息传送过去。  
  71.             if ([_wxDelegate respondsToSelector:@selector(loginSuccessByCode:)]) {  
  72.                 SendAuthResp *resp2 = (SendAuthResp *)resp;  
  73.                 [_wxDelegate loginSuccessByCode:resp2.code];  
  74.             }  
  75.         }else{ //失败  
  76.             NSLog(@"error %@",resp.errStr);  
  77.             UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"登录失败" message:[NSString stringWithFormat:@"reason : %@",resp.errStr] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil nil];  
  78.             [alert show];  
  79.         }  
  80.     }  
  81.       
  82.     if ([resp isKindOfClass:[SendMessageToWXResp class]]) { //微信分享 微信回应给第三方应用程序的类  
  83.         SendMessageToWXResp *response = (SendMessageToWXResp *)resp;  
  84.         NSLog(@"error code %d  error msg %@  lang %@   country %@",response.errCode,response.errStr,response.lang,response.country);  
  85.           
  86.         if (resp.errCode == 0) {  //成功。  
  87.             //这里处理回调的方法 。 通过代理吧对应的登录消息传送过去。  
  88.             if (_wxDelegate) {  
  89.                 if([_wxDelegate respondsToSelector:@selector(shareSuccessByCode:)]){  
  90.                     [_wxDelegate shareSuccessByCode:response.errCode];  
  91.                 }  
  92.             }  
  93.         }else{ //失败  
  94.             NSLog(@"error %@",resp.errStr);  
  95.             UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"分享失败" message:[NSString stringWithFormat:@"reason : %@",resp.errStr] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil nil];  
  96.             [alert show];  
  97.         }  
  98.     }  
  99. } @end  

 

 

ViewController.h

 

[objc] view plain copy  

  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface ViewController : UIViewController  
  4.   
  5.   
  6. @end  

 

ViewController.m

 

[objc] view plain copy  

  1. #import "ViewController.h"  
  2. #import "WXApi.h"  
  3. #import "AppDelegate.h"  
  4. //微信开发者ID  
  5. #define URL_APPID @"appid "  
  6. #define URL_SECRET @"app secret"  
  7. #import "AFNetworking.h"  
  8. @interface ViewController ()<WXDelegate>  
  9. {  
  10.     AppDelegate *appdelegate;  
  11. }  
  12. @end  
  13.   
  14. @implementation ViewController  
  15.   
  16. - (void)viewDidLoad {  
  17.     [super viewDidLoad];  
  18.     // Do any additional setup after loading the view, typically from a nib.  
  19. }  
  20. #pragma mark 微信登录  
  21. - (IBAction)weixinLoginAction:(id)sender {  
  22.       
  23.     if ([WXApi isWXAppInstalled]) {  
  24.         SendAuthReq *req = [[SendAuthReq alloc]init];  
  25.         req.scope = @"snsapi_userinfo";  
  26.         req.openID = URL_APPID;  
  27.         req.state = @"1245";  
  28.         appdelegate = [UIApplication sharedApplication].delegate;  
  29.         appdelegate.wxDelegate = self;  
  30.   
  31.         [WXApi sendReq:req];  
  32.     }else{  
  33.         //把微信登录的按钮隐藏掉。  
  34.     }  
  35. }  
  36. #pragma mark 微信登录回调。  
  37. -(void)loginSuccessByCode:(NSString *)code{  
  38.     NSLog(@"code %@",code);  
  39.     __weak typeof(*&self) weakSelf = self;  
  40.       
  41.     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];  
  42.     manager.requestSerializer = [AFJSONRequestSerializer serializer];//请求  
  43.     manager.responseSerializer = [AFHTTPResponseSerializer serializer];//响应  
  44.     manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json", @"text/json",@"text/plain", nil nil];  
  45.     //通过 appid  secret 认证code . 来发送获取 access_token的请求  
  46.     [manager GET:[NSString stringWithFormat:@"] parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {  
  47.          
  48.     } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {  //获得access_token,然后根据access_token获取用户信息请求。  
  49.   
  50.         NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];  
  51.         NSLog(@"dic %@",dic);  
  52.           
  53.         /* 
  54.          access_token   接口调用凭证 
  55.          expires_in access_token接口调用凭证超时时间,单位(秒) 
  56.          refresh_token  用户刷新access_token 
  57.          openid 授权用户唯一标识 
  58.          scope  用户授权的作用域,使用逗号(,)分隔 
  59.          unionid     当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段 
  60.          */  
  61.         NSString* accessToken=[dic valueForKey:@"access_token"];  
  62.         NSString* openID=[dic valueForKey:@"openid"];  
  63.         [weakSelf requestUserInfoByToken:accessToken andOpenid:openID];  
  64.     } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {  
  65.      NSLog(@"error %@",error.localizedFailureReason);  
  66.     }];  
  67.       
  68. }  
  69.   
  70. -(void)requestUserInfoByToken:(NSString *)token andOpenid:(NSString *)openID{  
  71.       
  72.     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];  
  73.     manager.requestSerializer = [AFJSONRequestSerializer serializer];  
  74.     manager.responseSerializer = [AFHTTPResponseSerializer serializer];  
  75.     [manager GET:[NSString stringWithFormat:@"] parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {  
  76.           
  77.     } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {  
  78.         NSDictionary *dic = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];  
  79.         //开发人员拿到相关微信用户信息后, 需要与后台对接,进行登录  
  80.         NSLog(@"login success dic  ==== %@",dic);  
  81.           
  82.     } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {  
  83.         NSLog(@"error %ld",(long)error.code);  
  84.     }];  
  85. }  
  86.   
  87. #pragma mark 微信好友分享  
  88. /** 
  89.  *  微信分享对象说明 
  90.  * 
  91.  *  @param sender  
  92. WXMediaMessage    多媒体内容分享 
  93. WXImageObject      多媒体消息中包含的图片数据对象 
  94. WXMusicObject      多媒体消息中包含的音乐数据对象 
  95. WXVideoObject      多媒体消息中包含的视频数据对象 
  96. WXWebpageObject    多媒体消息中包含的网页数据对象 
  97. WXAppExtendObject  返回一个WXAppExtendObject对象 
  98. WXEmoticonObject   多媒体消息中包含的表情数据对象 
  99. WXFileObject       多媒体消息中包含的文件数据对象 
  100. WXLocationObject   多媒体消息中包含的地理位置数据对象 
  101. WXTextObject       多媒体消息中包含的文本数据对象 
  102.   
  103.  */  
  104. - (IBAction)weixinShareAction:(id)sender {  
  105.  [self isShareToPengyouquan:NO];  
  106.       
  107. }  
  108.   
  109. #pragma mark 微信朋友圈分享  
  110. - (IBAction)friendShareAction:(id)sender {  
  111.       
  112.     [self isShareToPengyouquan:YES];  
  113. }  
  114. -(void)isShareToPengyouquan:(BOOL)isPengyouquan{  
  115.     /** 标题 
  116.      * @note 长度不能超过512字节 
  117.      */  
  118.     // @property (nonatomic, retain) NSString *title;  
  119.     /** 描述内容 
  120.      * @note 长度不能超过1K 
  121.      */  
  122.     //@property (nonatomic, retain) NSString *description;  
  123.     /** 缩略图数据 
  124.      * @note 大小不能超过32K 
  125.      */  
  126.     //  @property (nonatomic, retain) NSData   *thumbData;  
  127.     /** 
  128.      * @note 长度不能超过64字节 
  129.      */  
  130.     // @property (nonatomic, retain) NSString *mediaTagName;  
  131.     /** 
  132.      * 多媒体数据对象,可以为WXImageObject,WXMusicObject,WXVideoObject,WXWebpageObject等。 
  133.      */  
  134.     // @property (nonatomic, retain) id        mediaObject;  
  135.       
  136.     /*! @brief 设置消息缩略图的方法 
  137.      * 
  138.      * @param image 缩略图 
  139.      * @note 大小不能超过32K 
  140.      */  
  141.     //- (void) setThumbImage:(UIImage *)image;  
  142.     //缩略图  
  143.     UIImage *image = [UIImage imageNamed:@"消息中心 icon"];  
  144.     WXMediaMessage *message = [WXMediaMessage message];  
  145.     message.title = @"微信分享测试";  
  146.     message.description = @"微信分享测试----描述信息";  
  147.     //png图片压缩成data的方法,如果是jpg就要用 UIImageJPEGRepresentation  
  148.     message.thumbData = UIImagePNGRepresentation(image);  
  149.     [message setThumbImage:image];  
  150.       
  151.   
  152.     WXWebpageObject *ext = [WXWebpageObject object];  
  153.     ext.webpageUrl = @"";  
  154.     message.mediaObject = ext;  
  155.     message.mediaTagName = @"ISOFTEN_TAG_JUMP_SHOWRANK";  
  156.       
  157.     SendMessageToWXReq *sentMsg = [[SendMessageToWXReq alloc]init];  
  158.     sentMsg.message = message;  
  159.     sentMsg.bText = NO;  
  160.     //选择发送到会话(WXSceneSession)或者朋友圈(WXSceneTimeline)  
  161.     if (isPengyouquan) {  
  162.         sentMsg.scene = WXSceneTimeline;  //分享到朋友圈  
  163.     }else{  
  164.         sentMsg.scene =  WXSceneSession;  //分享到会话。  
  165.     }  
  166.       
  167.     //如果我们想要监听是否成功分享,我们就要去appdelegate里面 找到他的回调方法  
  168.     // -(void) onResp:(BaseResp*)resp .我们可以自定义一个代理方法,然后把分享的结果返回回来。  
  169.     appdelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;  
  170.     appdelegate.wxDelegate = self;  
  171.     BOOL isSuccess = [WXApi sendReq:sentMsg];  
  172.       
  173.       
  174.     //添加对appdelgate的微信分享的代理  
  175.       
  176. }  
  177.   
  178. #pragma mark 监听微信分享是否成功 delegate  
  179. -(void)shareSuccessByCode:(int)code{  
  180.     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"分享成功" message:[NSString stringWithFormat:@"reason : %d",code] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil nil];  
  181.     [alert show];  
  182. }  
  183.   
  184.   
  185.   
  186. - (void)didReceiveMemoryWarning {  
  187.     [super didReceiveMemoryWarning];  
  188.     // Dispose of any resources that can be recreated.  
  189. }  
  190.   
  191. @end  

源码下载地址:

微信分享前提: 1.需要成功在微信开发者平台注册了账号, 并取的...

概述

Web SDK 开发手册

环信IM的功能一直在演化,比如推送功能和聊天室功能是不久前的版本中添加的。

SDK 概述

网易云信 SDK 为 Web 应用提供一个完善的 IM 系统开发框架, 屏蔽掉 IM 系统的复杂的细节, 对外提供较为简洁的 API 接口, 方便第三方应用快速集成 IM 功能。
网易云信还开发了可供开发者们参考,如何使用该SDK的Web Demo:

  • Web源码导读
  • Web(移动端H5)源码导读(不包含音视频)

在前面对环信IM有了基本了解后,下来我们通过分析Demo,来看看它是如何使用UI库和SDK库,它的主要结构怎么设计的,从而为开发FSIM做好基础。

开发准备

主要数据结构和操作

下载并引入 SDK 文件

  • 从云信官网下载 Web SDK 并解压
  • 目录结构介绍
  • 如果要在浏览器里面使用 SDK, 相应的 JS 文件都在 js 目录下.
  • 如果要在微信小程序里面使用 SDK, 相应的 JS 文件在 weixin-app 目录下.
  • 选择并引入
  • 如果要使用 IM 功能, 请引入 NIM_Web_NIM_v.js
  • 如果通过 script 标签引入, 请通过 NIM 来获取引用
  • 如果要使用聊天室功能, 请引入 NIM_Web_Chatroom_v.js
  • 如果通过 script 标签引入, 请通过 Chatroom 来获取引用
  • 如果同时使用 IM 和聊天室功能, 请引入 NIM_Web_SDK_v.js
  • <p style='color: #d9534f;'>如果通过 script 标签引入, 请通过 SDK.NIMSDK.Chatroom 来获取 NIMChatroom 的引用, 下文中的 API 都是通过 NIMChatroom 来调用的</p>
  • 如果要使用 IM 的插件版实时音视频功能, 请引入 NIM_Web_Netcall_v.js, 通过 Netcall 来获取引用, 调用 NIM.use(Netcall) 来加载实时音视频插件
  • 如果要使用 IM 的WebRTC实时音视频功能, 请引入 NIM_Web_WebRTC_v.js, 通过 WebRTC 来获取引用, 调用 NIM.use(WebRTC) 来加载实时音视频插件

1. 消息Message

打包

如果开发者选用 webpack/babel 来打包, 那么请使用 exclude 将 SDK 文件排除, 避免 babel 二次打包引起的错误

对应的数据结构是EMMessage。

浏览器兼容性

云信 Web SDK (不包含实时音视频)兼容到 IE8

  • IE8/IE9 需要将项目部署在 HTTPS 环境下才能连接到云信服务器, 其它高级浏览器可以在 HTTP 或者 HTTPS 环境下连接到云信服务器

按类型分为文字消息EMChatText,图片消息EMChatImage,位置消息EMChatLocation,语音消息EMChatVoice,视频消息EMChatVideo,文件消息EMChatFile,透传消息EMChatCommand(服务器发送指令给客户端做特殊操作);按传送范围,分为单聊eMessageTypeChat,群聊eConversationTypeGroupChat,聊天室eConversationTypeChatRoom等类型。

数据库兼容性

在支持数据库的浏览器上 SDK 会将数据缓存到数据库中, 后续同步都是增量更新, 加快初始化速度

在单聊环境下插入一条文本消息的代码示例:

是否支持数据库

// 通过此 `boolean` 值来查看 SDK 在某个浏览器上是否支持数据库
NIM.support.db

复制代码

不使用数据库

如果开发者不想使用数据库, 那么可以设置初始化参数dbfalse来禁用数据库

var nim = NIM.getInstance({
db: false
});

1--EMChatText *txt = [[EMChatText alloc] initWithText:@"test1"];

2--EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithChatObject:txt];

3--EMMessage *message = [[EMMessage alloc] initWithReceiver:_conversation.chatter bodies:@[body]];

4--message.messageType = eMessageTypeChat;

5--message.deliveryState = eMessageDeliveryState_Delivered;

6--[[EaseMob sharedInstance].chatManager insertMessageToDB:message];

微信小程序

使用前请找技术支持开通功能

消息的操作,除了创建,还有发送,接收在线或者离线消息,消息解析,消息已送达和消息已读回执,这也就是聊天chat的主要操作。

require

请查阅开发准备来下载并引入 SDK 文件

  • 一个微信小程序同时只能有一个 WebSocket 连接, 所以没有办法同时使用 NIM 和 Chatroom
  • 示例代码如下
// 只使用 NIM
var NIM = require('NIM_Web_NIM_v')
// 只使用 Chatroom
var Chatroom = require('NIM_Web_Chatroom_v')

注意:登陆成功之后才能进行聊天操作。发消息时,单聊和群聊调用的是统一接口,区别只是要设置下message.isGroup属性。

接口调用

微信小程序的大部分接口跟浏览器环境完全一致, 如有不同会额外说明, 请查阅其它章节

异步发送消息接口:

真机准备

在微信公众品台 > 设置 > 开发设置 > 服务器配置, 配置域名白名单. 注意一个月内可申请3次修改, 请慎重修改.

设置 IM 需要的域名

  • request合法域名
  • lbs.netease.im
  • wlnimsc0.netease.im
  • socket合法域名
  • wlnimsc0.netease.im
  • uploadFile合法域名
  • nos.netease.com
  • downloadFile合法域名
  • nos.netease.com

设置聊天室需要的域名

  • request合法域名
  • wlnim43.netease.im
  • socket合法域名
  • wlnim43.netease.im
  • uploadFile合法域名
  • nos.netease.com
  • downloadFile合法域名
  • nos.netease.com

复制代码

依赖说明

  • SDK 使用一系列开源库来更好的完成工作, 所有库均挂在 NIM 下面
  • SDK 使用 es5-shim 来让低版本浏览器兼容 ES5 的部分方法
  • SDK 使用 platform.js 来检测浏览器平台, 通过 NIM.platform 来获取此库的引用
  • SDK 使用 socket.io-client 0.9 来建立 Socket 连接, 通过 NIM.iowindow.io 来获取此库的引用

/*!

@method

@brief 异步方法, 发送一条消息

@discussion 待发送的消息对象和发送后的消息对象是同一个对象, 在发送过程中对象属性可能会被更改. 在发送过程中, willSendMessage:error:和didSendMessage:error:这两个回调会被触发

@param message  消息对象(包括from, to, body列表等信息)

@param progress 发送多媒体信息时的progress回调对象

@result 发送的消息对象(因为是异步方法, 不能作为发送完成或发送成功失败与否的判断)

*/

- (EMMessage *)asyncSendMessage:(EMMessage *)message

progress:(id)progress;

初始化 SDK

请查阅开发准备来下载并引入 SDK 文件

在线接收消息接口:

示例代码

  • 此接口为单例模式, 对于同一个账号, 永远返回同一份实例, 即只有第一次调用会初始化一个实例
  • 后续调用此接口会直接返回初始化过的实例, 同时也会调用接口更新配置更新传入的配置
  • 后续调用此接口时, 如果连接已断开, 会自动建立连接
  • 当发生掉线时,SDK会自动进行重连
  • 开发者在收到onconnect回调之后代表链接已经建立, 此时 SDK 会开始同步数据, 随后在收到onsyncdone回调之后表示 SDK 完成了数据同步工作, 此时开发者可以进行渲染UI等操作了。
  • 这里的data代表数据, 在后面章节的示例代码中会多次用到这个对象
  • 这里的nim代表 SDK, 在后面章节的示例代码中会多次用到这个对象.
  • 这里的参数并不是所有的初始化参数, 请查阅其它章节的初始化参数
  • 初始化SDK
  • 多端登录初始化参数
  • 用户关系初始化参数
  • 好友关系初始化参数
  • 用户名片初始化参数
  • 群组初始化参数
  • 会话初始化参数
  • 消息初始化参数
  • 系统通知初始化参数
  • 同步完成
  • 完整的初始化代码
var data = {};
// 注意这里, 引入的 SDK 文件不一样的话, 你可能需要使用 SDK.NIM.getInstance 来调用接口
var nim = NIM.getInstance({
// debug: true,
appKey: 'appKey',
account: 'account',
token: 'token',
onconnect: onConnect,
onwillreconnect: onWillReconnect,
ondisconnect: onDisconnect,
onerror: onError
});
function onConnect() {
console.log('连接成功');
}
function onWillReconnect(obj) {
// 此时说明 SDK 已经断开连接, 请开发者在界面上提示用户连接已断开, 而且正在重新建立连接
console.log('即将重连');
console.log(obj.retryCount);
console.log(obj.duration);
}
function onDisconnect(error) {
// 此时说明 SDK 处于断开状态, 开发者此时应该根据错误码提示相应的错误信息, 并且跳转到登录页面
console.log('丢失连接');
console.log(error);
if (error) {
switch (error.code) {
// 账号或者密码错误, 请跳转到登录页面并提示错误
case 302:
break;
// 重复登录, 已经在其它端登录了, 请跳转到登录页面并提示错误
case 417:
break;
// 被踢, 请提示错误后跳转到登录页面
case 'kicked':
break;
default:
break;
}
}
}
function onError(error) {
console.log(error);
}

复制代码

参数解释

  • debug: 是否开启日志, 开发者可以开启日志, 这样 SDK 会将关键操作的信息打印到控制台上, 便于调试
  • appKey: 在云信管理后台查看应用的 appKey
  • account: 帐号, 应用内唯一
  • token: 帐号的 token, 用于建立连接
  • transports: 用于建立长连接的协议数组,可不填,默认为['websocket', 'xhr-polling']
  • 默认状态 sdk优先使用websocket连接,如果浏览器不支持websocket,则使用xhr-polling
  • 开发者可手动设置连接及顺序,可支持选项包括websocket、xhr-polling、flashsocket
  • 示例如: transports: ['websocket'、'xhr-polling'、'flashsocket']
  • onconnect: 连接建立后的回调, 会传入一个对象, 包含登录的信息, 有以下字段
  • lastLoginDeviceId: 上次登录的设备的设备号
  • connectionId: 本次登录的连接号
  • ip: 客户端IP
  • port: 客户端端口
  • country: 本次登录的国家
  • onwillreconnect: 即将重连的回调
  • 此时说明 SDK 已经断开连接, 请开发者在界面上提示用户连接已断开, 而且正在重新建立连接
  • 此回调会收到一个对象, 包含额外的信息, 有以下字段
  • duration: 距离下次重连的时间
  • retryCount: 重连尝试的次数
  • ondisconnect: 断开连接后的回调
  • 此时说明 SDK 处于断开状态, 开发者此时应该根据错误码提示相应的错误信息, 并且跳转到登录页面
  • 此回调会收到一个对象, 包含错误的信息, 有以下字段
  • code: 出错时的错误码, 可能为空
  • 302: 账号或者密码错误, 请跳转到登录页面并提示错误
  • 417: 重复登录, 已经在其它端登录了, 请跳转到登录页面并提示错误
  • 'kicked': 被踢
  • onerror: 发生错误的回调, 会传入错误对象

/*!

@method

@brief 收到消息时的回调

@param message      消息对象

@discussion 当EMConversation对象的enableReceiveMessage属性为YES时, 会触发此回调

针对有附件的消息, 此时附件还未被下载.

附件下载过程中的进度回调请参考didFetchingMessageAttachments:progress:,

下载完所有附件后, 回调didMessageAttachmentsStatusChanged:error:会被触发

*/

- (void)didReceiveMessage:(EMMessage *)message;

同步完成

SDK 在同步完成之后会通知开发者, 开发者可以在此回调之后再初始化自己的界面, 以及进行其他操作, 同步的数据包括下面章节中的

  • 黑名单, 对应回调 onblacklist, 请参考用户关系托管里面的初始化参数
  • 静音列表, 对应回调 onmutelist, 请参考用户关系托管里面的初始化参数
  • 好友, 对应回调 onfriends, 请参考好友关系托管里面的初始化参数
  • 我的名片, 对应回调 onmyinfo, 请参考用户名片托管里面的初始化参数
  • 好友的名片, 对应回调 onusers, 请参考用户名片托管里面的初始化参数
  • 群, 对应回调 onteams, 请参考群组里面的初始化参数
  • 会话, 对应回调 onsessions, 请参考会话里面的初始化参数
  • 漫游消息, 对应回调 onroamingmsgs, 请参考消息里面的初始化参数
  • 离线消息, 对应回调 onofflinemsgs, 请参考消息里面的初始化参数
  • 离线系统通知, 对应回调 onofflinesysmsgs, 请参考系统通知里面的初始化参数
  • 离线自定义系统通知, 对应回调 onofflinecustomsysmsgs, 请参考系统通知里面的初始化参数

示例代码

  • 这里的参数并不是所有的初始化参数, 请查阅初始化 SDK, 以及其它章节的初始化参数
  • 初始化SDK
  • 多端登录初始化参数
  • 用户关系初始化参数
  • 好友关系初始化参数
  • 用户名片初始化参数
  • 群组初始化参数
  • 会话初始化参数
  • 消息初始化参数
  • 系统通知初始化参数
  • 同步完成
  • 完整的初始化代码
var nim = NIM.getInstance({
onsyncdone: onSyncDone,
});
function onSyncDone() {
console.log('同步完成');
}

2. 会话Conversation

同步开关

SDK 默认会同步所有的数据, 开发者可以通过开关来选择不同步某些数据, 这些开关都是初始化参数

  • syncRelations, 是否同步黑名单和静音列表, 默认true. 如果传false就收不到黑名单和静音列表, 即不会收到onblacklist回调和onmutelist回调, 开发者后续可以调用获取黑名单和静音列表来获取黑名单和静音列表。
  • syncFriends, 是否同步好友列表, 默认true. 如果传false就收不到onfriends回调, 开发者后续可以调用获取好友列表来获取好友列表。
  • syncFriendUsers, 是否同步好友对应的用户名片列表, 默认true, 如果传false就收不到onusers回调.
  • syncRobots, 是否同步机器人列表,默认false, 如果传false就收不到onrobots回调。
  • syncTeams, 是否同步群列表, 默认true. 如果传false就收不到群列表, 即不会收到onteams回调, 开发者后续可以调用获取群列表来获取群列表.
  • syncExtraTeamInfo, 是否同步额外的群信息, 默认true会同步额外的群信息, 目前包括
  • 当前登录用户是否开启某个群的消息提醒 (SDK 只是存储了此信息, 具体用此信息来做什么事情完全由开发者控制)
  • 调用接口修改自己的群属性来关闭/开启某个群的消息提醒
  • 调用接口是否需要群消息通知来查询是否需要群消息通知
  • syncTeamMembers, 是否同步群成员, 默认true. 只有在syncTeams=true的时候才起作用, 如果传false就不会同步群成员, 即不会收到onteammembersonsyncteammembersdone回调, 开发者后续可以调用获取群成员来获取群成员.
  • syncRoamingMsgs, 是否同步漫游消息, 默认true. 如果传false就收不到漫游消息, 即不会收到onroamingmsgs回调.
  • syncMsgReceipts, 是否同步已读回执时间戳, 默认true. 如果传false就收不到已读回执时间戳.

示例代码

  • 这里的参数并不是所有的初始化参数, 请查阅初始化 SDK, 以及其它章节的初始化参数
  • 初始化SDK
  • 多端登录初始化参数
  • 用户关系初始化参数
  • 好友关系初始化参数
  • 用户名片初始化参数
  • 群组初始化参数
  • 会话初始化参数
  • 消息初始化参数
  • 系统通知初始化参数
  • 同步完成
  • 完整的初始化代码
var nim = NIM.getInstance({
syncRelations: false
});

会话是操作聊天消息EMMessage的容器,也就是说我们可以通过会话获得聊天记录。对应的数据结构是EMConversation。

完整的初始化代码

  • 请查阅其它章节的初始化参数
  • 初始化SDK
  • 多端登录初始化参数
  • 用户关系初始化参数
  • 好友关系初始化参数
  • 用户名片初始化参数
  • 群组初始化参数
  • 会话初始化参数
  • 消息初始化参数
  • 系统通知初始化参数
  • 同步完成
  • 完整的初始化代码
var data = {};
var nim = NIM.getInstance({
// 初始化SDK
// debug: true
appKey: 'appKey',
account: 'account',
token: 'token',
onconnect: onConnect,
onerror: onError,
onwillreconnect: onWillReconnect,
ondisconnect: onDisconnect,
// 多端登录
onloginportschange: onLoginPortsChange,
// 用户关系
onblacklist: onBlacklist,
onsyncmarkinblacklist: onMarkInBlacklist,
onmutelist: onMutelist,
onsyncmarkinmutelist: onMarkInMutelist,
// 好友关系
onfriends: onFriends,
onsyncfriendaction: onSyncFriendAction,
// 用户名片
onmyinfo: onMyInfo,
onupdatemyinfo: onUpdateMyInfo,
onusers: onUsers,
onupdateuser: onUpdateUser,
onrobots: onRobots,
// 群组
onteams: onTeams,
onsynccreateteam: onCreateTeam,
onteammembers: onTeamMembers,
onsyncteammembersdone: onSyncTeamMembersDone,
onupdateteammember: onUpdateTeamMember,
// 会话
onsessions: onSessions,
onupdatesession: onUpdateSession,
// 消息
onroamingmsgs: onRoamingMsgs,
onofflinemsgs: onOfflineMsgs,
onmsg: onMsg,
// 系统通知
onofflinesysmsgs: onOfflineSysMsgs,
onsysmsg: onSysMsg,
onupdatesysmsg: onUpdateSysMsg,
onsysmsgunread: onSysMsgUnread,
onupdatesysmsgunread: onUpdateSysMsgUnread,
onofflinecustomsysmsgs: onOfflineCustomSysMsgs,
oncustomsysmsg: onCustomSysMsg,
// 同步完成
onsyncdone: onSyncDone
});

function onConnect() {
console.log('连接成功');
}
function onWillReconnect(obj) {
// 此时说明 `SDK` 已经断开连接, 请开发者在界面上提示用户连接已断开, 而且正在重新建立连接
console.log('即将重连');
console.log(obj.retryCount);
console.log(obj.duration);
}
function onDisconnect(error) {
// 此时说明 `SDK` 处于断开状态, 开发者此时应该根据错误码提示相应的错误信息, 并且跳转到登录页面
console.log('丢失连接');
console.log(error);
if (error) {
switch (error.code) {
// 账号或者密码错误, 请跳转到登录页面并提示错误
case 302:
break;
// 被踢, 请提示错误后跳转到登录页面
case 'kicked':
break;
default:
break;
}
}
}
function onError(error) {
console.log(error);
}

function onLoginPortsChange(loginPorts) {
console.log('当前登录帐号在其它端的状态发生改变了', loginPorts);
}

function onBlacklist(blacklist) {
console.log('收到黑名单', blacklist);
data.blacklist = nim.mergeRelations(data.blacklist, blacklist);
data.blacklist = nim.cutRelations(data.blacklist, blacklist.invalid);
refreshBlacklistUI();
}
function onMarkInBlacklist(obj) {
console.log(obj);
console.log(obj.account + '被你在其它端' + (obj.isAdd ? '加入' : '移除') + '黑名单');
if (obj.isAdd) {
addToBlacklist(obj);
} else {
removeFromBlacklist(obj);
}
}
function addToBlacklist(obj) {
data.blacklist = nim.mergeRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function removeFromBlacklist(obj) {
data.blacklist = nim.cutRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function refreshBlacklistUI() {
// 刷新界面
}
function onMutelist(mutelist) {
console.log('收到静音列表', mutelist);
data.mutelist = nim.mergeRelations(data.mutelist, mutelist);
data.mutelist = nim.cutRelations(data.mutelist, mutelist.invalid);
refreshMutelistUI();
}
function onMarkInMutelist(obj) {
console.log(obj);
console.log(obj.account + '被你' + (obj.isAdd ? '加入' : '移除') + '静音列表');
if (obj.isAdd) {
addToMutelist(obj);
} else {
removeFromMutelist(obj);
}
}
function addToMutelist(obj) {
data.mutelist = nim.mergeRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function removeFromMutelist(obj) {
data.mutelist = nim.cutRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function refreshMutelistUI() {
// 刷新界面
}

function onFriends(friends) {
console.log('收到好友列表', friends);
data.friends = nim.mergeFriends(data.friends, friends);
data.friends = nim.cutFriends(data.friends, friends.invalid);
refreshFriendsUI();
}
function onSyncFriendAction(obj) {
console.log(obj);
switch (obj.type) {
case 'addFriend':
console.log('你在其它端直接加了一个好友' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'applyFriend':
console.log('你在其它端申请加了一个好友' + obj.account + ', 附言' + obj.ps);
break;
case 'passFriendApply':
console.log('你在其它端通过了一个好友申请' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'rejectFriendApply':
console.log('你在其它端拒绝了一个好友申请' + obj.account + ', 附言' + obj.ps);
break;
case 'deleteFriend':
console.log('你在其它端删了一个好友' + obj.account);
onDeleteFriend(obj.account);
break;
case 'updateFriend':
console.log('你在其它端更新了一个好友', obj.friend);
onUpdateFriend(obj.friend);
break;
}
}
function onAddFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function onDeleteFriend(account) {
data.friends = nim.cutFriendsByAccounts(data.friends, account);
refreshFriendsUI();
}
function onUpdateFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function refreshFriendsUI() {
// 刷新界面
}

function onMyInfo(user) {
console.log('收到我的名片', user);
data.myInfo = user;
updateMyInfoUI();
}
function onUpdateMyInfo(user) {
console.log('我的名片更新了', user);
data.myInfo = NIM.util.merge(data.myInfo, user);
updateMyInfoUI();
}
function updateMyInfoUI() {
// 刷新界面
}
function onUsers(users) {
console.log('收到用户名片列表', users);
data.users = nim.mergeUsers(data.users, users);
}
function onUpdateUser(user) {
console.log('用户名片更新了', user);
data.users = nim.mergeUsers(data.users, user);
}
function onRobots (robots) {
console.log('收到机器人列表', robots);
data.robots = robots;
}
function onTeams(teams) {
console.log('群列表', teams);
data.teams = nim.mergeTeams(data.teams, teams);
onInvalidTeams(teams.invalid);
}
function onInvalidTeams(teams) {
data.teams = nim.cutTeams(data.teams, teams);
data.invalidTeams = nim.mergeTeams(data.invalidTeams, teams);
refreshTeamsUI();
}
function onCreateTeam(team) {
console.log('你创建了一个群', team);
data.teams = nim.mergeTeams(data.teams, team);
refreshTeamsUI();
onTeamMembers({
teamId: team.teamId,
members: owner
});
}
function refreshTeamsUI() {
// 刷新界面
}
function onTeamMembers(teamId, members) {
console.log('群id', teamId, '群成员', members);
var teamId = obj.teamId;
var members = obj.members;
data.teamMembers = data.teamMembers || {};
data.teamMembers[teamId] = nim.mergeTeamMembers(data.teamMembers[teamId], members);
data.teamMembers[teamId] = nim.cutTeamMembers(data.teamMembers[teamId], members.invalid);
refreshTeamMembersUI();
}
function onSyncTeamMembersDone() {
console.log('同步群列表完成');
}
function onUpdateTeamMember(teamMember) {
console.log('群成员信息更新了', teamMember);
onTeamMembers({
teamId: teamMember.teamId,
members: teamMember
});
}
function refreshTeamMembersUI() {
// 刷新界面
}

function onSessions(sessions) {
console.log('收到会话列表', sessions);
data.sessions = nim.mergeSessions(data.sessions, sessions);
updateSessionsUI();
}
function onUpdateSession(session) {
console.log('会话更新了', session);
data.sessions = nim.mergeSessions(data.sessions, session);
updateSessionsUI();
}
function updateSessionsUI() {
// 刷新界面
}

function onRoamingMsgs(obj) {
console.log('漫游消息', obj);
pushMsg(obj.msgs);
}
function onOfflineMsgs(obj) {
console.log('离线消息', obj);
pushMsg(obj.msgs);
}
function onMsg(msg) {
console.log('收到消息', msg.scene, msg.type, msg);
pushMsg(msg);
}
function pushMsg(msgs) {
if (!Array.isArray(msgs)) { msgs = [msgs]; }
var sessionId = msgs[0].sessionId;
data.msgs = data.msgs || {};
data.msgs[sessionId] = nim.mergeMsgs(data.msgs[sessionId], msgs);
}

function onOfflineSysMsgs(sysMsgs) {
console.log('收到离线系统通知', sysMsgs);
pushSysMsgs(sysMsgs);
}
function onSysMsg(sysMsg) {
console.log('收到系统通知', sysMsg)
pushSysMsgs(sysMsg);
}
function onUpdateSysMsg(sysMsg) {
pushSysMsgs(sysMsg);
}
function pushSysMsgs(sysMsgs) {
data.sysMsgs = nim.mergeSysMsgs(data.sysMsgs, sysMsgs);
refreshSysMsgsUI();
}
function onSysMsgUnread(obj) {
console.log('收到系统通知未读数', obj);
data.sysMsgUnread = obj;
refreshSysMsgsUI();
}
function onUpdateSysMsgUnread(obj) {
console.log('系统通知未读数更新了', obj);
data.sysMsgUnread = obj;
refreshSysMsgsUI();
}
function refreshSysMsgsUI() {
// 刷新界面
}
function onOfflineCustomSysMsgs(sysMsgs) {
console.log('收到离线自定义系统通知', sysMsgs);
}
function onCustomSysMsg(sysMsg) {
console.log('收到自定义系统通知', sysMsg);
}

function onSyncDone() {
console.log('同步完成');
}

SDK中对应会话的操作,包括创建,删除,获取单个或者获取所有会话等操作。下面是创建和8001的会话示例代码:

登录与登出

复制代码

登出 IM

  • 初始化 SDK之后, SDK 会自动登录
  • 在收到onconnect回调后可以调用nim.disconnect();来登出 SDK
  • 登出 SDK 后可以调用nim.connect();来重新登入 SDK

EMConversation *conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:@"8001"conversationType:eConversationTypeChat];

切换 IM

如果需要切换 IM, 操作步骤如下

  • 调用登出IM来登出IM
  • 调用初始化SDK来初始化新的 IM

3. 群组Group

更新 IM 配置

SDK 设计为单例模式, 如果需要更新当前 IM 的配置, 那么可以调用此接口, 参数列表和格式跟NIM.getInstance保持一致, 以更新 token 为例

// 断开 IM
nim.disconnect();
// 更新 token
nim.setOptions({
token: 'newToken'
});
// 重新连接
nim.connect();

群组分为两大类(公开群组与私有群组),并根据邀请方式进一步细分为四小类。

多端登录

云信支持多端同时登录, 即用户可以同时在移动端和网页端登录同一账号

群组只有一个owner,为其创建者。有人数的限制。数据结构为EMGroup。

初始化参数

  • 这里的参数并不是所有的初始化参数, 请查阅初始化 SDK, 以及其它章节的初始化参数
  • 初始化SDK
  • 多端登录初始化参数
  • 用户关系初始化参数
  • 好友关系初始化参数
  • 用户名片初始化参数
  • 群组初始化参数
  • 会话初始化参数
  • 消息初始化参数
  • 系统通知初始化参数
  • 同步完成
  • 完整的初始化代码

示例代码

var nim = NIM.getInstance({
onloginportschange: onLoginPortsChange
});
function onLoginPortsChange(loginPorts) {
console.log('当前登录帐号在其它端的状态发生改变了', loginPorts);
}

参数解释

  • onloginportschange: 多端登录状态变化的回调, 会收到登录端列表, 以下情况会收到此回调
  • 登录时其它端在线
  • 登录后其它端上线或者下线

操作包括:创建,查询,加入,退出,解散,黑名单管理等操作。

登录端

登录端代表登录在某个设备上的相关信息, 有如下字段

  • type: 登录的设备类型
  • os: 登录设备的操作系统
  • mac: 登录设备的 mac 地址
  • deviceId: 登录设备ID, uuid
  • account: 登录的帐号
  • connectionId: 登录设备分配的连接号
  • ip: 登录的服务器 IP
  • time: 登录时间
  • online: 是否在线

4. 聊天室Chatroom

设备类型

目前云信支持的登录端有以下几种类型

  • 'Android' (安卓)
  • 'iOS' (苹果)
  • 'PC' (桌面)
  • 'Web' (浏览器)
  • 'Mac' (桌面)

相对于群组,聊天室比较简单些。环信官网关于“聊天室”模型的说明如下:

踢其它端

示例代码

nim.kick({
deviceIds: ['deviceId1'],
done: onKick
});
function onKick(error, obj) {
console.log('踢其它端' + (!error?'成功':'失败'));
console.log(error);
console.log(obj);
}

参数解释

  • 其它登录端的设备号可以在onloginportschange回调里获取, 参考登录端对象

进入聊天页面之前,进行加入聊天室操作;

用户关系托管

SDK 提供了用户关系托管, 包括黑名单和静音列表

成功进入聊天室之后,服务器会自动给推10条消息;

黑名单

  • 如果一个用户被加入了黑名单, 那么就不再会收到此用户发送的消息
  • 如果一个用户被从黑名单移除, 那么会重新收到此用户发送的消息

离开聊天页面之后,进行退出聊天室操作;

静音列表

  • SDK只负责维护静音列表, 具体根据静音列表要进行的操作由开发者决定

聊天室创建者owner可以进行退出聊天室操作;

初始化参数

  • 这里的参数并不是所有的初始化参数, 请查阅初始化 SDK, 以及其它章节的初始化参数
  • 初始化SDK
  • 多端登录初始化参数
  • 用户关系初始化参数
  • 好友关系初始化参数
  • 用户名片初始化参数
  • 群组初始化参数
  • 会话初始化参数
  • 消息初始化参数
  • 系统通知初始化参数
  • 同步完成
  • 完整的初始化代码

示例代码

var nim = NIM.getInstance({
onblacklist: onBlacklist,
onsyncmarkinblacklist: onMarkInBlacklist,
onmutelist: onMutelist,
onsyncmarkinmutelist: onMarkInMutelist
});
function onBlacklist(blacklist) {
console.log('收到黑名单', blacklist);
data.blacklist = nim.mergeRelations(data.blacklist, blacklist);
data.blacklist = nim.cutRelations(data.blacklist, blacklist.invalid);
refreshBlacklistUI();
}
function onMarkInBlacklist(obj) {
console.log(obj);
console.log(obj.account + '被你' + (obj.isAdd ? '加入' : '移除') + '黑名单');
if (obj.isAdd) {
addToBlacklist(obj);
} else {
removeFromBlacklist(obj);
}
}
function addToBlacklist(obj) {
data.blacklist = nim.mergeRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function removeFromBlacklist(obj) {
data.blacklist = nim.cutRelations(data.blacklist, obj.record);
refreshBlacklistUI();
}
function refreshBlacklistUI() {
// 刷新界面
}
function onMutelist(mutelist) {
console.log('收到静音列表', mutelist);
data.mutelist = nim.mergeRelations(data.mutelist, mutelist);
data.mutelist = nim.cutRelations(data.mutelist, mutelist.invalid);
refreshMutelistUI();
}
function onMarkInMutelist(obj) {
console.log(obj);
console.log(obj.account + '被你' + (obj.isAdd ? '加入' : '移除') + '静音列表');
if (obj.isAdd) {
addToMutelist(obj);
} else {
removeFromMutelist(obj);
}
}
function addToMutelist(obj) {
data.mutelist = nim.mergeRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function removeFromMutelist(obj) {
data.mutelist = nim.cutRelations(data.mutelist, obj.record);
refreshMutelistUI();
}
function refreshMutelistUI() {
// 刷新界面
}

参数解释

  • onblacklist: 同步黑名单的回调, 会传入黑名单列表blacklist
  • blacklist的属性invalid包含被删除的黑名单列表
  • 此回调是增量回调, 可以调用nim.mergeRelations和nim.cutRelations来合并数据
  • onsyncmarkinblacklist: 当前登录用户在其它端加入黑名单/从黑名单移除后的回调, 会传入一个参数, 包含两个字段
  • account: 要加入黑名单/从黑名单移除的账号
  • isAdd: true表示加入黑名单, false表示从黑名单移除
  • reocrd, 拼装好的对象
  • onmutelist: 同步静音列表的回调, 会传入静音列表mutelist
  • mutelist的属性invalid包含被删除的静音列表
  • 此回调是增量回调, 可以调用nim.mergeRelations和nim.cutRelations来合并数据
  • onsyncmarkinmutelist: 当前登录用户在其它端加入静音列表/从静音列表移除后的回调, 会传入一个参数, 包含两个字段
  • account: 要加入静音列表/从静音列表移除的账号
  • isAdd: true表示加入静音列表, false表示从静音列表移除
  • reocrd, 拼装好的对象

支持最大成员5000;

加入黑名单/从黑名单移除

  • 此接口可以完成以下两个功能, 通过参数isAdd来决定实际的功能
  • isAddtrue时, 会将account加入黑名单
  • 如果一个用户被加入了黑名单, 那么就不再会收到此用户发送的消息
  • isAddfalse时, 会将account从黑名单移除
  • 如果一个用户被从黑名单移除, 那么会重新收到此用户发送的消息
  • 每个功能SDK都提供了相应的独立接口
nim.markInBlacklist({
account: 'account',
// `true`表示加入黑名单, `false`表示从黑名单移除
isAdd: true,
done: markInBlacklistDone
});
function markInBlacklistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('将' + obj.account + (isAdd ? '加入黑名单' : '从黑名单移除') + (!error?'成功':'失败'));
if (!error) {
onMarkInBlacklist(obj);
}
}

环信的聊天室内仅有owner和游客;

加入黑名单

  • 如果一个用户被加入了黑名单, 那么就不再会收到此用户发送的消息
  • SDK内部调用nim.markInBlacklist来完成实际工作
nim.addToBlacklist({
account: 'account',
done: addToBlacklistDone
});
function addToBlacklistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('加入黑名单' + (!error?'成功':'失败'));
if (!error) {
addToBlacklist(obj);
}
}

不支持客户端建立聊天室;

从黑名单移除

  • 如果一个用户被从黑名单移除, 那么会重新收到此用户发送的消息
  • SDK内部调用nim.markInBlacklist来完成实际工作
nim.removeFromBlacklist({
account: 'account',
done: removeFromBlacklistDone
});
function removeFromBlacklistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('从黑名单移除' + (!error?'成功':'失败'));
if (!error) {
removeFromBlacklist(obj);
}
}

不支持客户端邀请;

加入静音列表/从静音列表移除

  • 此接口可以完成以下两个功能, 通过参数isAdd来决定实际的功能
  • isAddtrue时, 会将account加入静音列表
  • isAddfalse时, 会将account从静音列表移除
  • 每个功能SDK都提供了相应的独立接口
nim.markInMutelist({
account: 'account',
// `true`表示加入静音列表, `false`表示从静音列表移除
isAdd: 'true',
done: markInMutelistDone
});
function markInMutelistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('将' + obj.account + (isAdd ? '加入静音列表' : '从静音列表移除') + (!error?'成功':'失败'));
if (!error) {
onMarkInMutelist(obj);
}
}

不支持REST邀请;

加入静音列表

  • SDK只负责维护静音列表, 具体要根据静音列表进行的操作由开发者决定
  • SDK内部调用nim.markInMutelist来完成实际工作
nim.addToMutelist({
account: 'account',
done: addToMutelistDone
});
function addToMutelistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('加入静音列表' + (!error?'成功':'失败'));
if (!error) {
addToMutelist(obj);
}
}

聊天室内成员离线后,服务器当监听到此成员不在线后不在会给此成员再发推送。

从静音列表移除

  • SDK只负责维护静音列表, 具体要根据静音列表进行的操作由开发者决定
  • SDK内部调用nim.markInMutelist来完成实际工作
nim.removeFromMutelist({
account: 'account',
done: removeFromMutelistDone
});
function removeFromMutelistDone(error, obj) {
console.log(error);
console.log(obj);
console.log('从静音列表移除' + (!error?'成功':'失败'));
if (!error) {
removeFromMutelist(obj);
}
}

客户端操作包括:获取聊天室,获取聊天室详情,或许成员,加入和离开聊天室等。

获取黑名单和静音列表

  • 如果开发者在初始化SDK的时候设置了syncRelationsfalse, 那么就收不到onblacklistonmutelist回调, 可以调用此接口来获取黑名单和静音列表。
nim.getRelations({
done: getRelationsDone
});
function getRelationsDone(error, obj) {
console.log('获取静音列表' + (!error?'成功':'失败'), error, obj);
if (!error) {
onBlacklist(obj.blacklist);
onMutelist(obj.mutelist);
}
}

5. 好友BuddyList及黑名单BlockedList

好友关系托管

  • SDK 提供好友关系托管

因此如果未在黑名单上,使用环信可以给任何人发起聊天,不管是不是好友。

好友关系初始化参数

  • 这里的参数并不是所有的初始化参数, 请查阅初始化 SDK, 以及其它章节的初始化参数
  • 初始化SDK
  • 多端登录初始化参数
  • 用户关系初始化参数
  • 好友关系初始化参数
  • 用户名片初始化参数
  • 群组初始化参数
  • 会话初始化参数
  • 消息初始化参数
  • 系统通知初始化参数
  • 同步完成
  • 完整的初始化代码
  • 请参考处理系统通知里面的跟好友相关的逻辑

示例代码

var nim = NIM.getInstance({
onfriends: onFriends,
onsyncfriendaction: onSyncFriendAction
});
function onFriends(friends) {
console.log('收到好友列表', friends);
data.friends = nim.mergeFriends(data.friends, friends);
data.friends = nim.cutFriends(data.friends, friends.invalid);
refreshFriendsUI();
}
function onSyncFriendAction(obj) {
console.log(obj);
switch (obj.type) {
case 'addFriend':
console.log('你在其它端直接加了一个好友' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'applyFriend':
console.log('你在其它端申请加了一个好友' + obj.account + ', 附言' + obj.ps);
break;
case 'passFriendApply':
console.log('你在其它端通过了一个好友申请' + obj.account + ', 附言' + obj.ps);
onAddFriend(obj.friend);
break;
case 'rejectFriendApply':
console.log('你在其它端拒绝了一个好友申请' + obj.account + ', 附言' + obj.ps);
break;
case 'deleteFriend':
console.log('你在其它端删了一个好友' + obj.account);
onDeleteFriend(obj.account);
break;
case 'updateFriend':
console.log('你在其它端更新了一个好友', obj.friend);
onUpdateFriend(obj.friend);
break;
}
}
function onAddFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function onDeleteFriend(account) {
data.friends = nim.cutFriendsByAccounts(data.friends, account);
refreshFriendsUI();
}
function onUpdateFriend(friend) {
data.friends = nim.mergeFriends(data.friends, friend);
refreshFriendsUI();
}
function refreshFriendsUI() {
// 刷新界面
}

参数解释

  • onfriends, 同步好友列表的回调, 会传入好友列表friends
  • friends的属性invalid包含被删除的好友列表
  • 此回调是增量回调, 可以调用nim.mergeFriends和nim.cutFriends来合并数据
  • onsyncfriendaction, 当前登录用户在其它端进行好友相关的操作后的回调
  • 操作包括
  • 直接加为好友
  • 申请加为好友
  • 通过好友申请
  • 拒绝好友申请
  • 删除好友
  • 更新好友
  • 此回调会收到一个参数obj, 它有一个字段type的值为操作的类型, 具体类型如下:
  • 'addFriend' (直接加为好友), 此时obj的字段如下:
  • account的值为被直接加为好友的账号
  • friend为被直接加为好友的好友对象
  • ps为附言
  • 'applyFriend' (申请加为好友), 此时obj的字段如下:
  • account的值为被申请加为好友的账号
  • ps为附言
  • 'passFriendApply' (通过好友申请), 此时obj的字段如下:
  • account的值为被通过好友申请的账号
  • friend为被通过好友申请的好友对象
  • ps为附言
  • 'rejectFriendApply' (拒绝好友申请), 此时obj的字段如下:
  • account的值为被拒绝好友申请的账号
  • ps为附言
  • 'deleteFriend' (删除好友), 此时obj的字段如下:
  • account的值为被删除好友的账号
  • 'updateFriend' (更新好友), 此时obj的字段如下:
  • friend的值为被更新的好友对象
  • 可以调用nim.mergeFriends和nim.cutFriendsByAccounts来合并数据

添加好友的作用是我们可以通过查看好友名单,快速找到好友,与之交流。

好友对象

好友对象有以下字段:

  • account: 账号
  • alias: 昵称
  • custom: 扩展字段, 开发者可以自行扩展, 建议封装成JSON格式字符串
  • createTime: 成为好友的时间
  • updateTime: 更新时间

环信的黑名单体系是独立的,与好友无任何关系。如果将好友加入黑名单,该好友就同时在两个名单中。

直接加为好友

  • 直接加某个用户为好友后, 对方不需要确认, 直接成为当前登录用户的好友
  • ps: 附言, 选填, 开发者也可以使用JSON格式的字符串来扩展此内容
  • 对方会收到一条类型为'addFriend'的系统通知, 此类系统通知的from字段的值为申请方的帐号, to字段的值为接收方的账号。
nim.addFriend({
account: 'account',
ps: 'ps',
done: addFriendDone
});
function addFriendDone(error, obj) {
console.log(error);
console.log(obj);
console.log('直接加为好友' + (!error?'成功':'失败'));
if (!error) {
onAddFriend(obj.friend);
}
}

黑名单类型EMRelationship,包括取值eRelationshipBoth:双向都不接受消息;eRelationshipFrom:能给黑名单中的人发消息,接收不到黑名单中的人发的消息。

申请加为好友

  • 申请加某个用户为好友后, 对方会收到一条类型为'applyFriend'的系统通知, 此类系统通知的from字段的值为申请方的帐号, to字段的值为接收方的账号, 用户在收到好友申请后, 可以选择通过或者拒绝好友申请。
  • 如果通过好友申请, 那么申请方会收到一条类型为'passFriendApply'的系统通知, 此类系统通知的from字段的值为通过方的帐号, to字段的值为申请方的账号。
  • 如果拒绝好友申请, 那么申请方会收到一条类型为'rejectFriendApply'的系统通知, 此类系统通知的from字段的值为拒绝方的帐号, to字段的值为申请方的账号。
  • ps: 附言, 选填, 开发者也可以使用JSON格式的字符串来扩展此内容
nim.applyFriend({
account: 'account',
ps: 'ps',
done: applyFriendDone
});
function applyFriendDone(error, obj) {
console.log(error);
console.log(obj);
console.log('申请加为好友' + (!error?'成功':'失败'));
}

好友操作:获取好友列表,好友申请(发送请求,监听请求,同意请求,拒绝请求),删除好友,

通过好友申请

  • 申请加某个用户为好友后, 对方会收到一条类型为'applyFriend'的系统通知, 此类系统通知的from字段的值为申请方的帐号, to字段的值为接收方的账号, 用户在收到好友申请后, 可以选择通过或者拒绝好友申请。
  • 如果通过好友申请, 那么申请方会收到一条类型为'passFriendApply'的系统通知, 此类系统通知的from字段的值为通过方的帐号, to字段的值为申请方的账号。
  • 如果拒绝好友申请, 那么申请方会收到一条类型为'rejectFriendApply'的系统通知, 此类系统通知的from字段的值为拒绝方的帐号, to字段的值为申请方的账号。
  • ps: 附言, 选填, 开发者也可以使用JSON格式的字符串来扩展此内容
// 假设 sysMsg 是通过回调 `onsysmsg` 收到的系统通知
nim.passFriendApply({
idServer: sysMsg.idServer,
account: 'account',
ps: 'ps',
done: passFriendApplyDone
});
function passFriendApplyDone(error, obj) {
console.log(error);
console.log(obj);
console.log('通过好友申请' + (!error?'成功':'失败'));
if (!error) {
onAddFriend(obj.friend);
}
}

黑名单操作:获取黑名单,加入黑名单,移除黑名单。

郑重声明:本文版权归新匍京a奥门-最全网站手机版app官方下载所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。