消息收发

功能概述

SDK 中用于表示消息的结构为NIMMessage。消息属于云信即时通讯中最关键最重要的类,它是传递消息的基本模型。

部分重要属性列表:

参数 类型 说明
messageType 消息类型 消息的类型枚举,只读。当构造消息的时候,SDK 会根据传入的 messageObject 自动判断并填入消息类型
messageSubType 消息自定义子类型 默认为0。当需要自定义消息的子类型时,需要设置此项。本地消息检索时,可以通过设置NIMMessageSearchOption的messageSubTypes来查找指定的子类型
from 消息的发送者 为发送者 Id 。当发送消息的时候,SDK 会根据当前登录情况自动填写
session 消息的所属会话 为消息发送到对话的 Id 。当发送的是点对点消息时,此 Id 为接受者 Id;当发送的是群或聊天室消息时,此 Id 为群或聊天室 Id 。
messageId 消息客户端 Id 消息的唯一标识,在消息对象初始化后自动生成
serverID 消息服务端 Id 消息发送成功后在服务端生成
text 消息文本 用来做 UI 显示的消息文本,通常情况下,除了文本消息和提醒消息 外,其他消息 text 字段都为 nil
messageObject 消息附件 开发者需要重点关心的属性,附件需要实现 NIMMessageObject 协议。 开发者通过注入不同的消息附件使消息变为不同类型,并附上不同消息类型所需要的信息,如图片数据,地理位置等
setting 消息设置 开发者通过在发送消息前注入一个消息设置对象,可以制定当前消息的各种设置,如是否需要计入未读,是否需要多端同步等
antiSpamOption 反垃圾选项 目前仅支持易盾,只有接入了易盾才可以设置这个配置
apnsContent 推送文案 APNs 推送文案,设置后,手机在后台将会收到相关文案的苹果推送
apnsPayload 消息推送 Payload 可以通过这个字段定义消息推送 Payload , 苹果内置字段目前只支持 sound 字段
apnsContent 推送文案 APNs 推送文案,设置后,手机在后台将会收到相关文案的苹果推送
apnsMemberOption 指定成员推送选项 开发者通过在发送消息前注入这个设置对象,可以进行一些更复杂的推送设定,比如强制推送,部分推送等。目前只能在群会话中使用
remoteExt 服务器扩展 客户端在发送消息前,可以设置这个字段,这个字段将在本地存储且发送至对端,上层需要保证 NSDictionary 可以转换为 JSON
localExt 客户端扩展 客户端可以设置这个字段,这个字段只在本地存储,不会发送至对端,上层需要保证 NSDictionary 可以转换为 JSON。如果在消息发送后设置,需要手动调用存储消息到本地的方法。
messageExt 消息拓展字段 服务器下发的消息拓展字段,不在本地做持久化,目前只有聊天室中的消息才有该字段 (NIMMessageChatroomExtension) 。
timestamp 消息发送时间 本地存储消息可以通过修改时间戳来调整其在会话列表中的位置,发完服务器的消息时间戳将被服务器自动修正。
isReceivedMsg 是否是收到的消息 由于有漫游消息的概念,所以自己发出的消息漫游下来后仍旧是"收到的消息",这个字段用于消息出错是时判断需要重发还是重收。
deliveryState 消息投递状态 仅针对发送的消息,这个字段才有效。
attachmentDownloadState 消息附件下载状态 仅针对收到的消息,这个字段才有效。
isOutgoingMsg 是否是往外发的消息 由于能对自己发消息,所以并不是所有来源是自己的消息都是往外发的消息,这个字段用于判断头像排版位置(是左还是右)。
isPlayed 消息是否被播放过 修改这个属性,SDK 会自动更新 db 中对应的数据。
isDeleted 消息是否标记为已删除 删除消息在本地存储时只会标记删除状态,已删除的消息在获取本地消息列表时会被过滤掉,只有根据 messageId 获取消息的接口可能会返回已删除消息。
isRemoteRead 对端是否已读 只有当当前消息为 P2P 消息且 isOutgoingMsg 为 YES 时这个字段才有效,需要对端调用过发送已读回执的接口。
senderName 消息发送者名字 当发送者是自己时,这个值可能为空,这个值表示的是发送者当前的昵称,而不是发送消息时的昵称。聊天室消息里,此字段无效。
senderClientType 发送者客户端类型 发送者当时所处的客户端种类,种类可能随着 SDK 版本更新增加,上层开发者需考虑新老版本带来的兼容问题。

上述消息的状态属性,推荐只在主线程对这些属性进行读写

目前提供如下几种消息类型,不同的消息类型对应不同的 MessageObject:

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

消息发送

开发者需要通过 NIMSDK 里的 NIMChatManager 协议进行消息发送。

原型

@protocol NIMChatManager <NSObject>
/**
 *  发送消息
 *
 *  @param message 消息
 *  @param session 接受方会话
 *  @param error   错误 如果在准备发送消息阶段发生错误,这个error会被填充相应的信息
 *
 *  @return 发送完成后的回调,这里的回调完成只表示当前这个函数调用完成,需要后续的发送消息完成回调 – sendMessage:didCompleteWithError: 才能判断消息是否已经发送至服务器
 */
- (BOOL)sendMessage:(NIMMessage *)message
          toSession:(NIMSession *)session
              error:(NSError * __nullable *)error;
@end

关于会话NIMSession的具体信息,请参见最近会话章节。

此外,针对大文件还提供异步发送消息的方法:

@protocol NIMChatManager <NSObject>
/**
 *  异步发送消息,通常用于发送大文件
 *
 *  @param message 消息
 *  @param session 接收方
 *  @param completion 发送完成后的回调,这里的回调完成只表示当前这个函数调用完成,需要后续的发送消息完成回调 – sendMessage:didCompleteWithError: 才能判断消息是否已经发送至服务器
 */
- (void)sendMessage:(NIMMessage *)message
          toSession:(NIMSession *)session
         completion:(nullable void(^)(NSError * __nullable error))completion;    
@end

属性列表

参数 类型 说明
message NIMMessage 需要发送的消息,开发者构造出 message 后,需要选择构造对应的 messageObject 注入 (文本消息直接填入 text 即可,无须消息附件注入),即可传入此接口进行发送
session NIMSession 需要发送到的会话
error NSError * 开发者需要自己构造出一个 NSError 对象,并将对象引用传入。如果在准备发送消息阶段发生错误,这个对象会被填充相应的信息。通常为参数检查错误或者登录状态错误,可参考错误码说明定位具体的出错类型
completion void(^)(NSError *error) 该回调完成只代表接口调用成功

开发者需要通过 NIMChatManagerDelegate 协议进行消息发送结果的监听:

@protocol NIMChatManagerDelegate <NSObject>
/**
 *  发送消息完成回调
 *
 *  @param message 所发送的消息
 *  @param error 失败原因,如果发送成功则error为nil
 */
- (void)sendMessage:(NIMMessage *)message 
  didCompleteWithError:(nullable NSError *)error; 
@end

此外,开发者可以在以下回调里获取 消息发送的进度:

@protocol NIMChatManagerDelegate <NSObject>
/**
 *  发送消息进度回调
 *
 *  @param message 所发送的消息
 *  @param progress 进度
 */
- (void)sendMessage:(NIMMessage *)message 
           progress:(float)progress;
@end

文本消息发送

以发送一条文本消息 hello 至好友 Id 为 user的业务场景进行示例:

// 构造出具体会话:P2P单聊,对方账号为user
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 构造出具体消息
NIMMessage *message = [[NIMMessage alloc] init];
message.text        = @"hello";
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

图片消息发送

图片附件NIMImageObject参数列表

参数 类型 说明
path NSString 图片本地路径
thumbPath NSString 缩略图本地路径,缩略图在默认情况下由 SDK 自动下载,如果发现本地不存在缩略图,可手动调用 NIMChatManager 协议中的获取缩略图方法 fetchMessageAttachment:error: 进行下载
url NSString 大图的远程 URL 路径,开发者可通过这个属性自行下载大图
thumbUrl NSString 缩略图远程 URL 路径,仅适用于使用云信上传服务进行上传的资源,否则无效
size NSString 图片尺寸
option NIMImageOption 图片的压缩选项仅在发送时且通过 initWithImage: 方式初始化才有效
fileLength NSString 文件大小
md5 NSString 图片MD5

NIMImageOption 图片选项参数列表

参数 类型 说明
compressQuality float 压缩参数默认为 0 ,可传入 0.0 - 1.0 的值,如果值为 0 或者不合法参数时按照 0.5 进行压缩
format NIMImageFormat 图片压缩格式,可选 JPEG 和 PNG 两种。默认为 JPEG

普通图片附件初始化提供三种方式:

@interface NIMImageObject : NSObject<NIMMessageObject>
/**
 *  图片实例对象初始化方法
 *
 *  @param image 要发送的图片
 *
 *  @return 图片实例对象
 */
- (instancetype)initWithImage:(UIImage*)image;

/**
*  图片实例对象初始化方法
*
*  @param image 要发送的图片
*  @param scene 场景类别
*
*  @return 图片实例对象
*/
- (instancetype)initWithImage:(UIImage*)image scene:(NSString *)scene;
@end

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得图片附件对象
NIMImageObject *object = [[NIMImageObject alloc] initWithImage:image];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];
@interface NIMImageObject : NSObject<NIMMessageObject>
/**
 *  图片实例对象初始化方法
 *
 *  @param filepath 要发送的图片路径
 *
 *  @return 图片实例对象
 */
 - (instancetype)initWithFilepath:(NSString *)filepath;

 /**
 *  图片实例对象初始化方法
 *
 *  @param filepath 要发送的图片路径
 *  @param scene 场景类别
 *
 *  @discussion 使用此方法上传是不做压缩转换的原图上传。iOS 11 苹果采用了新的图片格式 HEIC ,如果采用原图会导致其他设备的兼容问题,请开发者在上层做好格式的兼容转换。
 *
 *  @return 图片实例对象
 */
 - (instancetype)initWithFilepath:(NSString *)filepath scene:(NSString *)scene;
 @end

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得图片附件对象
NIMImageObject *object = [[NIMImageObject alloc] initWithFilepath:path];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];
@interface NIMImageObject : NSObject<NIMMessageObject>
  /**
   *  图片实例对象初始化方法
   *
   *  @param data 图片数据
   *  @param extension 推荐使用的图片数据后缀名
   *
   *  @return 图片实例对象
   */
- (instancetype)initWithData:(NSData *)data
                   extension:(NSString *)extension;

/**
*  图片实例对象初始化方法
*
*  @param data 图片数据
*  @param extension 推荐使用的图片数据后缀名
*  @param scene 场景类别
*
*  @return 图片实例对象
*/
- (instancetype)initWithData:(NSData *)data
                   extension:(NSString *)extension
                   scene:(NSString *)scene;
@end                    

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得图片附件对象
NIMImageObject *object = [[NIMImageObject alloc] initWithData:data extension:@"png"];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

若为Webp格式的图片时,需要使用下列方法初始化图片实例对象:

@interface NIMImageObject : NSObject<NIMMessageObject>
  /**
   *  图片实例对象初始化方法, 可用于发送Webp图片
   *  @param filepath 要发送的图片路径
   *  @param scene 场景类别
   *  @param size  图片宽高,当发送文件为Webp时须需要传入该图片尺寸大小
   *  @return 图片实例对象
   */
- (instancetype)initWithFilepath:(NSString *)
                  filepath scene:(NSString *)scene 
                            size:(CGSize)size

/**
*  图片实例对象初始化方法, 可用于发送Webp图片
*  @param data 图片数据
*  @param extension 推荐使用的图片数据后缀名
*  @param scene 场景类别
*  @param size  图片宽高,当发送文件为Webp时须需要传入该图片尺寸大小
*  @return 图片实例对象
*/
- (instancetype)initWithData:(NSData *)data 
                   extension:(NSString *)extension 
                       scene:(NSString *)scene 
                        size:(CGSize)size
@end                    

语音消息发送

语音附件类NIMAudioObject参数列表

参数 类型 说明
path NSString 语音本地路径,语音在默认情况下由 SDK 自动下载,如果发现本地不存在语音文件,可手动调用 NIMChatManager 协议中的获取语音附件方法 fetchMessageAttachment:error: 进行下载
url NSString 语音的远程 URL 路径
duration NSInteger 语音时长,毫秒为单位,SDK会根据传入文件信息自动解析出音频的 duration, 开发者也可以自己计算设置这个值
md5 NSString 音频MD5

语音附件初始化提供两种方式:

@interface NIMAudioObject : NSObject<NIMMessageObject>
/**
 *  语音附件初始化方法
 *
 *  @param sourcePath 语音路径
 *
 *  @return 语音实例对象
 */
 - (instancetype)initWithSourcePath:(NSString *)sourcePath;

 /**
 *  语音对象初始化方法
 *
 *  @param sourcePath 语音路径
 *  @param scene 场景类别
 *
 *  @return 语音实例对象
 */
 - (instancetype)initWithSourcePath:(NSString *)sourcePath scene:(NSString *)scene;
@end

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得语音附件对象
NIMAudioObject *object = [[NIMAudioObject alloc] initWithSourcePath:path];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];
@interface NIMAudioObject : NSObject<NIMMessageObject>
/**
*  语音对象初始化方法
*
*  @param data 语音数据
*  @param extension 语音数据文件后缀名
*
*  @return 语音实例对象
*/ 
- (instancetype)initWithData:(NSData *)data
                extension:(NSString *)extension;

/**
*  语音对象初始化方法
*
*  @param data 语音数据
*  @param extension 语音数据文件后缀名
*  @param scene 场景类别
*
*  @return 语音实例对象
*/
- (instancetype)initWithData:(NSData *)data
                   extension:(NSString *)extension
                       scene:(NSString *)scene;
@end

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得语音附件对象
NIMAudioObject *audioObject = [[NIMAudioObject alloc] initWithData:data extension:@"aac"];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

视频消息发送

视频附件类NIMVideoObject参数列表

参数 类型 说明
displayName NSString 视频的显示名, 由开发者自行定义,供上层 UI 使用
md5 NSString 根据视频数据生成的 MD5
path NSString 视频的本地路径。
url NSString 视频的远程路径
coverUrl NSString 视频封面的远程路径,只有是上传到云信服务器上的视频才支持封面地址,否则地址无效
coverPath NSString 视频封面的本地路径。视频封面在默认情况下由 SDK 自动下载,如果发现本地不存在封面文件,可手动调用 NIMChatManager 协议中的获取封面方法 fetchMessageAttachment:error: 进行下载
coverSize CGSize 视频封面的大小,由 SDK 自行计算
duration NSInteger 视频时长,毫秒为单位, SDK 会根据传入文件信息自动解析出 duration ,但上层也可以自己设置这个值

视频消息附件初始化提供两种方式:

@interface NIMVideoObject : NSObject<NIMMessageObject>
/**
 *  视频实例对象的初始化方法
 *
 *  @param sourcePath 视频的文件路径
 *
 *  @return 视频实例对象
 */
- (instancetype)initWithSourcePath:(NSString *)sourcePath;

/**
*  视频实例对象的初始化方法
*
*  @param sourcePath 视频的文件路径
*  @param scene 场景类别
*
*  @return 视频实例对象
*/
- (instancetype)initWithSourcePath:(NSString *)sourcePath scene:(NSString *)scene;
@end 

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得视频附件对象
NIMVideoObject *object = [[NIMVideoObject alloc] initWithSourcePath:path];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];
@interface NIMVideoObject : NSObject<NIMMessageObject>
/**
 *  视频实例对象的初始化方法
 *
 *  @param data 视频数据
 *  @param extension 视频文件后缀
 *
 *  @return 视频实例对象
 */
- (instancetype)initWithData:(NSData *)data
                extension:(NSString *)extension;

/**
*  视频实例对象的初始化方法
*
*  @param data 视频数据
*  @param extension 视频文件后缀
*  @param scene 场景类别
*
*  @return 视频实例对象
*/
- (instancetype)initWithData:(NSData *)data
                   extension:(NSString *)extension
                       scene:(NSString *)scene;
@end

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得视频附件对象
NIMVideoObject *object = [[NIMVideoObject alloc] initWithData:data extension:@"mp4"];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

文件消息发送

文件附件类NIMFileObject参数列表

参数 类型 说明
displayName NSString 文件的显示名, 由开发者自行定义,供上层 UI 使用
md5 NSString 根据文件数据生成的 MD5
path NSString 文件的本地路径。目前 SDK 并不提供文件下载功能,但是建议 APP 使用这个 path 作为文件的下载地址,以便后期 SDK 提供缓存清理等功能
url NSString 文件的远程路径
fileLength long long 文件的大小

文件附件初始化提供两种方式:

@interface NIMFileObject : NSObject<NIMMessageObject>
/**
 *  文件对象初始化方法(根据文件路径)
 *
 *  @param sourcePath 文件路径
 *
 *  @return 文件实例对象
 */
 - (instancetype)initWithSourcePath:(NSString *)sourcePath;

 /**
 *  文件对象初始化方法(根据文件路径)
 *
 *  @param sourcePath 文件路径
 *  @param scene 场景类别
 *
 *  @return 文件实例对象
 */
 - (instancetype)initWithSourcePath:(NSString *)sourcePath scene:(NSString *)scene;
@end 

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得文件附件对象
NIMFileObject *object = [[NIMFileObject alloc] initWithSourcePath:path];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];
@interface NIMFileObject : NSObject<NIMMessageObject>
/**
 *  文件实例对象的初始化方法
 *
 *  @param data 文件数据
 *  @param extension 文件后缀
 *
 *  @return 文件实例对象
 */
- (instancetype)initWithData:(NSData *)data
                    extension:(NSString *)extension;

/**
*  文件对象初始化方法(根据文件数据)
*
*  @param data 文件数据
*  @param extension 文件拓展名
*  @param scene 场景类别
*  @return 文件实例对象
*/

- (instancetype)initWithData:(NSData*)data extension:(NSString*)extension scene:(NSString *)scene;
@end

示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得视频附件对象
NIMFileObject *audioObject = [[NIMFileObject alloc] initWithData:data extension:@"data"];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

位置消息发送

位置附件类NIMLocationObject参数列表参数列表

参数 类型 说明
latitude double 维度位置,由初始化时传入
longitude double 经度位置,由初始化时传入
title NSString 位置标题信息,由初始化时传入

-初始化方法原型

@interface NIMLocationObject : NSObject<NIMMessageObject>
/**
 *  位置实例对象初始化方法
 *
 *  @param latitude  纬度
 *  @param longitude 经度
 *  @param title   地理位置描述
 *  @return 位置实例对象
 */
- (instancetype)initWithLatitude:(double)latitude
                        longitude:(double)longitude
                            title:(nullable NSString *)title;
@end 

以发送一条位置消息, 经纬度为 (30.27415,120.15515) ,地点名为 address , 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得位置附件对象
NIMLocationObject *object = [[NIMLocationObject alloc] initWithLatitude:120.15515 longitude:30.27415 title:@"address"];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

提示消息发送

提示消息主要用于会话内的通知提醒,消息使用场景例如:进入会话时出现的欢迎消息,或是会话过程中命中敏感词后的提示消息等场景,当然也可以用自定义消息实现,只是相对复杂一些。

提示消息附件内部没有额外的信息字段,提示内容建议放入 NIMMessage 中的 text 字段,额外信息可以存储在 NIMMessageremoteExtlocalExt 字段中。

附件原型:

@interface NIMTipObject : NSObject<NIMMessageObject>
@end

以发送一条提示消息, 文案内容为 welcome , 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
NIMSession *session  = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得文件附件对象
NIMTipObject *object = [[NIMTipObject alloc] init];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
message.text = @"welcome";
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

自定义消息发送

序列化与发送

除了 SDK 预定义的几种消息类型外,若开发者如果想要实现更多的消息类型(如图文消息、红包消息等),不可避免地需要使用自定义消息这种类型。自定义消息附件的原型是 NIMCustomObject。SDK 只负责发送和收取由 NIMCustomObject 中 id attachment 序列化和反序列化后的字节流。

在发送端,SDK 将 encodeAttachment 后得到的字节流发送出去;在接收端,SDK 读取字节流,并通过开发者设置的反序列化对象进行解析。

NIMCustomObject 附件原型:

@interface NIMCustomObject : NSObject<NIMMessageObject>

/**
 *  用户自定义附件
 *  @discussion SDK负责将attachment通过encodeAttachment接口序列化后的结果进行透传
 */
@property(nullable, nonatomic, strong) id<NIMCustomAttachment>  attachment;


/**
 *  注册自定义消息解析器
 *
 *  @param decoder 自定义消息解析器
 *  @disucssion 如果用户使用自定义消息类型,就需要注册自定义消息解析器,负责将透传过来的自定义消息反序列化成上层应用可识别的对象
 */
+ (void)registerCustomDecoder:(id<NIMCustomAttachmentCoding>)decoder;

@end

参数列表

参数 类型 说明
attachment id 用户自定义的附件类封装,需要实现NIMCustomAttachment,在发送的时候讲对象赋值到这个属性。SDK负责将 attachment 通过encodeAttachment 接口序列化后的结果进行透传

下面,以发送一条商品信息(含商品名与链接)消息为例,介绍自定义消息的序列化与发送流程。

// Attachment.h
@interface Attachment : NSObject<NIMCustomAttachment>
// 商品名
@property (nonatomic,copy) NSString *goodsName;
// 商品链接
@property (nonatomic,copy) NSString *goodsURL;
@end

// Attachment.m
@implementation Attachment

// 实现 NIMCustomAttachment 的 encodeAttachment 方法
- (NSString *)encodeAttachment
{
    // 商品信息内容以字典封装
    NSDictionary *dict = @{
                            @"goodsName" :  self.goodsName,
                            @"goodsURL"  :  self.goodsURL,
                          };

    // 进一步序列化得到 content 并返回
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict  options:0  error:nil];
    NSString *content = nil;

    if (data) {
        content = [[NSString alloc] initWithData:data
                                        encoding:NSUTF8StringEncoding];
    }

    return content;
}
@end

此外,NIMCustomAttachment 还提供文件上传下载相关接口,详见API文档。

// 构造出具体会话,以发给用户user为例
NIMSession *session  = [NIMSession session:@"user" type:NIMSessionTypeP2P];

// 构造自定义消息附件
NIMCustomObject *object = [[NIMCustomObject alloc] init];
Attachment *attachment = [[Attachment alloc] init];
object.attachment = attachment;

// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;

// 错误反馈对象
NSError *error = nil;

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

至此,序列化与发送流程已经介绍完毕。

反序列化

从本地数据库中读取自定义消息与接收方收到自定义消息等情况下,都需要经过解析才能获取到自定义消息附件的具体内容。以上例中的商品信息为例,介绍自定义消息的反序列化流程。

// CustomAttachmentDecoder.h
@interface CustomAttachmentDecoder : NSObject<NIMCustomAttachmentCoding>
@end


// CustomAttachmentDecoder.m
@implementation CustomAttachmentDecoder
// 所有的自定义消息都会走这个解码方法,如有多种自定义消息请在该方法中扩展,并自行做好类型判断和版本兼容。
- (id<NIMCustomAttachment>)decodeAttachment:(NSString *)content{
    id<NIMCustomAttachment> attachment;
    NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
    if (data) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        if ([dict isKindOfClass:[NSDictionary class]]) {
            NSString *goodsName = dict[@"goodsName"];
            NSString *goodsURL = dict[@"goodsURL"]; 
            Attachment *myAttachment = [[Attachment alloc] init];
            myAttachment.goodsName = goodsName;
            myAttachment.goodsURL = goodsURL;
            attachment = myAttachment;
        }
    }
    return attachment;
}
@end

- (BOOL)application: didFinishLaunchingWithOptions:中注入解析器:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
// NIM SDK初始化
[NIMCustomObject registerCustomDecoder:[[CustomAttachmentDecoder alloc] init]];
... 
}

接收消息时,需要判断是否是自定义消息,并进一步判断自定义消息类型,然后获取对应的内容:

if (message.messageType == NIMMessageTypeCustom) {

    NIMCustomObject *object = message.messageObject;
    if ([object.attachment isKindOfClass:[Attachment class]]) {
        Attachment *attachment = (Attachment *)object.attachment;

        // 通过 attachment.goodsName 与 attachment.goodsURL 获取到的内容,在UI上做进一步展示。
        ...

        }

    }

消息属性设置

发送消息时可以设置消息配置选项 NIMMessage - NIMMessageSetting,主要用于设定该消息是否存入云端、是否写入漫游等。

/**
 *  消息配置
 */
@interface NIMMessageSetting : NSObject
/**
 *  消息是否存入云端。
 *  @discussion 默认为YES。 
 */
@property (nonatomic,assign)    BOOL        historyEnabled;
/**
 *  消息是否支持漫游
 *  @discussion 默认为YES。 
 */
@property (nonatomic,assign)    BOOL        roamingEnabled;
/**
 *  当发送方在多个客户端同时登录时,其中一端发送一条消息后,客户端是否需要在收消息的回调抛出该条消息。
 *  @discussion 默认为YES。
 */
@property (nonatomic,assign)    BOOL        syncEnabled;
/**
 *  消息是否需要被计入未读计数
 *  @discussion 默认为YES。默认情况下,用户收到的所有消息都会被计入未读。设置这个为NO后,对应的消息被对端接受后将不计入未读消息计数内。
 */
@property (nonatomic,assign)    BOOL        shouldBeCounted;
/**
 *  消息是否需要推送
 *  @discussion 默认为YES。将这个字段设为NO,消息将不再有推送通知。
 */
@property (nonatomic,assign)    BOOL        apnsEnabled;
/**
 *  推送是否需要带前缀(一般为昵称)
 *  @discussion 默认为YES。将这个字段设为NO,推送消息将不带有前缀(xx:)。
 */
@property (nonatomic,assign)    BOOL        apnsWithPrefix;

/**
 *  是否需要抄送
 *  @discussion 默认为YES,即默认会抄送消息给开发者的服务器(如果有配置的话)
 */
@property (nonatomic,assign)    BOOL        routeEnabled;

/**
 *  该消息是否要存离线,若设置为false,将不会存入离线库与云端历史消息库。
 *  @discussion 默认为YES
 */
@property (nonatomic,assign)    BOOL        persistEnable;
@end

文件资源场景

SDK支持对图片、语音、视频与文件等设置对应的存活时间。

原型

@interface NIMSDK : NSObject

/**
*  资源场景配置
*  @discussion nos 预设场景和自定义场景规则
*  可以覆盖设置,如果预设场景不设置,为系统默认设置
*  sceneDict key-value,系统默认预设场景为3种,自定义场景不超过10种
*  key 是场景,nsstring类型;value 是资源存活时间,nsnumber类型,精确到天,0为永久存活
*/
@property (nonatomic,strong)         NSMutableDictionary *sceneDict;
@end

例如,设置为@{@"nim_icon":@0,@"nim_msg":@0,@"nim_system":@0}代表:

头像等用户资料(nim_icon)的 NOS 资源存活时间为 永久。

图片、音频、视频等各类文件(nim_msg)的 NOS 资源存活时间为 永久。

nim_system为SDK内部使用。

sceneDict-key NIMNOSSceneType枚举值
nim_icon NIMNOSSceneTypeAvatar
nim_msg NIMNOSSceneTypeMessage

在各种附件类型消息(图片、语音、视频等)初始化方法中定义,例如:

NIMSession *session = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得图片附件对象,并设置对应的scene为nim_msg
NIMImageObject *imageObject = [[NIMImageObject alloc] initWithImage:image scene:NIMNOSSceneTypeMessage];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = imageObject;
...
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

本地消息插入

当有业务场景需要单纯插入一条消息至本地数据库内,而不发出时,可以使用插入本地消息的方法来实现。

目前支持本地插入的类型为:

@protocol NIMConversationManager <NSObject>
/**
 *  写入消息
 *
 *  @param message 需要更新的消息
 *  @param session 需要更新的会话
 *  @param completion 完成后的回调
 *  @discussion 当保存消息成功之后,会收到 NIMChatManagerDelegate 中的 onRecvMessages: 回调。目前支持消息类型:NIMMessageTypeText,NIMMessageTypeTip,NIMMessageTypeCustom
 */
- (void)saveMessage:(NIMMessage *)message
         forSession:(NIMSession *)session
         completion:(nullable NIMUpdateMessageBlock)completion;
@end

属性列表

参数 类型 说明
message NIMMessage 需要写入的没有被发送的消息,支持类型见上文
session NIMSession 消息所在的会话
completion NIMUpdateMessageBlock 完成后的回调

方法为异步写入,无须开发者在上层单独开线程,直接在当前线程调用即可。

不允许插入已存在的消息。当保存消息成功之后,会收到NIMChatManagerDelegate中的onRecvMessages:回调。

构造NIMMessage消息对象时,可以通过from字段设置消息发送者的accid,通过timestamp字段设置保存消息的时间。

消息更新

消息的部分属性支持在本地更新,目前可更新的字段为本地扩展字段 LocalExt 以及自定义消息的附件对象 NIMCustomObject

原型

@protocol NIMConversationManager <NSObject>
/**
 *  更新本地已存的消息记录
 *
 *  @param message 需要更新的消息
 *  @param session 需要更新的会话
 *  @param completion 完成后的回调
 *  @discussion 为了保证存储消息的完整性,提供给上层调用的消息更新接口只允许更新如下字段:所有消息的本地拓展字段(LocalExt)和自定义消息的消息对象(messageObject)
 */
- (void)updateMessage:(NIMMessage *)message
           forSession:(NIMSession *)session
           completion:(nullable NIMUpdateMessageBlock)completion;
@end

属性列表

参数 类型 说明
message NIMMessage 需要被更新的消息,支持的更新属性见上文
session NIMSession 消息所在的会话
completion NIMUpdateMessageBlock 完成后的回调

方法为异步写入,无须开发者在上层单独开线程,直接在当前线程调用即可。

消息取消发送

开发者需要通过 NIMSDK 里的 NIMChatManager 协议进行消息取消发送,只能取消正在发送中的消息(如大文件发送),通常配合异步发送消息接口,接口返回值成功时消息的状态为发送失败状态。

接口原型

@protocol NIMChatManager <NSObject>

/**
 *  取消正在发送的消息
 *
 *  @param message 目标消息
 *
 *  @return 是否调用成功
 */
- (BOOL)cancelSendingMessage:(NIMMessage *)message;

@end
参数 类型 说明
message NIMMessage 正在发送中的消息

消息重发

如网络原因导致的发送消息失败时,可以调用重发消息的接口重试发送。

原型

@protocol NIMChatManager <NSObject>
/**
 *  更新本地已存的消息记录
 *
 *  @param message 需要重发的消息
 *  @param error 
 * 
 *  @return 发送完成后的回调,这里的回调完成只表示当前这个函数调用完成,需要后续的发送消息完成回调 – sendMessage:didCompleteWithError: 才能判断消息是否已经发送至服务器
 */
- - (BOOL)resendMessage:(NIMMessage *)message 
                  error:(NSError *__nullable *)error
@end

消息转发

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

@protocol NIMChatManager <NSObject>
/**
 *  转发消息至其他联系人
 *
 *  @param message 需要转发的消息
 *  @param session 会话
 *  @param error 发送完成后的回调,这里的回调完成只表示当前这个函数调用完成,需要后续的发送消息完成回 调 – sendMessage:didCompleteWithError: 才能判断消息是否已经发送至服务器
 */
- (BOOL)forwardMessage:(NIMMessage *)message
             toSession:(NIMSession *)session
                 error:(NSError **)error
@end
参数 类型 说明
message NIMMessage 需要转发的消息
session NIMSession 需要转发到的会话
error NSError 出错原因

消息接收

接收到消息会通过 chatManager 的回调函数通知上层:

原型

@protocol NIMChatManagerDelegate <NSObject>
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages
@end

参数列表

参数 类型 说明
messages NSArray 消息集合,集合按时间排序并保证所属同一个会话

通知类消息接收

一些特定场景的行为,云信服务器预置了一些通知消息。通知消息也是一种特定消息,开发者需要解析消息中附带的信息,来获取通知内容。如最常见的通知消息是群通知事件,如有新成员进群,则群内已有成员将收到此通知消息。目前不支持从客户端发出通知消息。

附件原型:

@interface NIMNotificationObject : NSObject<NIMMessageObject>
/**
 *  通知内容
 */
@property (nonatomic,strong,readonly) NIMNotificationContent  *content;

/**
 *  通知类型
 */
@property (nonatomic,assign,readonly) NIMNotificationType notificationType;
@end

参数列表

参数 类型 说明
content NIMNotificationContent 通知内容
notificationType NIMNotificationType 通知类型,通知类型会随着 SDK 版本升级扩展,开发者需要考虑升级所带来的兼容问题

通知消息需要进行解析,具体步骤为:

所有 content 类型如下:

通知类型 NIMNotificationContent
群事件通知 NIMTeamNotificationContent
网络电话通知 NIMNetCallNotificationContent
聊天室通知 NIMChatroomNotificationContent
未被支持类型通知 NIMUnsupportedNotificationContent

针对群事件通知NIMTeamNotificationContent,详情可参见群组通知消息

多媒体类消息接收

多媒体类消息,如语音消息、图片消息、文件消息和视频消息,需要考虑收到消息后下载资源的情况。 针对使用云信上传服务的多媒体类消息:

若要关闭默认策略,自主选择下载时机,可以使用以下方法来完成:

设置NIMSDKConfigfetchAttachmentAutomaticallyAfterReceivingfetchAttachmentAutomaticallyAfterReceivingInChatroomNO

@interface NIMSDKConfig <NSObject>
/**
* 是否在收到消息后自动下载附件 (群聊和单聊)。默认为YES,SDK会在第一次收到消息是直接下载消息附件,上层开发可以根据自己的需要进行设置。
*/
@property (nonatomic, assign) BOOL fetchAttachmentAutomaticallyAfterReceiving

/**
* 是否在收到聊天室消息后自动下载附件,默认为NO。
*/
@property (nonatomic, assign) BOOL fetchAttachmentAutomaticallyAfterReceivingInChatroom
@end                         
@protocol NIMChatManager <NSObject>
- (BOOL)fetchMessageAttachment:(NIMMessage *)message
                         error:(NSError **)error
@end                         

参数列表

参数 类型 说明
message NIMMessage 需要获取附件的消息
error NSError 抛出的错误对象

进行附件的下载,附件的下载过程会通过回调反馈。

@protocol NIMChatManager <NSObject>
- (void)cancelFetchingMessageAttachment:(NIMMessage *)message;
@end

附件包括:图片消息的图片缩略图,视频消息的视频缩略图,音频消息的音频文件,文件消息的文件和自定义消息中的自定义文件。

值得注意的是:

针对使用云信上传服务的图片,视频消息,上述方法下载的是缩略图和封面图片。若需要下载原视频、原图片,可以使用以下方法,传入附件对象的参数url与path来实现原文件的下载。

@protocol NIMResourceManager <NSObject>
/**
* @param urlString 下载的RL
* @param filepath  下载路径
* @param progress  进度Block
* @param completion 完成Block
*/
- (void)download:(NSString *)urlString 
        filepath:(NSString *)filepath 
        progress:(nullable NIMHttpProgressBlock)progress 
      completion:(nullable NIMDownloadCompleteBlock)completion;
@end                         

关于NIMResourceManager的更多方法,请参见客户端API文档。

聊天室接收消息

由于聊天室为消息量较大的场景,在接收消息时,SDK 为了防止过频回调,会在接受到消息包后等待一段时间,然后批量上报收到的消息。

在此同时,由于业务逻辑不一致导致界面处理不同,如果开发者仍然觉得消息插入过频导致界面卡顿,可以考虑在上层做一个待插入的消息池,同时创建专门用来计算排版的子线程。具体逻辑可以参考 Demo 的聊天室消息处理。

消息过滤

SDK提供消息过滤忽略的功能。消息过滤后,SDK将不存储对应的消息,也不会上抛给接收回调,因此应用层不会收到对应的消息。

消息过滤仅对在线消息、离线消息、漫游消息等有效。查询本地和云端历史记录是无法过滤的。

不建议在不要在消息过滤函数或方法中进行耗时操作,否则将导致线程阻塞。

在初始化SDK时,创建一个NIMSDKConfigDelegate对象,实现下列方法,并将此对象赋值给NIMSDKConfig的delegate属性。

文件传输过程管理

SDK提供文件传输管理功能,开发可以通过以下方法来管控文件传输。

@protocol NIMChatManager <NSObject>
/** 
* 消息是否正在传输 (发送/接受附件)
*/
- (BOOL)messageInTransport:(NIMMessage *)message;

/** 
* 传输消息的进度 (发送/接受附件)
*/
- (float)messageTransportProgress:(NIMMessage *)message;
@end
@protocol NIMChatManagerDelegate <NSObject>
/** 
* 上传资源文件成功的回调
*/
- (void)uploadAttachmentSuccess:(NSString *)urlString 
                     forMessage:(NIMMessage *)message;

/** 
* 监听下载进度
* @param progress 下载进度,范围为 0 ~ 1
*/
- (void)fetchMessageAttachment:(NIMMessage *)message
                      progress:(float)progress;

/** 
* 监听下载进度
*/
- (void)fetchMessageAttachment:(NIMMessage *)message 
          didCompleteWithError:(nullable NSError *)error
@end

消息撤回

消息撤回

允许用户撤回一定时间内发送过的消息,客户端可允许撤回时长默认2分钟,可在网易云信控制台配置。

@protocol NIMChatManager <NSObject>
/**
* 撤回消息
*/
- (void)revokeMessage:(NIMMessage *)message
           completion:(NIMRevokeMessageBlock)completion;

/**
* 撤回消息,并触发推送。同时指定推送文案与附加信息apnsPayload,以及撤回通知本身是否计入未读。
*/
- (void)revokeMessage:(NIMMessage *)message
          apnsContent:(nullable NSString *)apnsContent
          apnsPayload:(nullable NSDictionary *)apnsPayload
      shouldBeCounted:(BOOL)should
           completion:(nullable NIMRevokeMessageBlock)completion;
@end
参数 类型 说明
message NIMMessage 需要撤回的消息
apnsContent NSDictionary 推送内容
apnsPayload NSDictionary 推送附加信息
should BOOL 撤回通知本身是否计入未读
completion NIMRevokeMessageBlock 完成回调

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

以下情况消息撤回会失败:

此外,若被撤消息已经通过APNs推送到达客户端,可以通过设置apnsPayload来实现将原通知栏文案替换为apnsContent的效果。具体参见通知栏内容覆盖

监听消息撤回

当对方撤回消息成功时,被撤回方 SDK 会触发回调:

@protocol NIMChatManagerDelegate <NSObject>
- (void)onRecvRevokeMessageNotification: (NIMRevokeMessageNotification *)notification
@end

NIMRevokeMessageNotification属性一览:

属性 含义
notificationType 通知类型,如点对点消息撤回、群聊消息撤回等
fromUserId 撤回动作的执行者
messageFromUserId 被撤回的消息的发送者
session 被撤回消息所属的会话
timestamp 被撤回消息的时间戳
message 被撤回的消息
roaming 该条撤回通知是否属于漫游通知(即之前是否在其他端收到过)
postscript 撤回的附言

SDK 在收到消息撤回后,会先从本地数据库中找到对应消息并进行删除。如果需要在撤回后显示一条对方已撤回的提示 ,开发者可以自行构造一条提醒消息并调用插入本地消息的方法。

当被撤回消息时,支持配置如下属性来重新计算未读数:

@interface NIMSDKConfig : NSObject
/**
* 是否需要将被撤回的消息计入未读计算考虑。默认为 NO。设置成 YES 的情况下,如果被撤回的消息本地还未读,那么当消息发生撤回时,对应会话的未读计数将减 1 以保持最近会话未读数的一致性。
*/
@property (nonatomic,assign) BOOL shouldConsiderRevokedMessageUnreadCount;
@end

已读回执

当发送方需要知道接收方是否已经阅读了自己发送的消息时,需要使用已读回执的功能。

单聊消息已读回执

在会话界面中调用发送已读回执的接口并传入当前会话的最后一条消息,即表示这之前的消息本方都已读。

发送已读回执:

@protocol NIMChatManager <NSObject>
- (void)sendMessageReceipt:(NIMMessageReceipt *)receipt
                completion:(NIMSendMessageReceiptBlock)completion;
@end
参数 类型 说明
receipt NIMMessageReceipt 消息回执
completion NIMSendMessageReceiptBlock 完成回调

监听已读回执:

@protocol NIMChatManagerDelegate <NSObject>
- (void)onRecvMessageReceipts:(NSArray<NIMMessageReceipt *> *)receipts
@end

此外,可以通过 NIMMessage 中的 isRemoteRead 来得知该消息对方是否已读。

群聊消息已读回执

群消息已读回执功能,需要联系商务顾问申请开通后才能使用。同时,使用该功能时需要将群成员控制在100人以内。

@interface NIMMessageSetting : NSObject
/**
 *  其他群成员收到此消息是否需要发送已读回执
 */
@property (nonatomic, assign) BOOL teamReceiptEnabled
@end
@protocol NIMChatManager <NSObject>
- (void)sendTeamMessageReceipts:(NSArray<NIMMessageReceipt*> *)receipts 
                     completion:(nullable NIMSendTeamMessageReceiptsBlock)completion
@end

参数列表

参数 类型 说明
receipt NIMMessageReceipt 消息回执
completion NIMSendTeamMessageReceiptsBlock 完成回调
@protocol NIMChatManagerDelegate <NSObject>
- (void)onRecvMessageReceipts:(NSArray<NIMMessageReceipt *> *)receipts;
@end

参数列表

参数 类型 说明
receipts NSArray * 消息回执数组
@protocol NIMChatManager <NSObject>

/**
 *  刷新群组消息已读、未读数量
 *
 *  @param messages      要查询的消息集合
 *  @discussion          消息已读变化后,会通过 NIMChatManager 的代理 onRecvMessageReceipts: 回调给上层
 *                       刷新的消息必须为群组消息
 */
- (void)refreshTeamMessageReceipts:(NSArray<NIMMessage *> *)messages;

@end

参数列表

参数 类型 说明
message NSArray * 要更新的消息集合

包括已读人数的 id 和 未读人数的 id 列表。需要注意查询详情对象不会跟着回执人数变化而变化,如果要获取最新的详情,必须再次调用此接口。

@protocol NIMChatManagerDelegate <NSObject>

/**
 *  查询群组消息回执详情
 *
 *  @param NIMMessage    要查询的消息
 *  @discussion          详情包括已读人数的 id 列表和未读人数的 id 列表
 *                       查询详情对象不会跟着回执人数变化而变化,如果要获取最新的详情,必须再次调用此接口
 *
 */
- (void)queryMessageReceiptDetail:(NIMMessage *)message
                       completion:(NIMQueryReceiptDetailBlock)completion;

@end                     

参数列表

参数 类型 说明
message NIMMessage 要查询的消息
completion NIMQueryReceiptDetailBlock 查询群组消息回执详情回调

此外,可以通过NIMMessageteamReceiptInfo来获取当前消息的群已读回执信息。

广播消息接收

网易云信支持全员广播消息,广播消息由服务端接口发起,对应用内的所有用户发送一条广播消息。客户端不支持发送, SDK 收到广播之后直接往上层通知,不支持客户端存储。

接口原型

@protocol NIMBroadcastManager <NSObject>

/**
 *  添加广播消息委托
 *
 *  @param delegate 广播通知回调
 */
- (void)addDelegate:(id<NIMBroadcastManagerDelegate>)delegate;

/**
 *  移除广播消息委托
 *
 *  @param delegate 广播通知回调
 */
- (void)removeDelegate:(id<NIMBroadcastManagerDelegate>)delegate;

@end

参数列表

参数 类型 说明
delegate id 广播通知回调对象

回调原型

@protocol NIMBroadcastManagerDelegate <NSObject>

/**
 *  收到广播消息回调
 *
 *  @param broadcastMessage 广播消息
 */

- (void)onReceiveBroadcastMessage:(NIMBroadcastMessage *)broadcastMessage;
@end

参数列表

参数 类型 说明
broadcastMessage NIMBroadcastMessage 广播消息

系统广播 NIMBroadcastMessage 原型

参数列表

参数 类型 说明
broadcastId int64_t 系统广播 id,全局唯一
sender NSString 发起者 id
timestamp NSTimeInterval 时间
content NSString 内容

示例

// 添加监听
- (void)addListener
{
   [[NIMSDK sharedSDK].broadcastManager addDelegate:self];
}

...

// 回调方法
- (void)onReceiveBroadcastMessage:(NIMBroadcastMessage *)broadcastMessage
{
    //do something with broadcast message
}

语音消息处理

针对语音消息,SDK 封装了录制与播放的方法供开发者使用。多媒体管理 NIMMediaManager 提供了音频播放、高清语音录制的功能。需要注意的是 NIM SDK 中的语音播放和录制仅支持 aac 和 amr,如果需要更多格式的支持,APP 需要自己实现,但并不推荐。

播放

播放音频

@protocol NIMMediaManager <NSObject>
/**
 *  播放音频文件
 *
 *  @discussion 开始播放,NIMMediaManagerDelegate中的playAudio:didBeganWithError:回调会被触发,播放完成后, NIMMediaManagerDelegate中的playAudio:didCompletedWithError:回调会被触发
 *  @param filepath 音频文件路径
 */
- (void)play:(NSString *)filepath;
@end
参数 类型 说明
filepath NSString 音频文件路径

其中 filePath 为音频文件的路径。

开始播放音频的回调

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  开始播放音频的回调
 *
 *  @param filePath 音频文件路径
 *  @param error    错误信息
 */
- (void)playAudio:(NSString *)filePath didBeganWithError:(nullable NSError *)error;
@end

音频播放进度更新回调

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  音频播放进度更新回调
 *
 *  @param filePath 音频文件路径
 *  @param value    播放进度 0.0 - 1.0
 */
- (void)playAudio:(NSString *)filePath progress:(float)value;
@end

音频播放完成的回调

当音频播放自然完成时,将走入以下回调:

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  音频播放完成后的回调
 *
 *  @param filePath 音频文件路径
 *  @param error    错误信息
 */
- (void)playAudio:(NSString *)filePath didCompletedWithError:(NSError *)error
@end

参数列表

参数 类型 说明
filepath NSString 音频文件路径
error NSError 错误信息

主动停止音频播放回调

当主动停止音频播放时,将走入以下回调:

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  音频播放完成后的回调
 *
 *  @param filePath 音频文件路径
 *  @param error    错误信息
 */
- (void)stopPlayAudio:(NSString *)filePath didCompletedWithError:(nullable NSError *)error;
@end

判断是否正在播放音频

@protocol NIMMediaManager <NSObject>
/**
 *  是否正在播放音频
 */
- (BOOL)isPlaying
@end

切换音频的输出设备

@protocol NIMMediaManager <NSObject>
/**
 *  切换音频输出设备
 *
 *  @param outputDevice 音频输出设备
 *
 *  @return 是否切换成功
 */
- (BOOL)switchAudioOutputDevice:(NIMAudioOutputDevice)outputDevice
@end

NIMAudioOutputDevice 列表

参数 说明
NIMAudioOutputDeviceReceiver 0 听筒
NIMAudioOutputDeviceSpeaker 1 扬声器

停止播放音频

@protocol NIMMediaManager <NSObject>
/**
 *  停止播放音频
 *
 */
- (void)stopPlay
@end

该操作会触发回调上文音频播放结束的回调。

贴耳传感器监听

@protocol NIMMediaManager <NSObject>
/**
 *  在播放声音的时候,如果手机贴近耳朵,是否需要自动切换成听筒播放
 *
 */
- (void)setNeedProximityMonitor:(BOOL)needProximityMonitor;
@end

录制

录制音频

@protocol NIMMediaManager <NSObject>
/**
 *  开始录制音频
 *  @param type 音频类型,aac或amr。
 *  @param duration 最长录音时间
 *  @discussion 开始录音,NIMMediaManagerDelegate中的recordAudio:didBeganWithError:回调会被触发,录音完成后, NIMMediaManagerDelgate中的recordAudio:didCompletedWithError:回调会被触发
 */
- (void)record:(NIMAudioType)type duration:(NSTimeInterval)duration;
@end

开始录制音频的回调

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  开始录制音频的回调
 *
 *  @param filePath 录制的音频的文件路径
 *  @param error    错误信息
 *  @discussion 如果录音失败,filePath 有可能为 nil
 */
- (void)recordAudio:(NSString *)filePath didBeganWithError:(NSError *)error
@end

录制音频完成后的回调

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

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  录制音频完成后的回调
 *
 *  @param filePath 录制完成的音频文件路径
 *  @param error    错误信息
 */
- (void)recordAudio:(NSString *)filePath didCompletedWithError:(NSError *)error
@end

音频录制进度更新回调

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  音频录制进度更新回调
 *
 *  @param currentTime 当前录制的时间
 */
- (void)recordAudioProgress:(NSTimeInterval)currentTime
@end

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

@protocol NIMMediaManager <NSObject>
/**
 *  录音进度更新间隔。如果值大于0,则会按照相应间隔调用recordAudioProgress:回调,默认值为0.3。
 */
@property (nonatomic, assign) NSTimeInterval recordProgressUpdateTimeInterval
@end

停止录制音频

@protocol NIMMediaManager <NSObject>
/**
 *  停止录制音频
 *
 *  @discussion 停止录音后NIMMediaManagerDelegate中的recordAudio:didCompletedWithError:回调会被触发
 */
- (void)stopRecord
@end

判断是否正在录制音频

@protocol NIMMediaManager <NSObject>
/**
 *  是否正在录音
 *
 */
- (BOOL)isRecording
@end

取消录音

@protocol NIMMediaManager <NSObject>
/**
 *  取消录制音频
 *
 */
- (void)cancelRecord
@end

录音被取消的回调

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  录音被取消的回调
 */
- (void)recordAudioDidCancelled
@end

获取录音分贝

@protocol NIMMediaManager <NSObject>
/**
 *  获取录音峰值分贝
 *
 */
- (float)recordPeakPower
@end
@protocol NIMMediaManager <NSObject>
/**
 *  获取录音平均分贝
 *
 */
- (float)recordAveragePower
@end

来电打断

@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  播放音频开始被打断回调
 */
- (void)playAudioInterruptionBegin

/**
 *  录音开始被打断回调
 */
- (void)recordAudioInterruptionBegin
@end
@protocol NIMMediaManagerDelegate <NSObject>
/**
 *  播放音频结束被打断回调
 */
- (void)playAudioInterruptionEnd

/**
 *  录音结束被打断回调
 */
- (void)recordAudioInterruptionEnd
@end

语音转文字

要使用语音转文字功能,请联系商务顾问申请开通「语音识别」。如果未开通功能的情况下调用接口,将返回403。

语音转文字的原理:

@protocol NIMMediaManager <NSObject>
/**
 *  语音转文字
 *
 */
- (void)transAudioToText:(NIMAudioToTextOption *)option 
                  result:(NIMAudioToTextBlock)result;
@end

其中NIMAudioToTextOption各属性如下:

属性 含义
url 音频URL。目前只支持云信服务器的URL,不支持外链。
filepath 音频本地地址