iOS之旅--NIM SDK 使用指南_nimsdk-程序员宅基地

技术标签: iOS开发之旅  

便于记录查看地址,方便查找

NIM SDK 使用指南

SDK 概述

网易云信 SDK (NIM SDK) 为移动应用提供完善的 IM 开发框架,屏蔽其内部复杂细节,对外提供较为简洁的 API 接口,方便第三方应用快速集成 IM 功能。SDK 兼容 iOS 7.0+ ,Demo 兼容 iOS 8.0+ 。

开发准备

NIM SDK 提供两种集成方式:您既可以通过 CocoaPods 自动集成我们的 SDK,也可以通过手动下载 SDK, 然后添加到您的项目中。

我们提供两个下载地址。分别为:

  • 官网 SDK 下载入口

  • 我们提供了 GitHub 发布仓库 。NIMSDK,此仓库包含 IM 和音视频功能,您可以根据自己的需求选择下载。

手动添加 SDK

  • 根据自己工程需要,下载对应版本的 NIM SDK,得到 NIMSDK.framework 文件 ( 如果选择音视频版本,还将得到 NIMAVChat.framework 文件 ) ,以及未连接的全部三方依赖库 注1 ,将他们导入工程。

  • 添加其他 NIM SDK 依赖库

    • MobileCoreServices.framework
    • SystemConfiguration.framework
    • AVFoundation.framwork
    • CoreTelephony.framework
    • CoreMedia.framework
    • AudioToolbox.framework
    • VideoToolbox.framework
    • libc++.tbd 注2
    • libsqlite3.0.tbd
    • libz.tbd

    1 :开发者应根据自身项目,将不冲突的依赖库也添加进工程。
    2 :在 SDK 3.0.0 以前版本 (包括 3.0.0) ,c++ 库请使用 libstdc++6.0.9.tbd , 之后的版本统一替换成 libc++.tbd 。

  • 在 Build Settings -> Other Linker Flags 里,添加选项 -ObjC

  • 在需要使用即时通讯 SDK 的地方 import <NIMSDK/NIMSDK.h> ,在需要使用实时音视频 SDK 的地方 import <NIMAVChat/NIMAVChat.h> 。

通过 CocoaPods 集成

在 Podfile 文件中加入

  pod 'NIMSDK'

安装

  pod install

如果无法安装 SDK 最新版本,运行以下命令更新本地的 CocoaPods 仓库列表

  pod repo update

SDK 类说明

NIM SDK 主要提供了如下类(协议)与方法

  • NIMSDK 整个SDK的主入口,单例,主要提供初始化,注册,内部管理类管理的功能
  • NIMLoginManager 登录管理类,负责登录,注销和相应的回调收发
  • NIMChatManager 聊天管理类,负责消息的收发
  • NIMConversationManager 会话管理类,负责消息,最近会话的管理
  • NIMTeamManager 群组管理类,负责群组各种操作
  • NIMMediaManager 媒体管理类,负责多媒体相关的接口,比如录音
  • NIMSystemNotificationManager 系统通知管理类,负责系统消息的接收和存储
  • NIMApnsManager 推送管理类,负责推送的设置和接收
  • NIMResourceManager 资源管理类,负责文件的上传和下载
  • NIMUserManager 好友管理类,负责对好友的增删查,以及对其会话的消息设置
  • NIMChatroomManager 聊天室管理类,负责聊天室状态管理和数据拉取及设置
  • NIMDocTranscodingManager 文档转码管理类,负责文档转码的查询和删除等

NIMAVChat 主要提供了如下类(协议)与方法

  • NIMAVChat 是 NIMSDK 的音视频和实时会话扩展,封装了网络通话、实时会话和网络探测等的管理
  • NIMNetCallManager 音视频网络通话管理类,提供音视频网络通话功能
  • NIMRTSManager 实时会话管理类,提供数据通道 (TCP/语音通道) 来满足实时会话的需求
  • NIMRTSConferenceManager 多人实时会话管理类,提供多人数据通道 (TCP) 来满足多人实时会话的需求
  • NIMAVChatNetDetectManager 音视频网络探测管理类,提供音视频网络状态诊断功能

配置 HTTPS 支持

在默认情况下,SDK 认为用户资料头像,群头像,聊天室类用户头像等信息都是默认托管在云信上,所以 SDK 会针对他们自动开启 HTTPS 支持,开发者不需要任何额外配置。

但如果开发者需要将这些信息都托管在自己的服务器上,需要在 NIMSDKConfig.h 中,将

@property (nonatomic,assign)    BOOL    enabledHttpsForInfo
@property (nonatomic,assign)    BOOL    enabledHttpsForMessage;

设置为 NO,避免 SDK 自动将开发者设置的 HTTP URL 自动转换为 HTTPS URL

因为苹果的 ATS 政策,如果应用中使用了 HTTP 请求,需要将工程配置文件中的 info.plist 文件,NSAppTransportSecurity 条目中适配好 NSExceptionDomains。需要注意的是,2017 年以后,应用中存在 HTTP 请求会有审核被拒的风险。

初始化 SDK

  • 在需要使用 SDK 的地方导入头文件 <NIMSDK/NIMSDK.h> 。
  • 添加 SDK 初始化方法。

    -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
            NIMSDKOption *option    = [NIMSDKOption optionWithAppKey:appKey];
            option.apnsCername      = // APNS 推送证书名
           option.pkCername        = //Pushkit 证书名
          [[NIMSDK sharedSDK] registerWithOption:option];
          return YES;
      }

推荐在 APP 启动时尽快注册 NIM SDK。

登录与登出

在使用 SDK 之前,需要对云信的体系流程有基本的认知,推荐开发者首先阅读这里 。

手动登录

调用

[[[NIMSDK sharedSDK] loginManager] login:account
                                   token:token
                              completion:^(NSError *error) {}];

error为登录错误信息,成功则为nil。不要在登录完成的回调中直接获取 SDK 缓存数据,而应该在 同步完成的回调里获取数据 或者 监听相应的数据变动回调后获取 。

注:在不特殊说明的情况下,SDK 的所有回调都是在主线程中发起,无论是以 block 还是 delegate 的形式,也推荐开发者仅在主线程调用 SDK 相关接口。

获取登录帐号的云信 id:

NSString *userID = [NIMSDK sharedSDK].loginManager.currentAccount;

SDK 不支持直接添加网易云通信用户,请参考服务端API文档 的 创建网易云通信 ID 章节,在您的应用服务器上使用 Http 接口进行添加。

自动登录

NIM SDK 有两种自动登录的场景:

1.SDK 发起的自动登录:登录完毕后因网络发生切换,断网等情况发生而需要重连,SDK 将自动进行重连重登,无需 APP 干预。

2.APP 发起的自动登录:APP 启动时,如果已保存用户名和密码可以选择调用自动登录接口,并立刻打开主界面。此时 APP 可以在无网络,未登录成功的状态下直接访问用户本地数据。

//APP主动发起自动登录
- (void)autoLogin:(NIMAutoLoginData *)loginData

NIMAutoLoginData 中的 forcedMode 为强制模式开关。非强制模式下的自动登录,服务器将检查当前登录设备是否为上一次登录设备,如果不是,服务器将拒绝这次自动登录(返回 error code 为 417 的错误);强制模式下的自动登录,服务器将不检查当前登录设备是否为上一次登录设备,安全性较低,但较为便捷。

和手动登录不同,自动登录通过委托通知登录状态。 APP 需要实现如下回调 (手动登录也会收到同样的委托回调)

- (void)onLogin:(NIMLoginStep)step

自动登录过程不需要 APP 加以干预,SDK 会在有网络的情况下有策略地不断重试直到登录为止。但下面两种异常情况需要 APP 处理:被踢和特殊的登录错误。

  • 被踢的回调
-(void)onKick:(NIMKickReason)code 
   clientType:(NIMLoginClientType)clientType

APP收到被踢回调后需要进行注销并切换到登录界面。

  • 自动登录失败的回调
- (void)onAutoLoginFailed:(NSError *)error

大部分自动登录回调错误 APP 并不需要关心,只需注意如下几种情况:

1.用户名密码错误导致自动登录失败,error code 为 302。这种情况一般发生于用户在其他设备上修改了密码。

2.已有一端登录导致自动登录失败,error code 为 417。这种情况发生于非强制登录模式下已有一端在线而当前设备进行自动登录(设置为只允许一端同时登录时),出于安全方面的考虑,云信服务器判定当前端需要重新手动输入用户密码进行登录,故拒绝登录。

3.NIMSDKConfig 设置了 maxAutoLoginRetryTimes 属性,即 App 设定当前 SDK 自动登录失败的重试次数,那么在当前会话中如果登录出错超过预定次数,将抛出 code 为 NIMLocalErrorCodeAutoLoginRetryLimit 的本地错误

一旦发生如上情况,APP 同样需要进行额外处理:注销或重试。

登出

调用

[[[NIMSDK sharedSDK] loginManager] logout:^(NSError *error){}];

应用层登出/注销自己的账号时需要调用 SDK 的登出操作,该操作会通知云信服务器进行 APNS 推送信息的解绑操作,避免用户已登出但推送依然发送到当前设备的情况发生。

考虑到用户体验,登出的超时时间会比其他请求短一些。上层应用不管登出请求是否成功,UI 表现上都应该做出登出行为。

多端登录

当用户在某个客户端登录时,其他没有被踢掉的端会触发回调:

- (void)onMultiLoginClientsChanged;

同时,可以查询当前时间登录的设备列表:

- (NSArray<NIMLoginClient *> *)currentLoginClients;

云信内置踢人策略为:移动端(Android,iOS)互踢,桌面端(PC,Web)互踢,移动端和桌面端共存。

如果当前的互踢策略无法满足业务需求的话,可以联系我们取消内置互踢,根据多端登录的回调和当前的设备列表,判断本设备是否需要被踢出。如果需要踢出,直接调用登出接口并在界面上给出相关提示即可。

登录与用户信息同步

NIM SDK 的登录一共有大约十个步骤,包括正在连接,连接成功,正在登录等。详见 NIMLoginStep 枚举。其中重要的两个步骤为:登录成功 (NIMLoginStepLoginOK) 和 同步成功 (NIMLoginStepSyncOK)。

  • 登录成功 SDK 已成功登录,获取到基本信息,并开始同步数据
  • 同步成功 SDK 已同步完成所有 IM 信息

NIM SDK 在登录后会同步群信息,离线消息,漫游消息,系统通知等数据。

基础消息功能

消息功能概述

SDK 中用户与同一个对象的聊天信息集合,称为一个会话,用 NIMSession 来表示。会话有单人会话,群组会话,聊天室会话等类型。

SDK 中用于表示消息的结构为 NIMMessage,目前提供如下几种消息类型,不同的消息类型对应不同的 MessageObject

消息格式 MessageObject
文本消息 nil
图片消息 NIMImageObject
音频消息 NIMAudioObject
视频消息 NIMVideoObject
文件消息 NIMFileObject
地理位置消息 NIMLocationObject
通知消息 NIMNotificationObject
提醒消息 NIMTipObject
自定义消息 NIMCustomObject

消息 NIMMessage 定义了一些额外的状态属性,推荐只在主线程对这些属性进行读写

  • 消息的接收状态 isReceivedMsg

    由于漫游消息的存在,所以自己发出的消息漫游下来后仍旧是 收到的消息 ,这个字段用于消息出错时,判断需要重发还是重收。

  • 消息的排版状态 isOutgoingMsg

    用于鉴别是否为发出去的消息。用户可以选择和自己发起对话,所以并不是所有来源是自己的消息都是往外发的消息,这个字段主要用于判断头像排版位置,往外发的消息气泡放右边,其他消息气泡放左边。

  • 消息的投递状态 deliveryState

    此状态仅对发送的消息有效。消息的投递状态有 发送中 , 发送失败 , 发送成功 三种。

  • 消息附件的下载状态 attachmentDownloadState

    此状态仅对收到的且带有附件的消息有效。 下载状态有 下载失败 , 下载中 , 下载成功 三种。

  • 消息的删除状态 isDeleted

    消息是否标记为已删除,已删除的消息在获取本地消息列表时会被过滤掉,只有根据messageId获取消息的接口可能会返回已删除消息。

  • 消息的播放状态 isPlayed

    用于鉴别音频类的消息是否播放过。 上层应用可以根据业务修改这个属性。注意不要频繁修改这个属性值,每次对这个属性做出修改,就会自动更新一次数据库。

  • 消息服务器扩展字段 remoteExt

    此字段会发送到其他端,上层需要保证 NSDictionary 可以转换为 JSON。

  • 消息本地扩展字段 localExt

    此字段只在本地存储,不会发送至对端,上层需要保证 NSDictionary 可以转换为 JSON。

  • 消息发送方的显示名 senderName

    服务器内置的消息发送者名字,当发送者是自己时,这个值为空。在本地没法获取到相应发送者信息时推荐时使用这个值。

  • 对端已读 isRemoteRead

    接收对端已读回执后,所有小于已读回执时间戳的消息都会被置为 对端已读 。

发送消息

1.构造并发送消息

  • 文本消息
//构造消息
NIMMessage *message = [[NIMMessage alloc] init];
message.text    = text;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 图片消息
//构造消息
NIMImageObject * imageObject = [[NIMImageObject alloc] initWithImage:image];
NIMMessage *message          = [[NIMMessage alloc] init];
message.messageObject        = imageObject;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 音频消息
//构造消息
NIMAudioObject *audioObject = [[NIMAudioObject alloc] initWithSourcePath:filePath];
NIMMessage *message        = [[NIMMessage alloc] init];
message.messageObject      = audioObject;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 视频消息
//构造消息
NIMVideoObject *videoObject = [[NIMVideoObject alloc] initWithSourcePath:filePath];
NIMMessage *message         = [[NIMMessage alloc] init];
message.messageObject       = videoObject;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 地理位置消息
//构造消息
//其中,latitude为纬度,longitude为经度,title为位置的描述字段
NIMLocationObject *locationObject = [[NIMLocationObject alloc] initWithLatitude:latitude Longitude:longitude address:title];
NIMMessage *message               = [[NIMMessage alloc] init];
message.messageObject             = locationObject;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 文件类型消息
//构造消息
//其中,path 为文件保存路径
NIMFileObject *fileObject = [[NIMFileObject alloc] initWithSourcePath:path];
NIMMessage *message       = [[NIMMessage alloc] init];
message.messageObject     = fileObject;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 机器人提问消息

//要在界面上显示的消息
message.text = @"hi @robot, hello robot";

//真正和机器人对话的消息
NSString *content = @"hello robot";

//构造机器人消息附件    
NIMRobotObject *object = [[NIMRobotObject alloc] initWithRobot:content robotId:robotId];
message.messageObject  = object;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 机器人跳转消息

//要在界面上显示的消息
message.text = @"hi @robot, plan A";

//具体跳转的模板 target
NSString *target = @"targetID";

//具体跳转参数
NSString *params = @"params";

//构造机器人消息附件    
NIMRobotObject *object = [[NIMRobotObject alloc] initWithRobotId:robotId target:target param:params];
message.messageObject  = object;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 通知消息

    一些特定场景的行为,云信服务器预置了一些通知消息。通知消息也是一种特定消息,开发者需要解析消息中附带的信息,来获取通知内容,具体步骤为:

    • 解析 NIMMessage 中的 messageObject 字段,强类型转换为 NIMNotificationObject
    • 解析 NIMNotificationObject 中的 content 字段,得到父类 NIMNotificationContent
    • 根据 NIMNotificationContent 中的 notificationType 字段,将父类 NIMNotificationContent 强类型转化成具体子类型。 所有 content 类型如下:
通知类型 NIMNotificationContent
群通知 NIMTeamNotificationContent
网络电话通知 NIMNetCallNotificationContent
聊天室通知 NIMChatroomNotificationContent
未被支持类型通知 NIMUnsupportedNotificationContent

由于系统升级,旧版本的 SDK 可能无法解析新版本数据,所有无法解析的新通知显示为未被支持。

当不需要一些通知时,开发者可以实现 NIMSDKConfig 的委托 delegate,来控制哪些通知需要忽略。

  - (BOOL)shouldIgnoreNotification:(NIMNotificationObject *)notification

当消息将要存储到本地时,会调用此回调,开发者只应该在这个回调里做简单逻辑判断,如果做耗时操作会严重影响存储性能。

不支持从客户端发出通知消息。

  • 提醒消息

    提醒消息用于会话内的状态提醒,如进入会话时出现的欢迎消息,会话命中敏感词后的提示消息等。

//构造消息
NIMTipObject *tipObject = [[NIMTipObject alloc];
NIMMessage *message     = [[NIMMessage alloc] init];
message.messageObject   = tipObject;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
  • 自定义消息

自定义消息用于 APP 拓展自己的消息类型,实现不同业务逻辑。自定义消息的 MessageObject(NIMCustomObject) 仅有一个 id 字段,SDK 会负责透传这个对象序列化后的结果。NIMCustomAttachment 协议包括一个必须实现的序列化接口和三个与上传相关的可选接口。如果需要在自定义消息中上传文件作为附件的一部分,必须实现这三个上传接口,缺一不可。实现自定义消息参考教程

//构造消息
NIMCustomObject *customObject     = [[NIMCustomObject alloc] init]; 
customObject.attachment           = attachment;
NIMMessage *message               = [[NIMMessage alloc] init];
message.messageObject             = customObject;

//构造会话
NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];

//发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];

2.检查调用状态

正常情况这一步可以省略,但刚开始集成 SDK 时,因为上层开发对 API 不熟悉有可能传入一些无效参数,推荐在开发前期务必检查 sendMessage:toSession:error 的返回值和 error 信息,并以此为依据排查问题。

3.处理回调

在调用完发送消息接口后,通常会收到如下回调

  • 即将发送消息回调
- (void)willSendMessage:(NIMMessage *)message

建议开发者仅在收到这个回调后才将消息加入显示用的数据源中。

  • 消息发送进度回调
- (void)sendMessage:(NIMMessage *)message
           progress:(CGFloat)progress

图片,视频等需要上传附件的消息会有比较详细的进度回调,文本消息则没有这个回调。

  • 消息发送完毕回调
- (void)sendMessage:(NIMMessage *)message
didCompleteWithError:(NSError *)error

如果消息发送成功 error 为 nil,反之 error 会被填充具体的失败原因。

4.重发

因为网络原因等导致的发送消息失败而需要重发的情况,直接调用

- (BOOL)resendMessage:(NIMMessage *)message
                error:(NSError **)error

此时如果再次调用 sendMessage,则会被 NIM SDK 认作新消息。

5.消息的发送设置

SDK 提供消息发送设置来满足开发者的对服务器自定义需求,这些设置可以在 NIMMessage 的 NIMMessageSetting 属性中找到。

  • 消息允许在消息历史中拉取开关 historyEnabled

    默认为 YES 。正常而言所有消息都会出现在通过 NIMConversationManager 调用( fetchMessageHistory:option:result: )返回的结果中,但是可以通过设置这个值来使得消息不出现在这其中。

  • 消息支持漫游开关 roamingEnabled

    默认为 YES 。 消息漫游的概念是指一定时间内发送的消息可以在另一端被同步到,以保证最大限度的消息同步。(如 iOS 上收发的消息过了一天登录 PC 仍旧会收到,这种消息我们称之为漫游消息)

  • 消息支持多端同步开关 syncEnabled

    默认为 YES 。在默认情况下,如果用户在 iOS 端和其他端(如 PC )同时登录一个帐号,那么 iOS 端发送的消息会被同步到其他端,同样其他端发送的消息也会被同步到 iOS 端。但是需要注意的是因为 iOS 经常会退到后台,所以其他端发送的消息在 iOS 断线后是通过漫游消息来同步到的。

  • 消息被计入未读开关 shouldBeCounted

    默认为 YES 。默认情况下,用户收到的所有消息都会被计入未读。设置这个为 NO 后,对应的消息被对端接受后将不计入未读消息计数内。本地写消息时,也可以用这个字段配置写入后是否计入未读。

  • 消息需要被推送开关 apnsEnabled

    默认为YES。设置这个为NO后,消息将不再有苹果推送通知。

  • 消息推送前缀开关(一般为昵称) apnsWithPrefix

    默认为YES。将这个字段设为NO,推送消息将不带有前缀,如推送消息 “ 小明:今天吃什么? ” 中的 “ 小明:” 将被省略。

  • 消息是否需要抄送 routeEnabled

    默认为YES。将这个字段设为NO, 则不会抄送此消息给开发者的服务器(如果有配置的话)

接收消息

  • 回调处理 收消息过程会通过 chatManager 的回调函数通知上层
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages

如果收到的是图片,视频等需要下载附件的消息,在回调的处理中还需要调用

(SDK 默认会在第一次收到消息时自动调用)

- (BOOL)fetchMessageAttachment:(NIMMessage *)message
                         error:(NSError **)error

进行附件的下载,附件的下载过程会通过

- (void)fetchMessageAttachment:(NIMMessage *)message
                      progress:(CGFloat)progress
- (void)fetchMessageAttachment:(NIMMessage *)message
          didCompleteWithError:(NSError *)error;

这两个回调返回进度和结果。

消息转发

除了 通知消息 之外,其他类型消息均支持转发给其他会话。

- (BOOL)forwardMessage:(NIMMessage *)message
             toSession:(NIMSession *)session
                 error:(NSError **)error

这里返回的 error 参数只是表示当前这个函数调用是否成功,需要后续的回调才能够判断消息是否已经发送至服务器。后续回调和普通消息发送流程相同。

已读回执

在会话界面中调用发送已读回执的接口并传入最后一条消息,即表示这之前的消息都已读,对端将收到此回执。

发送已读回执

- (void)sendMessageReceipt:(NIMMessageReceipt *)receipt
                completion:(NIMSendMessageReceiptBlock)completion;

接受已读回执

- (void)onRecvMessageReceipt:(NIMMessageReceipt *)receipt;

在发送端 NIMMessageReceipt 需要通过最后一条消息 NIMMessage 进行初始化并进行发送,而接收端可以通过 NIMMessageReceipt 中的 timestamp 来得知发送端当前已读时间戳。此功能仅在 P2P 消息中有效。重复发送和通过无效消息构造的已读回执都将被 SDK 忽略。

消息撤回

在会话时,允许用户撤回一定时间内发送过的消息。

- (void)revokeMessage:(NIMMessage *)message
           completion:(NIMRevokeMessageBlock)completion;

在撤回消息请求调用成功后, SDK 会先回调给上层成功,再自动将本地的这条消息删除。如果需要在撤回后显示一条已撤回的提示 ( 见 Demo 交互 ) ,开发者可以自行构造一条提醒消息并插入本地数据库。

以下情况消息撤回会失败

  • 消息并没有投递到对端
  • 消息超过撤回时限

当有消息撤回发生时,被撤回方 SDK 会触发回调:

- (void)onRecvRevokeMessageNotification:(NIMRevokeMessageNotification *)notification

SDK 在收到消息撤回后,会先从本地数据库中找到对应消息并进行删除,之后通知上层消息已删除。如果需要在撤回后显示一条已撤回的提示 ( 见 Demo 交互 ) ,开发者在这个回调中自行构造一条提醒消息并插入本地数据库。

由于用户业务场景不一致,在撤回后可能在撤回后用一条提醒消息替代,也有可能不做任何提示,而被撤回的消息本身可能是未读的,这样不同的业务逻辑就造成了未读数的不一致。 在 NIMSDKConfig.h 中统一封装了撤回未读配置 接口:

@property (nonatomic,assign) BOOL shouldConsiderRevokedMessageUnreadCount;

默认为 NO。设置成 YES 的情况下,如果被撤回的消息本地还未读,那么当消息发生撤回时,对应会话的未读计数将减 1 以保持最近会话未读数的一致性。 当不做任何提示时,可以设置为 YES,以保持未读计数的一致性。

最近会话

NIMConversationManager 提供最近消息的本地存储管理功能。

最近会话 NIMRecentSession 用于表示会话列表页的数据模型。当用户发送,收取及删除消息时,都会同时去修改最近会话。

当收到或者一条消息时,会自动生成这个消息对应的最近会话。但值得注意的是最近会话和会话并不是一一对应的关系,删除最近会话并不会影响会话。

  • 获取最近会话,一般用于首页显示会话列表
- (NSArray<NIMRecentSession *> *)allRecentSessions
  • 最近会话的通知

NIMConversationManager 提供了最近会话的三个回调通知上层:

分别为增加,修改,删除最近会话的回调:

- (void)didAddRecentSession:(NIMRecentSession *)recentSession
           totalUnreadCount:(NSInteger)totalUnreadCount

- (void)didUpdateRecentSession:(NIMRecentSession *)recentSession
              totalUnreadCount:(NSInteger)totalUnreadCount

- (void)didRemoveRecentSession:(NIMRecentSession *)recentSession
              totalUnreadCount:(NSInteger)totalUnreadCount
  • 最近消息添加

开发者无法自己添加最近消息,最近消息会在发送或者收到消息的时候自动添加,并触发增加最近会话的回调。

  • 消息/会话的删除

单条消息的删除

- (void)deleteMessage:(NIMMessage *)message;

调用此方法时,如果删除的是最后一条消息,消息所属的最近会话的 lastMessage 属性会自动变成上一条消息(没有则为空消息),同时触发最近消息修改的回调。

单个会话批量消息删除

- (void)deleteAllmessagesInSession:(NIMSession *)session
               removeRecentSession:(BOOL)removeRecentSession

removeRecentSession 标记了最近会话是否会被保留,会话内消息将会标记为已删除。调用此方法会触发最近消息修改的回调,如果选择保留最近会话, lastMessage 属性将会被置成一条空消息。

  • 最近会话的删除
- (void)deleteRecentSession:(NIMRecentSession *)recentSession

只会删除最近会话,但保留会话内消息。调用时,总未读消息数会减去当前会话的未读数。调用此方法触发最近消息删除的回调。

  • 清空所有会话的消息
- (void)deleteAllMessages:(BOOL)removeRecentSessions

removeRecentSession 标记了最近会话是否会被保留。调用这个接口只会触发 - (void)allMessagesDeleted 回调,其他针对单个 recentSession 的回调都不会被调用。

  • 总未读数获取
- (NSInteger)allUnreadCount
  • 标记某个会话为已读
- (void)markAllMessagesReadInSession:(NIMSession *)session

调用这个方法时,会将所有属于这个会话的消息都置为已读状态。相应的最近会话(如果有的话)未读数会自动置 0 并且触发最近消息修改的回调

  • 最近会话的本地扩展

最近会话提供本地扩展能力,可以用来开发 @ 以及 置顶 等功能。

开发者可以通过 RecentSession 的 localExt 接口读取扩展。

并通过调用 NIMConversationManager 修改本地扩展信息

- (void)updateRecentLocalExt:(NSDictionary *)ext
               recentSession:(NIMRecentSession *)recentSession

历史记录

云端记录

NIMConversationManager 支持从云信服务器上远程获取之前的聊天历史记录。

- (void)fetchMessageHistory:(NIMSession *)session
                     option:(NIMHistoryMessageSearchOption *)option
                     result:(NIMFetchMessageHistoryBlock)block;

其中 option 为搜索选项,具体选项如下:

  • 搜索方向: 从当前消息开始,正向或反向查询消息历史。此参数对聊天室会话无效
  • 搜索条数: 搜索的范围由 startTime ,endTime 和 limit 参数共同限制,limit 为非零整数,上限为 100 条。
  • 同步数据: 是否在远程获取消息成功之后同步到本地数据库,同步只会保证消息数据写入本地但不触发回调。默认不同步。

本地记录

  • NIMConversationManager 支持本地查询消息

     - (NSArray<NIMMessage *> *)messagesInSession:(NIMSession *)session
                                          message:(NIMMessage *)message
                                            limit:(NSInteger)limit;

    传入一个已知的消息,返回比这个消息更早的消息集合。如果没有已知的消息,则传入 nil,返回最新的消息集合。

  • NIMConversationManager 支持按消息 id 查询消息,可以查出被删除的消息。

     - (NSArray<NIMMessage *> *)messagesInSession:(NIMSession *)session 
                                       messageIds:(NSArray<NSString *> *)messageIds;
  • NIMConversationManager 支持根据会话搜索本地历史消息

     - (void)searchMessages:(NIMSession *)session
                     option:(NIMMessageSearchOption *)option
                     result:(NIMSearchMessageBlock)block;

    以及搜索本地全局历史消息

     - (void)searchAllMessages:(NIMMessageSearchOption *)option
                    result:(NIMGlobalSearchMessageBlock)result

    其中 option 为搜索选项,具体选项如下:

    • 搜索方向: 正向或反向查询消息历史。

    • 搜索条数: 搜索的范围由 startTime , endTime 和 limit 参数共同限制。limit 为非零整数。

    • 消息类型: 需要搜索的消息类型。

    • 匹配内容: 如果需要搜索的消息类型为文本,会进行内容的匹配。

    • 是否是全消息类型:默认为 NO,当设置为 YES 时,忽略 messageType 和 searchContent,同时返回所有的消息类型消息。

    • 消息发起者列表。

    搜索将返回:时间在 (startTime,endTime) 之间,消息类型为指定类型,且匹配搜索内容或消息发起者列表的一定数量的消息。

语音录制及播放

多媒体管理 NIMMediaManager 提供了音频播放、高清语音录制的功能。需要注意的是 NIM SDK 中的语音播放和录制仅支持 aac 和 amr,如果需要更多格式的支持,APP 需要自己实现,但并不推荐。

播放音频

  • 切换音频的输出设备。
- (BOOL)switchAudioOutputDevice:(NIMAudioOutputDevice)outputDevice
  • 判断是否正在播放音频
- (BOOL)isPlaying
  • 播放音频
- (void)play:(NSString *)filepath;

其中 filePath 为音频文件的路径,该操作会触发以下回调:

初始化工作完成,准备开始播放音频的时候会触发

- (void)playAudio:(NSString *)filePath didBeganWithError:(NSError *)error

音频播放结束的时候会触发

- (void)playAudio:(NSString *)filePath didCompletedWithError:(NSError *)error
  • 停止播放音频
- (void)stopPlay

该操作会触发回调:

- (void)playAudio:(NSString *)filePath didCompletedWithError:(NSError *)error

录制音频

  • 判断是否正在录制音频
- (BOOL)isRecording
  • 录制音频
- (void)recordForDuration:(NSTimeInterval)duration;

其中 duration 限制了录音的最大时长,该操作会触发以下回调:

初始化工作完成,准备开始录制的时候会触发

- (void)recordAudio:(NSString *)filePath didBeganWithError:(NSError *)error

当到录音时长达到设置的最大时长,或者手动停止录音会触发

- (void)recordAudio:(NSString *)filePath didCompletedWithError:(NSError *)error

按照一定的时间间隔触发

- (void)recordAudioProgress:(NSTimeInterval)currentTime

其中 currentTime 为当前的录音时长,触发该回调的时间间隔可以通过以下属性设置,默认为 0.3 秒

@property (nonatomic, assign) NSTimeInterval recordProgressUpdateTimeInterval

  • 停止录制音频
- (void)stopRecord

该操作会触发

- (void)recordAudio:(NSString *)filePath didCompletedWithError:(NSError *)error
  • 取消录音
- (void)cancelRecord

该操作会触发

- (void)recordAudioDidCancelled
  • 获取录音分贝

获取峰值

- (float)recordPeakPower

获取平均值

- (float)recordAveragePower

来电打断

  • 来电时会根据正在播放音频还是录音,分别触发
- (void)playAudioInterruptionBegin

- (void)recordAudioInterruptionBegin
  • 通话结束返回应用会分别触发
- (void)playAudioInterruptionEnd

- (void)recordAudioInterruptionEnd

群组功能

群组功能概述

群组功能对应的管理类为 NIMTeamManager 。NIMTeamManager 提供了普通群 (Normal) 以及高级群 (Advanced) 两种形式的群聊功能。高级群拥有更多的权限操作,两种群聊形式在共有操作上保持了接口一致。推荐 APP 开发时只选择一种群类型进行开发。普通群和高级群在原则上是不能互相转换的,他们的群类型在创建时就已经确定。在 SDK 2.4.0 版本后,高级群可以拥有普通群的全部功能,推荐使用高级群进行开发。

  • 普通群

开发手册中所提及的普通群都等同于 Demo 中的讨论组。普通群没有权限操作,适用于快速创建多人会话的场景。每个普通群只有一个管理员。管理员可以对群进行增减员操作,普通成员只能对群进行增员操作。在添加新成员的时候,并不需要经过对方同意。

  • 高级群

高级群在权限上有更多的限制,权限分为群主、管理员、以及群成员。

获取群组

NIM SDK 在程序启动时会对本地群信息进行同步,所以只需要调用本地缓存接口获取群就可以了。 SDK 提供了批量获取自己的群接口、以及根据单个群 id 查询的接口。同样 SDK 也提供了远程获取群信息的接口。

本地获取

- (NSArray<NIMTeam *> *)allMyTeams
- (NIMTeam *)teamById:(NSString *)teamId

远程获取

- (void)fetchTeamInfo:(NSString *)teamId
           completion:(NIMTeamFetchInfoHandler)block;

创建群组

- (void)createTeam:(NIMCreateTeamOption *)option
             users:(NSArray<NSString *> *)users
        completion:(NIMTeamCreateHandler)completion
  • option 提供以下创建群选项

  • 创建群类别,普通群或者高级群

  • 群名称

  • 群头像

  • 群介绍

  • 群公告

  • 群验证方式

  • 邀请群成员

  • 邀请附言

  • 被邀请人验证方式

  • 谁可以邀请其他人入群 (默认群主管理员)

  • 谁可以修改群资料 (默认群主管理员)

  • 谁可以修改群自定义属性(默认群主管理员)

加入群组

用户可以通过被动接受邀请和主动加入两种方式进入群组。

邀请用户入群

- (void)addUsers:(NSArray<NSString *>  *)users
          toTeam:(NSString *)teamId
      postscript:(NSString *)postscript
      completion:(NIMTeamMemberHandler)completion

请求完成后,如果是普通群,被邀请者将直接入群;如果是高级群,云信服务器会下发一条系统消息到目标用户,目标用户可以选择同意或者拒绝入群。

同意群邀请(仅限高级群)

- (void)acceptInviteWithTeam:(NSString*)teamId
                   invitorId:(NSString*)invitorId
                  completion:(NIMTeamHandler)block

拒绝群邀请(仅限高级群)

- (void)rejectInviteWithTeam:(NSString*)teamId
                   invitorId:(NSString*)invitorId
                rejectReason:(NSString*)rejectReason
                  completion:(NIMTeamHandler)block

主动申请入群(仅限高级群)

- (void)applyToTeam:(NSString *)teamId
            message:(NSString *)message
         completion:(NIMTeamApplyHandler)block

请求完成后,云信服务器会下发一条系统消息给群管理员,管理员可以选择通过或者拒绝申请。

通过申请(仅限高级群)

- (void)passApplyToTeam:(NSString *)teamId
                 userId:(NSString *)userId
             completion:(NIMTeamApplyHandler)block

拒绝申请(仅限高级群)

- (void)rejectApplyToTeam:(NSString *)teamId
                   userId:(NSString *)userId
             rejectReason:(NSString *)rejectReason
               completion:(NIMTeamHandler)block

编辑群组资料

普通成员可以修改自己的群资料,管理员以上权限的群成员可以修改他人群资料以及群组信息。包括:

修改群成员昵称

- (void)updateUserNick:(NSString *)userId
               newNick:(NSString *)newNick
                inTeam:(NSString *)teamId
            completion:(NIMTeamHandler)block

修改群名称

- (void)updateTeamName:(NSString *)teamName
                teamId:(NSString *)teamId
            completion:(NIMTeamHandler)block

修改群头像

- (void)updateTeamAvatar:(NSString *)teamAvatarUrl
                  teamId:(NSString *)teamId
              completion:(NIMTeamHandler) block

修改群介绍

- (void)updateTeamIntro:(NSString *)intro
                 teamId:(NSString *)teamId
             completion:(NIMTeamHandler)block

修改群公告

- (void)updateTeamAnnouncement:(NSString *)announcement
                        teamId:(NSString *)teamId
                    completion:(NIMTeamHandler)block

修改群验证方式

- (void)updateTeamJoinMode:(NIMTeamJoinMode)joinMode
                    teamId:(NSString *)teamId
                completion:(NIMTeamHandler)block

修改被邀请人验证方式

- (void)updateTeamBeInviteMode:(NIMTeamBeInviteMode)beInviteMode
                        teamId:(NSString *)teamId
                    completion:(NIMTeamHandler)block;

修改谁可以邀请其他人入群

- (void)updateTeamInviteMode:(NIMTeamInviteMode)inviteMode
                      teamId:(NSString *)teamId
                  completion:(NIMTeamHandler)block

修改谁可以修改群资料

- (void)updateTeamUpdateInfoMode:(NIMTeamUpdateInfoMode)updateInfoMode
                          teamId:(NSString *)teamId
                      completion:(NIMTeamHandler)block

修改谁可以修改群自定义属性

- (void)updateTeamUpdateClientCustomMode:(NIMTeamUpdateClientCustomMode)clientCustomMode
                                  teamId:(NSString *)teamId
                              completion:(NIMTeamHandler)block

管理群组权限

高级群群主可以对群进行权限管理,权限管理包括:

提升管理员

- (void)addManagersToTeam:(NSString *)teamId
                    users:(NSArray<NSString *>  *)users
               completion:(NIMTeamHandler)completion

移除管理员

- (void)removeManagersFromTeam:(NSString *)teamId
                         users:(NSArray<NSString *>  *)users
                    completion:(NIMTeamHandler)completion

转让群

- (void)transferManagerWithTeam:(NSString *)teamId
                     newOwnerId:(NSString *)newOwnerId
                        isLeave:(BOOL)isLeave
                     completion:(NIMTeamHandler)block

群组成员

获取群成员

- (void)fetchTeamMembers:(NSString *)teamId
              completion:(NIMTeamMemberHandler)block

获取到的群成员只有云信服务器托管的群相关数据,需要开发者结合自己管理的用户数据进行界面显示。

修改自己的群成员自定义属性

- (void)updateMyCustomInfo:(NSString *)newInfo
                    inTeam:(NSString *)teamId
                completion:(NIMTeamHandler)block

修改后,其他在线用户自动同步获得修改后的属性。

用户退群

- (void)quitTeam:(NSString *)teamId
      completion:(NIMTeamHandler)block

用户退群成功后,相关会话信息仍然会保留,但不再能接收关于此群的消息。

禁言用户

- (void)updateMuteState:(BOOL)mute
                 userId:(NSString *)userId
                 inTeam:(NSString *)teamId
             completion:(NIMTeamHandler)block

禁言用户后,云信服务器会下发一条提示该用户被禁言的群组通知消息。

踢出用户

- (void)kickUsers:(NSArray<NSString *> *)users
         fromTeam:(NSString *)teamId
       completion:(NIMTeamHandler)completion

被踢出的用户相关会话信息仍然会保留,但不再能接收关于此群的消息。

解散群

- (void)dismissTeam:(NSString*)teamId
         completion:(NIMTeamHandler)block

群解散后,所有群用户关于此群会话会被保留,但是不能能够在此群会话里收发消息。

群组委托

用户的群信息会在以下条件下更新:

  • 修改群组名称
  • 更改群验证方式
  • 更改群介绍
  • 更改群公告

这些操作成功后,云信服务器会推送一条群通知,同时触发 SDK 更新群信息的委托事件:

- (void)onTeamUpdated:(NIMTeam *)team

用户的群信息会在以下条件下移除:

  • 群解散
  • 退群
  • 被踢出群

这些操作成功后,云信服务器同样会推送一条群通知,同时触发 SDK 更新群信息的委托事件:

- (void)onTeamRemoved:(NIMTeam *)team

用户的群成员信息会在以下条件下更新

  • 群成员数量变动
  • 静音群组
  • 群成员信息变动,包括权限,群昵称等

这些操作成功后,云信服务器同样会推送一条群通知,同时触发 SDK 更新群信息的委托事件:

- (void)onTeamMemberChanged:(NIMTeam *)team;

群组通知

群组通知是一种消息类型 ( NIMMessageTypeNotification ) ,用户在创建群或者进入群成功之后,任何关于群的变动,云信服务器都会下发一条群通知消息。群通知消息和其他消息一样,可从 NIMConversationManager 提供的消息查询接口中获取。

  • 群组通知解析步骤:

    • 解析 NIMMessage 中的 messageObject 字段,强类型转换为 NIMNotificationObject
    • 解析 NIMNotificationObject 中的 content 字段,得到父类 NIMNotificationContent
    • 根据 NIMNotificationContent 中的 notificationType 字段,将父类 NIMNotificationContent 强类型转化为 NIMTeamNotificationContent
  • 群组通知的具体类型可以通过 NIMTeamNotificationContent 的 operationType 解析。

  • SDK 在收到群通知之后,会对本地缓存的群信息做出对应的修改,然后触发与修改相对应的委托事件回调。

  • 群通知是接收型的消息,开发者不应该自己手动去创建和发送群通知消息。

群组通知内容 NIMTeamNotificationContent 的字段说明:

  • operationType : 群组通知事件类型,表示具体属于哪一种群组通知,通知种类由 NIMTeamOperationType枚举定义。
  • source : 通知的操作者 ID ,表示谁触发了这个通知。
  • targets : 通知的被操作者 ID 列表,表示这个通知影响的用户群体。
  • notifyExt : 通知的扩展字段,这个扩展字段是由每个触发通知的操作接口定义的。目前只能由服务器的操作接口去定义这个字段。

    例如:

     群组踢出用户,可以调用服务器 HTTP 接口,并传入通知扩展参数。调用后会触发用户被踢出群组的事件消息通知,此时,收到消息的其他群成员就可以通过读取 `NIMTeamNotificationContent` `notifyExt` 字段来获取踢出时定义的扩展字段。
  • attachment : 有些通知比较复杂,需要一些额外信息来辅助上层显示,目前有额外信息的群通知类型为:

    • 群更新通知,额外信息被封装为 NIMUpdateTeamInfoAttachment 类型。
    • 群禁言通知,额外信息被封装为 NIMMuteTeamMemberAttachment 类型。

群消息推送设置

SDK 提供了修改群消息通知的接口,上层可以通过设置这个选项以影响群消息的通知行为。当设置 notify 为 NO 时,群内消息将不会有 APNS 通知。当然上层也可以使用这一属性来决定收到在线消息时的 APP 表现 (是否响铃等)。

- (void)updateNotifyState:(BOOL)notify
                   inTeam:(NSString *)teamId
               completion:(NIMTeamHandler)block;

群禁言

群组允许管理员将部分成员禁言,或者全体禁言。禁言属于高级功能,需要调用云信服务器接口,客户端 SDK 仅提供查询功能。

  • 查询禁言用户列表

    - (void)fetchTeamMutedMembers:(NSString *)teamId
                       completion:(nullable NIMTeamMemberHandler)completion;

    绝大多数情况这个请求都是从本地读取缓存并同步返回,但是由于群成员信息量较大, SDK 采取的是登录后延迟拉取的策略。

    考虑到用户网络等问题, SDK 有可能没有及时缓存群成员信息,那么这个请求将是个带网络请求的异步操作(增量请求)。

    同时这个接口会去请求本地没有缓存的群用户的资料信息,但不会触发 - (void)onUserInfoChanged: 回调。

    如果群处于全体禁言状态,则禁言用户列表无效。

    • 查询群的全体禁言状态

      此状态定义在 NIMTeam 中,使用接口查询

      - (BOOL)inAllMuteMode;
    • 群禁言通知

      通知的解析方式请参考之前小节 群组通知 。

      • 单体禁言

        单体禁言属于群内用户属性发生变更,SDK 单独定义了一个通知的操作类型 NIMTeamOperationTypeMute。获得通知后判断通知 NIMTeamNotificationContent 的 operationType 是否为这个操作类型即可。

      • 群全体禁言

        群全体禁言属于群本身的属性发生变更, SDK 将这个变更定义在了群信息的更新通知里。取得 NIMTeamNotificationContent 的 attachment 字段,判断 NIMTeamUpdateTag 是否为 NIMTeamUpdateTagMuteMode 即可。

自定义拓展

SDK 提供了群信息的拓展接口,开发者可以自行定义内容。

- (void)updateTeamCustomInfo:(NSString *)info
                      teamId:(NSString *)teamId
                  completion:(NIMTeamHandler)block

开发者可以通过 NIMTeam 的两个属性读取拓展信息:

  • 应用方可以自行拓展这个字段做个性化配置,客户端不可以修改这个字段

    @property (nonatomic,copy,readonly)  NSString *serverCustomInfo;
  • 应用方可以自行拓展这个字段做个性化配置,客户端可以修改这个字段

     @property (nonatomic,copy,readonly)  NSString *clientCustomInfo;

聊天室

在集成聊天室之前,推荐开发者首先阅读这里

聊天室功能概述

聊天室功能对应的管理类为 NIMChatroomManager 。 NIMChatroomManager 提供了聊天室的业务管理,如进入/退出聊天室,获取相关信息以及权限操作等。目前不支持通过 SDK 接口建立/解散聊天室。

聊天室模型特点:

  • 进入聊天室时将建立新的连接,退出聊天室或者被踢会断开连接,在聊天室中掉线会有自动重连,开发者需要监听聊天室连接状态来做出正确的界面表现。
  • 支持聊天人数无上限。
  • 聊天室只允许用户手动进入,无法进行邀请。
  • 支持同时进入多个聊天室,会建立多个连接。
  • 不支持多端进入同一个聊天室,后进入的客户端会将前一个踢掉。
  • 断开聊天室连接后,服务器不会再推送该聊天室的消息给此用户。
  • 聊天室成员分固定成员和非固定成员两种类型。

进入聊天室

用户要在聊天室内说话,必须先调用接口进入此聊天室。用户进入聊天室后,不会收到此聊天室的历史消息推送。如有历史消息需求,可以调用消息查询接口进行显示。

- (void)enterChatroom:(NIMChatroomEnterRequest *)request
           completion:(NIMChatroomEnterHandler)completion;

NIMChatroomEnterRequest 中包含了聊天室的基本数据信息,包括需要进入的聊天室 id 和一些供用户自定义的扩展字段,后续当前用户的所有聊天室消息都会带上登录时设置的扩展字段。

扩展包括:

  • 每次消息中都会带上的扩展 roomExt,这个字段可以放入用户在聊天室的自定义信息,如权限,头衔等等。这个扩展会放入每条消息的 messageExt (需要转换成 NIMMessageChatroomExtension ) 字段的 roomExt 里。
  • 只有在进入聊天室时的通知消息里,会带上的扩展 roomNotifyExt,这个扩展会放入聊天室通知消息 content(需要转换成 NIMChatroomNotificationContent ) 字段的 notifyExt 里。

进入聊天室会建立新的连接,不同的聊天室对应着不同的连接,开发者可以监听连接状态做一些业务处理。

- (void)chatroom:(NSString *)roomId connectionStateChanged:(NIMChatroomConnectionState)state;

当进入聊天室后,再发生掉线问题时,SDK 将自动重连,无需开发者再次调用进入房间接口。

在重连时,可能遇到一些特殊网络错误(如聊天室用户被封禁,聊天室状态异常),会触发以下回调,开发者应该在这个回调中退出聊天室界面。

- (void)chatroom:(NSString *)roomId autoLoginFailed:(NSError *)error;

离开聊天室

离开聊天室时,会断开聊天室对应的连接,并不再收到关于此聊天室的任何消息。

- (void)exitChatroom:(NSString *)roomId
          completion:(NIMChatroomHandler)completion;

当用户被踢或者聊天室关闭时,会触发被踢回调,这个时候也会断开聊天室对应的连接:

- (void)chatroom:(NSString *)roomId beKicked:(NIMChatroomKickReason)reason;

聊天室消息收发

聊天室消息收发接口与普通消息收发统一,在发送消息时指定会话类型为聊天室即可。会话 id 即为聊天室 id。

查询聊天室消息历史

进入聊天室时,不会下发关于聊天室的历史消息,可以通过下面的接口查询聊天室消息历史。

- (void)fetchMessageHistory:(NSString *)roomId
                     option:(NIMHistoryMessageSearchOption *)option
                     result:(NIMFetchChatroomHistoryBlock)completion;

获取聊天室信息

此接口可以远程获取聊天室信息,NIM SDK 不会缓存聊天室信息,开发者需要根据业务自己做好缓存。

- (void)fetchChatroomInfo:(NSString *)roomId
               completion:(NIMChatroomInfoHandler)completion;

修改聊天室信息

此接口可以修改聊天室信息,调用完这个接口后,开发者应该自己修改内存缓存的 NIMChatroom 对象。

此接口需要生成 NIMChatroomUpdateRequest 对象来完成请求。

NIMChatroomUpdateRequest中的 needNotify 参数可以设置成功修改信息后云信服务器是否推送一条修改的聊天室消息通知。

NIMChatroomUpdateRequest中的 notifyExt 参数可以设置推送的聊天室消息通知里带的自定义扩展字段。

- (void)updateChatroomInfo:(NIMChatroomUpdateRequest *)request
                completion:(nullable NIMChatroomHandler)completion;

获取聊天室成员

此接口可以远程获取聊天室成员列表,NIM SDK 不会缓存聊天室成员列表,开发者需要根据业务自己做好缓存。 NIM SDK 提供两种方式获取聊天室成员:

  • 按锚点分页获取

      - (void)fetchChatroomMembers:(NIMChatroomMemberRequest *)request
                        completion:(NIMChatroomMembersHandler)completion;
  • 按用户 id 获取聊天室成员信息

     - (void)fetchChatroomMembersByIds:(NIMChatroomMembersByIdsRequest *)request
                         completion:(NIMChatroomMembersHandler)completion;

修改自己的聊天室成员信息

此接口可以修改聊天室成员信息,调用完这个接口后,开发者应该自己修改内存缓存的 NIMChatroomMember 对象。

此接口需要生成 NIMChatroomMemberInfoUpdateRequest 对象来完成请求。

NIMChatroomMemberInfoUpdateRequest中的 needNotify 参数可以设置成功修改信息后云信服务器是否推送一条修改的聊天室消息通知。

NIMChatroomMemberInfoUpdateRequest中的 notifyExt 参数可以设置推送的聊天室消息通知里带的自定义扩展字段。

- (void)updateMyChatroomMemberInfo:(NIMChatroomMemberInfoUpdateRequest *)request
                        completion:(nullable NIMChatroomHandler)completion;

聊天室权限管理

聊天室可以调整成员的类型,分固定成员和非固定成员两种,固定成员又分为创建者、管理员、普通成员和受限成员四种。禁言用户和拉黑用户都属于受限用户。

  • 设置为管理员

    - (void)markMemberManager:(NIMChatroomMemberUpdateRequest *)request
                 completion:(NIMChatroomHandler)completion;
  • 设置为普通成员

    - (void)markNormalMember:(NIMChatroomMemberUpdateRequest *)request
                completion:(NIMChatroomHandler)completion;
  • 设置为拉黑用户 拉黑的用户被移出黑名单后该成员变成非固定成员。

    - (void)updateMemberBlack:(NIMChatroomMemberUpdateRequest *)request
                 completion:(NIMChatroomHandler)completion;
  • 设置为禁言用户

    - (void)updateMemberMute:(NIMChatroomMemberUpdateRequest *)request
                completion:(NIMChatroomHandler)completion;

踢出成员

创建者或管理员可以将权限比自己低的用户踢出聊天室

- (void)kickMember:(NIMChatroomMemberKickRequest *)request
        completion:(NIMChatroomHandler)completion;

聊天室通知消息

在聊天室中所有的通知都以消息 NIMMessage 的形式展示,内部 messageObject 为 NIMNotificationTypeChatroom 类型的 NIMNotificationObject。上层开发在收到具体消息需要进行过滤和显示。目前支持的聊天室消息事件定义在 NIMChatroomEventType 枚举里,具体有:

  • 聊天室成员进入聊天室
  • 聊天室成员离开聊天室
  • 聊天室成员被拉黑/取消拉黑
  • 成员被设置禁言/取消禁言
  • 成员被设置临时禁言/取消临时禁言
  • 设置/移除管理员
  • 设置/移除固定成员
  • 聊天室被关闭
  • 聊天室信息被更新
  • 聊天室成员被踢
  • 聊天室成员主动更新了聊天室的角色信息
  • 聊天室通用队列变更
  • 聊天室全体禁言/非禁言状态变更

解析聊天室通知消息的详细步骤:

  1. 判断消息是否为通知消息

    • 判断 NIMMessage 的 messageType 字段是否为 NIMMessageTypeNotification 。
  2. 判断通知消息是否为聊天室通知

    • 将 NIMMessage 的 messageObject 字段强类型转换为 NIMNotificationObject 。
    • 判断转换后的 NIMNotificationObject 中 notificationType 字段是否为 NIMNotificationTypeChatroom 。
  3. 解析聊天室通知的具体内容

    • 将 NIMNotificationObject 中 content 字段强类型转换为 NIMChatroomNotificationContent 。
    • 查看转换后 NIMChatroomNotificationContent 的具体字段。

聊天室通知内容 NIMChatroomNotificationContent 的字段说明:

  • eventType : 聊天室通知事件类型,表示具体属于哪一种聊天室通知,通知种类由 NIMChatroomEventType 枚举定义。
  • source : 通知的操作者,表示谁触发了这个通知,被封装为NIMChatroomNotificationMember 类型。
  • targets : 通知的被操作者,表示这个通知影响的用户,被封装为 NSArray 类型, NSArray 中每个元素被封装成 NIMChatroomNotificationMember 类型。
  • notifyExt : 通知的扩展字段,这个扩展字段是由每个触发通知的操作接口定义的。例如:

    用户通过调用接口进入聊天室

        - (void)enterChatroom:(NIMChatroomEnterRequest *)request completion:(nullable NIMChatroomEnterHandler)completion;

    在这个请求中,请求对象 NIMChatroomEnterRequest 里可以定义一个通知扩展字段 roomNotifyExt。 定义后当用户进入聊天室,会触发用户进入聊天室的事件消息通知,此时,收到消息的其他聊天室成员就可以通过读取 NIMChatroomNotificationContent 的 notifyExt 字段来获取进入的用户定义的 roomNotifyExt字段。

  • ext : 目前只有 NIMChatroomEventTypeAddMuteTemp 事件才有拓展信息,拓展信息为 NSNumber ,表示临时禁言时长。

聊天室禁言

聊天室允许管理员将部分成员禁言,或者全体禁言。禁言属于高级功能,需要调用云信服务器接口,客户端 SDK 仅提供聊天室禁言的通知功能。

聊天室禁言通知类型被同样定义在了 NIMChatroomEventType 中,分别为

  • 聊天室成员被临时/解除禁言
  • 聊天室被全体禁言/解除全体禁言

具体解析步骤请参考之前小节 聊天室通知消息

系统通知

除消息通道外,NIM SDK 还提供系统通知这种通道用于消息之外的通知分发。目前有两种类型:内置系统通知和自定义系统通知。

内置

这是由 NIM SDK 预定义的通知类型,目前仅支持几种群操作的通知,如被邀请入群,SDK 负责这些通知的持久化。所有的内置系统通知都是通过

-(void)onReceiveSystemNotification:(NIMSystemNotification *)notification;

下发给 APP。为了保证整个程序逻辑的一致性,APP 需要针对不同类型的系统通知进行相应的操作。

内置系统通知的本地存储:(以下接口分为全量和过滤,过滤接口需要传入过滤器 NIMSystemNotificationFilter,可以按类型选择获取内置系统通知)

  • 获取本地存储的内置系统通知

    • 全量接口

      - (NSArray *)fetchSystemNotifications:(NIMSystemNotification *)notification                                                        
                                      limit:(NSInteger)limit;
    • 过滤接口

       - (NSArray *)fetchSystemNotifications:(NIMSystemNotification *)notification 
                                         limit:(NSInteger)limit                          
                                        filter:(NIMSystemNotificationFilter *)filter;
  • 获取本地存储的内置系统未读数

    • 全量接口

      - (NSInteger)allUnreadCount;
    • 过滤接口

      - (NSInteger)allUnreadCount:(NIMSystemNotificationFilter *)filter;
  • 删除本地存储的内置系统通知

    • 全量接口

      - (void)deleteAllNotifications;
    • 过滤接口

      - (void)deleteAllNotifications:(NIMSystemNotificationFilter *)filter;
    • 单条接口

      - (void)deleteNotification:(NIMSystemNotification *)notification;
  • 标记本地存储的内置系统通知为已读

    • 全量接口

      - (void)markAllNotificationsAsRead;
    • 过滤接口

       - (void)markAllNotificationsAsRead:(NIMSystemNotificationFilter *)filter;
    • 单条接口

       - (void)markNotificationsAsRead:(NIMSystemNotification *)notification;

自定义

除内置系统通知外,NIM SDK 也额外提供自定义系统给开发者,方便开发者进行业务逻辑的通知。这个通知既可以由客户端发起也可以由开发者服务器发起。

注意:自定义通知和自定义消息的不同之处在于,自定义消息归属于 NIM SDK 消息体系内,适用于会话,由 SDK 存储在消息数据库中,与 NIM SDK 其他内建消息类型一同展现给用户。而自定义通知主要用于第三方的一些事件状态通知,SDK 不存储,也不解析这些通知。SDK 仅仅负责替第三方传递和通知这些事件,起到透传的作用,收到自定义通知后的持久化工作需要由上层开发负责。

发送自定义通知(客户端)

- (void)sendCustomNotification:(NIMCustomSystemNotification *)notification
                     toSession:(NIMSession *)session
                    completion:(NIMSystemNotificationHandler)completion

客户端发起的自定义通知目前支持自定义如下字段:通知内容(推荐使用 json 组织),推送文案(如果没有则不进行 APNS 推送),是否只发给在线用户。最后一个字段的意义在于区分自定义通知的使用场景。选择只发给在线用户,当目标用户不在线时这条通知会被云信服务器丢弃,这种实现比较适合发送即时通知,如正在输入。反之云信服务器会缓存当前通知(有上限),并在目标用户上线后推送给目标用户。

接收自定义通知

- (void)onReceiveCustomSystemNotification:(NIMCustomSystemNotification *)notification;

事件订阅(在线状态)

云信允许用户订阅监听其他用户产生的事件,产生的事件的方式分为两种:

  • 用户主动发布的自定义事件。
  • 由于用户的一些特定行为触发的内置系统事件。

具体在线状态的业务逻辑可以参考 Demo 的 NTESSubscribeManager 实现。

发布自定义事件

- (void)publishEvent:(NIMSubscribeEvent *)event
          completion:(NIMEventSubscribeBlock)completion;

在发布的前,需要自行构造出 NIMSubscribeEvent 对象,必须需要填写的字段为 type , value。 type 目前仅支持 “在线状态事件” , 即 NIMSubscribeSystemEventTypeOnline 。

订阅事件

- (void)subscribeEvent:(NIMSubscribeRequest *)request
            completion:(NIMEventSubscribeResponseBlock)completion;

取消订阅

- (void)unSubscribeEvent:(NIMSubscribeRequest *)request
              completion:(NIMEventSubscribeResponseBlock)completion;

在调用 订阅/取消订阅 事件接口前,需要先构造 NIMSubscribeRequest 订阅请求对象。

在订阅事件中,订阅请求中必需填写 typeexpirypublishers 字段。publishers 字段最多仅支持 100 个账号 id , 某些场景如在线状态,订阅人数会超过限制,需要多次调用此接口来满足业务,具体详见 Demo 中 NTESSubscribeManager 的 - (void)subscribeOnlineState 方法。

在取消订阅中,订阅请求中必须填写 type 字段,如果不填写 publishers 字段,则取消指定事件的全部订阅关系。

查询订阅事件关系

- (void)querySubscribeEvent:(NIMSubscribeRequest *)request
                 completion:(NIMEventSubscribeQueryBlock)completion;

SDK 提供查询本账号和指定账号存在的订阅关系接口,调用接口前,必须先构造 NIMSubscribeRequest 订阅请求对象。 其中,必须填写 type 字段 和 publishers 字段,查询人数最大支持 100 人。

目前不支持直接查询本账号和所有账号的订阅关系,上层需要维护好需要查询的用户 id, 通过多次调用此接口完成查询。

APNS 推送

前期准备

[[NIMSDK sharedSDK] registerWithAppID:您的APPKEY
                              cerName:您的推送证书名];
  • 客户端注册 APNS,并在获取到 APNS Token 时将值传给 SDK
- (void)registerAPNs
{
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerForRemoteNotifications)])
    {
        UIUserNotificationType types = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |      UIRemoteNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types
        categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        UIRemoteNotificationType types = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound |        UIRemoteNotificationTypeBadge;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
    }
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    [[NIMSDK sharedSDK] updateApnsToken:deviceToken];
}

推送时机

开发者在 发送消息 和 自定义系统通知 时,可以指定是否同时进行推送服务。为了节省不必要的流量开销,只有当接收者的应用切换到后台时,云信推送服务才会开启;如果应用在前台,则不会有推送通知。如果有应用前台通信需求,建议开发者使用 自定义系统通知 ,并监听回调:

- (void)onReceiveCustomSystemNotification:(NIMCustomSystemNotification *)notification;

属性设置

NIM SDK 提供全局 APNS 属性设置,用于设置免打扰时间和推送样式,详细内容可以参考 NIMPushNotificationSetting

  • 获取推送设置:
NIMPushNotificationSetting *setting =  [[[NIMSDK sharedSDK] apnsManager] currentSetting];
  • 修改推送设置:
[[[NIMSDK sharedSDK] apnsManager] updateApnsSetting:setting
completion:^(NSError *error) {}];

APNS 多端设置 NIMPushNotificationMultiportConfig

  • 获取 APNS 多端设置
- (NIMPushNotificationMultiportConfig *)currentConfig;
  • 修改 APNS 多端设置
- (void)updateConfig:(NIMPushNotificationMultiportConfig *)config
          completion:(NIMApnsHandler)completion;

当桌面端在线时,可以通过设置 shouldPushNotificationWhenPCOnline 字段,控制是否需要发推送给手机端。

消息推送内容设置

用户在发送消息的时候,设置 NIMMessage 的 apnsContent 属性进行消息推送内容设置。如果不设置 apnsContent 属性,将使用云信内置文案。设置 NIMMessage 的 apnsPayload 可以自定义推送参数。

示例代码:

NIMAudioObject *audioObject = [[NIMAudioObject alloc] initWithSourcePath:filePath];
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = audioObject;
message.apnsContent = @"发来了一段语音";    //对方收到的推送文案

用户在发送自定义系统通知的时候,设置 NIMCustomSystemNotification 的 apnsContent 属性来定制消息推送内容,同时可以设置 apnsPayload 来配置推送参数。

消息的成员推送选项

用户在发消息的时候,可以通过配置 NIMMessage 里的 apnsMemberOption 字段实现更为复杂的推送逻辑,目前这个字段只能在群会话中生效。

  • 需要在给某些指定的成员推送特殊的文案

    • 设置 NIMMessageApnsMemberOption 的 userIds 字段,如果这个字段为nil,则表示推送给当前会话内的所有用户。
    • 设置 NIMMessageApnsMemberOption 的 apnsContent 字段来指定特殊的推送文案,如果这个字段为 nil ,则使用消息本身的推送文案。
  • 强制推送。适用场景例如用户屏蔽了某个群,但是在群里有其他人 @ 了这个用户,则不管用户是否对这个群屏蔽推送,都要推送给这个用户如 “有人 @ 了你” 这样的文案。

    • 同上设置指定特殊的推送成员。
    • 同上设置特殊的推送文案。
    • 设置 NIMMessageApnsMemberOption 的 forcePush 字段为 YES

PushKit

PushKit 作为苹果公司在 iOS8 系统及以上引入的新类型推送,也被称作 voip push 。顾名思义,这种推送可以帮助我们提升 voip 应用的体验,优化 voip 应用的开发实现,降低 voip 应用的电量消耗。

基于这种类型的推送,开发者不必在后台设法维护一套长连接来保证接通率,客户端在收到推送的时候,会自动后台唤起应用,可以在此时完成云信相关的业务注册,展开正常的 voip 业务。开发者甚至可以在 PushKit 基础上, 借助 CallKit 搭建出一套呼叫界面,让应用拥有媲美原生来电通话的用户体验。

目前通过在云信后台配置 PushKit 证书,点对点电话呼叫接口推送将会使用 PushKit 。PushKit 证书配置与 APNS 证书配置雷同,这里不再展开。

在客户端实现中,需要将接口

- (void)registerWithAppID:(NSString *)appKey
                  cerName:(nullable NSString *)cerName

变更为

- (void)registerWithOption:(NIMSDKOption *)option

注册 PushKit 推送

PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

在 PKPushRegistryDelegate 协议回调中,调用云信上传 PushKit Token 接口:

- (void)updatePushKitToken:(NSData *)token
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
    if ([type isEqualToString:PKPushTypeVoIP])
    {
        [[NIMSDK sharedSDK] updatePushKitToken:credentials.token];
    }
}

推送问题排查方案

推送配置后在后台仍收不到通知栏提醒可检查如下步骤:

云信IOS推送收不到问题排查方案

用户资料托管

NIMUserManager 提供了用户帐号资料管理。以下几个接口仅当选择云信托管用户资料时有效,如果开发者不希望云信获取自己的用户数据,则需自行维护用户资料。

NIMUserManager 里,使用 NIMUser 对用户进行封装。其中用户信息为 NIMUserInfo 属性。 具体的信息字段由 NIMUserInfoUpdateTag定义。 NIMUserInfoUpdateTag内置了多个常用信息字段(有格式校验)和一个拓展字段 NIMUserInfoUpdateTagEx 供开发者自行拓展。

获取本地用户资料

- (NIMUser *)userInfo:(NSString *)userId;

用户资料除自己之外,不保证其他用户资料实时更新。其他用户数据更新时机为:

  • 调用 - (void)fetchUserInfos:completion: 方法刷新用户

  • 收到此用户发来消息

  • 程序再次启动,此时会同步好友资料

获取服务器用户资料

- (void)fetchUserInfos:(NSArray<NSString *> *)users
            completion:(NIMUserInfoBlock)completion

此接口可以批量从服务器获取用户资料,出于用户体验和流量成本考虑,不建议应用频繁调用此接口。对于用户数据实时性要求不高的页面,应尽量调用读取本地缓存接口。

编辑用户资料

- (void)updateMyUserInfo:(NSDictionary *)values completion:(NIMUserBlock)block;

只允许用户编辑自己的资料。此接口可以一次性编辑多个属性。如昵称,头像等,传入的数据键值对是 {@(NIMUserInfoUpdateTag) : NSString},无效数据将被过滤。一些字段有修改格式校验。具体限制为:

属性名 具体字段 类型限制 格式校验
用户昵称 NIMUserInfoUpdateTagNick NSString
用户头像 NIMUserInfoUpdateTagAvatar NSString
用户签名 NIMUserInfoUpdateTagSign NSString
用户性别 NIMUserInfoUpdateTagGender NIMUserGender 只支持指定枚举
用户邮箱 NIMUserInfoUpdateTagEmail NSString 只支持合法邮箱
用户生日 NIMUserInfoUpdateTagBirth NSString yyyy-MM-dd
用户手机 NIMUserInfoUpdateTagBirth NSString 合法手机号 如13588888888、+(86)-13055555555
拓展字段 NIMUserInfoUpdateTagExt NSString

当修改用户资料成功后,会触发回调:

- (void)onUserInfoChanged:(NIMUser *)user;

用户关系托管

NIMUserManager 提供了用户用户关系管理,以及对用户会话的消息设置。在云信中,不是好友也允许聊天。用户关系如果不托管给云信,开发者需要自己在应用服务器维护。

好友关系

  • 获取好友列表

      - (NSArray<NIMUser *> *)myFriends;

    好友列表有本地缓存,缓存会在手动/自动登录后与服务器自动进行同步更新。接口返回的是 NIMUser 列表。 NIMUser 封装了开发者向云信托管的好友ID,对此好友的会话设置(是否需要消息提醒,是否是拉黑用户等), 以及用户的详细信息 NIMUserInfo (需要将用户信息交给云信托管)。

  • 好友请求

      - (void)requestFriend:(NIMUserRequest *)request
                 completion:(NIMUserBlock)block;
    • 好友请求包括请求添加好友以及同意/拒绝好友请求两种。

    • 好友请求需要构造出一个 NIMUserRequest 对象,封装添加对象用户的ID,以及添加方式。

      代码示例:

       NIMUserRequest *request = [[NIMUserRequest alloc] init];
       request.userId          = self.user.usrId;                            //封装用户ID
       request.operation       = NIMUserOperationRequest;                    //封装验证方式
       request.message         = @"跪求通过";                                 //封装自定义验证消息
    • 验证方式有 NIMUserOperationAdd 和 NIMUserOperationRequest 两种。

      第一种是不需要验证方式的,一旦请求后双方直接互为好友。

      第二种是需要验证的,对方会收到一条类型为 NIMSystemNotificationTypeFriendAdd 系统通知 ( NIMSystemNotification )。

  • 验证回复有 同意 NIMUserOperationVerify 和 拒绝 NIMUserOperationReject 两种。 对方收到消息之后,可以选择接受或者拒绝好友邀请,此时同样调用 requestFriend:completion: 方法,传入拒绝对象的ID和验证回复类型即可。

  • 好友添加成功后,会触发回调:

         - (void)onFriendChanged:(NIMUser *)user;
  • 删除好友

    • 用户和用户之间可以解除好友关系。

        - (void)deleteFriend:(NSString *)userId
                  completion:(NIMUserBlock)block;
    • 解除成功后,会同时修改本地的缓存数据,并触发回调:

        - (void)onFriendChanged:(NIMUser *)user;

黑名单

云信中,黑名单和好友关系是互相独立的,即修改好友关系不会影响黑名单关系,同时,修改黑名单也不会对好友关系进行操作。

  • 获取黑名单成员列表
- (NSArray<NIMUser *> *)myBlackList;

黑名单列表有本地缓存,缓存会在手动/自动登录后与服务器自动进行同步更新。接口返回的是 NIMUser 列表。 NIMUser 封装了开发者向云信托管的好友ID,对此好友的会话设置(是否需要消息提醒,是否是拉黑用户等), 以及用户的详细信息 NIMUserInfo (需要将用户信息交给云信托管)。

  • 添加用户到黑名单
- (void)addToBlackList:(NSString *)userId
            completion:(NIMUserBlock)block;

拉黑成功后,会同时修改本地缓存,并触发回调:

- (void)onBlackListChanged;
  • 将用户从黑名单移除
- (void)removeFromBlackBlackList:(NSString *)userId
                      completion:(NIMUserBlock)block;

移除成功后,会同时修改本地缓存,并触发回调:

- (void)onBlackListChanged;
  • 判断用户是否在自己的黑名单内
- (BOOL)isUserInBlackList:(NSString *)userId;

此接口是根据本地缓存数据来判断是否拉黑的,在调用时请保证本地缓存是正确的(登录后有正常完成数据同步)。

消息提醒

云信中,可以单独设置是否开启某个用户的消息提醒,即对某个用户静音。静音关系和好友关系是互相独立的,修改好友关系不会影响静音关系,同时,修改静音关系也不会对好友关系进行操作。

  • 获取静音成员列表
- (NSArray<NIMUser *> *)myMuteUserList;

静音列表有本地缓存,缓存会在手动/自动登录后与服务器自动进行同步更新。接口返回的是 NIMUser 列表。 NIMUser 封装了开发者向云信托管的好友ID,对此好友的会话设置(是否需要消息提醒,是否是拉黑用户等), 以及用户的详细信息 NIMUserInfo (需要将用户信息交给云信托管)。

  • 设置消息提醒
- (void)updateNotifyState:(BOOL)notify
                  forUser:(NSString *)userId
               completion:(NIMUserBlock)block;

设置成功之后,同时更新本地缓存数据。

  • 用户是否有消息提醒
- (BOOL)notifyForNewMsg:(NSString *)userId;

此接口是根据本地缓存数据来判断是否有消息提醒的,在调用时请保证本地缓存是正确的(登录后有正常完成数据同步)。

当修改用户资料成功后,会触发回调:

- (void)onUserInfoChanged:(NIMUser *)user;

智能对话机器人

智能对话机器人解决方案依托网易 IM 即时通讯、语音识别、语义理解等服务,为开发者提供人机交互API/SDK、语音识别、意图识别、知识库配置、动态接口等功能,可以在应用IM内快速集成场景丰富的智能对话机器人。

区别于开发者业务后台自行设定的机器人,网易波特中配置的机器人,类似网易精灵、小黄鸡这种通过配置知识库,与用户进行交流问答的智能对话机器人 。开发者可以在 网易波特服务 开通机器人服务。

机器人和云信账号是有绑定关系的,一个机器人账号对应了一个云信 id ,两者互相独立 , 云信内部负责维护对应关系。机器人所对应的云信用户不会在线,也不应该和其他正常用户有用户关系,如加好友,拉黑等。

智能对话机器人消息属于云信内置基础消息类型中的一种,发送示例请参考 发送消息 章节。

机器人内容格式规范可参考 机器人消息体模板说明 。

机器人的数据会在每次登录后自动同步至客户端。本地机器人数据由 NIMRobotManager 管理。

  • 获取本地存储的所有有效的机器人
- (NSArray *)allRobots
  • 是否是有效的机器人
- (BOOL)isValidRobot:(NSString *)userId

当机器人被移除时,userId 对应的机器人则为无效。

  • 获取机器人信息
- (NIMRobot *)robotInfo:(NSString *)userId
机器人消息

机器人消息分上行消息和下行消息。用户向机器人发送的消息被称为上行消息,构造示例可以参考发送消息 章节;机器人向用户回复的消息被称为下行消息。

在 NIMRobotObject 里,判断是否上下行的字段为

@property (nonatomic, assign, readonly) BOOL isFromRobot;

同时,设置了只有机器人下行消息才有效的只读字段:

  • 机器人回复的消息所属的提问消息 Id
@property (nullable, nonatomic, copy, readonly) NSString *responseForMessageId
  • 机器人回复的消息内容数据,上层需要根据这个数据进行 UI 展现
@property (nullable, nonatomic, copy, readonly) NSDictionary *response

API 文档


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sjl_leaf/article/details/77096296

智能推荐

推荐30款最佳的数据可视化工具_可视化软件-程序员宅基地

文章浏览阅读1.2w次。推荐30款最佳的数据可视化工具发表于2014-04-02 13:28| 64049次阅读| 来源CSDN| 0 条评论| 作者张红月开源可视化工具iChartsFusionCharts XTModest MapsRaw摘要:大量繁杂的数据在经过可视化工具处理后,就能以图形化的形式展现在用户面前,清晰直观。随着各种数据的增加,这种可视化工具越来越得到开_可视化软件

androidt程序文字锯齿-程序员宅基地

文章浏览阅读264次。刚才才发现,在开发android程序时,如果在manifest中忘了如以下[code="xml"] [/code]这样的定义,将会导致在程序中文字出现锯齿,甚至在onDraw方法中画出来的图形比例不一样的结果。难怪以前看一些程序,总是很奇怪地出现文字锯齿的现象,原来是这个原因。..._android绘制draw文字时为什么文字被切割

delphi日期的使用-程序员宅基地

文章浏览阅读113次。delphi中日期的函数大部分都在DateUtil中。1、获取当年当月当周的第一天和最后一天 函数uses DateUtils;function StartOfTheYear(const AValue: TDateTime): TDateTime; //获取当年的第一天function EndOfTheYear(const AValue: TDateTime): TDateTime;functi..._delphi 获取当年最后一天

QtCreator 断点不起作用_qtcreator断点不能生效-程序员宅基地

文章浏览阅读9k次。使用QtCreator 调试程序时一直无法进入断点,断点根本不起作用。解决方法:打开.pro文件将图中的release改为debug,再次调试运行就可以进入断点了。_qtcreator断点不能生效

vue3在js文件中使用store_js 文件访问store-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏3次。vue3在js文件使用store报错undefined_js 文件访问store

vulnhub渗透测试靶场练习1_vulhub的poc脚本-程序员宅基地

文章浏览阅读912次。一次完整的渗透测试靶场练习_vulhub的poc脚本

随便推点

使用Qt开发运行于WinCE上的程序_wince 7上跑qt程序-程序员宅基地

文章浏览阅读9k次。 使用Qt开发运行于WinCE上的程序 简介 1一、编译Qt SDK for WinCE,建立开发环境 11 编译环境 : “Wince60standard(操作系统)_armv4i(处理器)_msvc2005(开发环境)” 12 编译步骤 (整个过程参见Qt文档) 2二.代码编写 2三、编译Qt-WinCE程序 3四. _wince 7上跑qt程序

关于C++中如何判断文件、目录存在的若干方法_c++判断目录是否存在-程序员宅基地

文章浏览阅读2.2w次,点赞8次,收藏28次。在我们平时的编程中,经常需要判断文件或者目录是否存在,相对来说判断文件存在比较简单,判断目录存在则比较复杂。下面就详细的介绍几种方法。首先,关于判断文件存在的方法:一、ifstream输入流在C++中,可以利用ifstream文件输入流,当我们直接使用ifstream来创建文件输入流的时候,如果文件不存在则流创建失败。ifstream fin("he_c++判断目录是否存在

数据库中的读写放大与空间放大_读放大-程序员宅基地

文章浏览阅读1.4k次。在实现最优compaction策略时,我们必须考虑多个因素。一种方法是回收重复记录占用的空间,减少空间开销,但这会产生由不断重写表导致的更高的写放大。替代方案是避免连续重写数据,而这又增加了读放大(在读取期间协调关联到相同键的数据记录的开销)和空间放大(因为冗余记录会被保存更长时间)。读放大:由为了检索数据而需要读取多个表所引起。写放大: 由compaction过程中不断进行的重写所引起。空间放大由: 存储关联到同一键的多个记录所引起。_读放大

gitlab项目描述如何换行显示_我们是如何做DevOps的?-程序员宅基地

文章浏览阅读817次。一、DevOps的理解DevOps的概念理解DevOps 的概念在软件开发行业中逐渐流行起来。越来越多的团队希望实现产品的敏捷开发,DevOps 使一切成为可能。有了 DevOps ,团队可以定期发布代码、自动化部署、并将持续集成 / 持续交付作为发布过程的一部分。一句话概括就是提高生产力,快速交付!二、引入DevOps的背景2.1 福禄技术栈介绍后端开发框架:基于C#的.netCore...

NLP学习资料汇总-程序员宅基地

文章浏览阅读165次。NLP入门:莫烦PythonTransformer:【译】图解Transformer - d0main - 博客园Bert:图解BERT(NLP中的迁移学习) - d0main - 博客园双向Transformer:【译】深度双向Transformer预训练【BERT第一作者分享】 - d0main - 博客园bert三个嵌入层:【译】为什么BERT有3个嵌入层,它们都是如何实现的 - d0main - 博客园Transfomer加入位置信息:【译】在Transformer中加入相..._nlp学习资料

高通工具过滤_高通常用开发工具介绍-程序员宅基地

文章浏览阅读454次。目录1:下载2:QXDM3:其他4:参考文档高通工具网站:https://createpoint.qti.qualcomm.com/tools/下载1:fastboot 2:QPST 3:QFITFastbootadb reboot bootloader下载:fastboot flash partition gpt_both0.binfastboot flash aboot emmc_appsbo..._createpoint qualcomm