消息收发


会话和消息

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

原型

@interface NIMSession : NSObject<NSCopying>

/**
 *  会话ID,如果当前session为team,则sessionId为teamId,如果是P2P则为对方帐号
 */
@property (nonatomic,copy,readonly)         NSString *sessionId;

/**
 *  会话类型,当前仅支持P2P,Team和Chatroom
 */
@property (nonatomic,assign,readonly)       NIMSessionType sessionType;


/**
 *  通过id和type构造会话对象
 *
 *  @param sessionId   会话ID
 *  @param sessionType 会话类型
 *
 *  @return 会话对象实例
 */
 + (instancetype)session:(NSString *)sessionId
                   type:(NIMSessionType)sessionType;

@end

属性列表

参数 类型 说明
sessionId NSString 会话的唯一标识, 如果当前 session 为 team 类型, 则 session Id 为team Id ,如果是点对点单聊类型,则为对方帐号
sessionType NIMSessionType 会话的类型,是一个 NSInteger 的枚举,当前仅支持点对点,群聊和聊天室

在使用的时候,不需要去 SDK 获取会话对象,直接根据已有的会话 Id 和 类型构造出即可。

示例:

//p2p
NIMSession *myFriendSession = [NIMSession session:@"friend user id" type:NIMSessionTypeP2P];

//team
NIMSession *teamSession = [NIMSession session:@"team id" type:NIMSessionTypeTeam];

//do something with session

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

原型

@interface NIMMessage : NSObject

/**
 *  消息类型
 */
@property (nonatomic,assign,readonly)       NIMMessageType messageType;

/**
 *  消息来源
 */
@property (nullable,nonatomic,copy)                  NSString *from;

/**
 *  消息所属会话
 */
@property (nullable,nonatomic,copy,readonly)       NIMSession *session;

/**
 *  消息ID,唯一标识
 */
@property (nonatomic,copy,readonly)         NSString *messageId;

/**
 *  消息文本
 *  @discussion 消息中除 NIMMessageTypeText 和 NIMMessageTypeTip 外,其他消息 text 字段都为 nil
 */
@property (nullable,nonatomic,copy)                  NSString *text;

/**
 *  消息附件内容
 */
@property (nullable,nonatomic,strong)                id<NIMMessageObject> messageObject;

/**
 *  消息设置
 *  @discussion 可以通过这个字段制定当前消息的各种设置,如是否需要计入未读,是否需要多端同步等
 */
@property (nullable,nonatomic,strong)                NIMMessageSetting *setting;

/**
 *  消息反垃圾配置
 *  @discussion 目前仅支持易盾,只有接入了易盾才可以设置这个配置
 */
@property (nullable,nonatomic,strong)                NIMAntiSpamOption *antiSpamOption;

/**
 *  消息推送文案,长度限制200字节
 */
@property (nullable,nonatomic,copy)                  NSString *apnsContent;

/**
 *  消息推送Payload
 *  @discussion 可以通过这个字段定义消息推送Payload,支持字段参考苹果技术文档,长度限制 2K
 */
@property (nullable,nonatomic,copy)                NSDictionary *apnsPayload;

/**
 *  指定成员推送选项
 *  @discussion 通过这个选项进行一些更复杂的推送设定,目前只能在群会话中使用
 */
@property (nullable,nonatomic,strong)                NIMMessageApnsMemberOption *apnsMemberOption;

/**
 *  服务器扩展
 *  @discussion 客户端可以设置这个字段,这个字段将在本地存储且发送至对端,上层需要保证 NSDictionary 可以转换为 JSON,长度限制 4K
 */
@property (nullable,nonatomic,copy)                NSDictionary    *remoteExt;

/**
 *  客户端本地扩展
 *  @discussion 客户端可以设置这个字段,这个字段只在本地存储,不会发送至对端,上层需要保证 NSDictionary 可以转换为 JSON
 */
@property (nullable,nonatomic,copy)                NSDictionary    *localExt;

/**
 *  消息拓展字段
 *  @discussion 服务器下发的消息拓展字段,并不在本地做持久化,目前只有聊天室中的消息才有该字段(NIMMessageChatroomExtension)
 */
@property (nullable,nonatomic,strong)                id messageExt;

/**
 *  消息发送时间
 *  @discussion 本地存储消息可以通过修改时间戳来调整其在会话列表中的位置,发完服务器的消息时间戳将被服务器自动修正
 */
@property (nonatomic,assign)                NSTimeInterval timestamp;

/**
 *  消息投递状态 仅针对发送的消息
 */
@property (nonatomic,assign,readonly)       NIMMessageDeliveryState deliveryState;


/**
 *  消息附件下载状态 仅针对收到的消息
 */
@property (nonatomic,assign,readonly)       NIMMessageAttachmentDownloadState attachmentDownloadState;


/**
 *  是否是收到的消息
 *  @discussion 由于有漫游消息的概念,所以自己发出的消息漫游下来后仍旧是"收到的消息",这个字段用于消息出错是时判断需要重发还是重收
 */
@property (nonatomic,assign,readonly)       BOOL isReceivedMsg;

/**
 *  是否是往外发的消息
 *  @discussion 由于能对自己发消息,所以并不是所有来源是自己的消息都是往外发的消息,这个字段用于判断头像排版位置(是左还是右)。
 */
@property (nonatomic,assign,readonly)       BOOL isOutgoingMsg;

/**
 *  消息是否被播放过
 *  @discussion 修改这个属性,后台会自动更新db中对应的数据
 */
@property (nonatomic,assign)                BOOL isPlayed;


/**
 *  消息是否标记为已删除
 *  @discussion 已删除的消息在获取本地消息列表时会被过滤掉,只有根据messageId获取消息的接口可能会返回已删除消息。
 */
@property (nonatomic,assign,readonly)       BOOL isDeleted;


/**
 *  对端是否已读
 *  @discussion 只有当当前消息为 P2P 消息且 isOutgoingMsg 为 YES 时这个字段才有效,需要对端调用过发送已读回执的接口
 */
@property (nonatomic,assign,readonly)       BOOL isRemoteRead;

/**
 *  消息发送者名字
 *  @discussion 当发送者是自己时,这个值可能为空,这个值表示的是发送者当前的昵称,而不是发送消息时的昵称。聊天室消息里,此字段无效。
 */
@property (nullable,nonatomic,copy,readonly)         NSString *senderName;


/**
 *  发送者客户端类型
 */
@property (nonatomic,assign,readonly)   NIMLoginClientType senderClientType;
@end

属性列表

参数 类型 说明
messageType 消息类型 消息的类型枚举,只读。当构造消息的时候,SDK 会根据传入的 messageObject 自动判断并填入消息类型
from 消息的发送者 为发送者 Id 。当发送消息的时候,SDK 会根据当前登录情况自动填写
session 消息的所属会话 为消息发送到对话的 Id 。当发送的是点对点消息时,此 Id 为接受者 Id;当发送的是群或聊天室消息时,此 Id 为群或聊天室 Id 。
messageId 消息 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
机器人消息 NIMRobotObject
自定义消息 NIMCustomObject

消息发送

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

原型

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

属性列表

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

1.文本消息。

以发送一条文本消息 hello 至好友 Id 为 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];

2.图片消息。

附件原型:

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

/**
 *  图片实例对象初始化方法
 *
 *  @param filepath 要发送的图片路径
 *
 *  @return 图片实例对象
 */
- (instancetype)initWithFilepath:(NSString *)filepath;


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


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


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


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

/**
 *  文件展示名
 */
@property (nullable, nonatomic, copy) NSString *displayName;


/**
 *  图片本地路径
 *  @discussion 目前 SDK 没有提供下载大图的方法,但推荐使用这个地址作为图片下载地址,APP 可以使用自己的下载类或者 SDWebImage 做图片的下载和管理
 */
@property (nullable, nonatomic, copy, readonly) NSString *path;

/**
 *  缩略图本地路径
 */
@property (nullable, nonatomic, copy, readonly) NSString *thumbPath;


/**
 *  图片远程路径
 */
@property (nullable, nonatomic, copy, readonly) NSString *url;

/**
    *  缩略图远程路径
    *  @discussion 仅适用于使用云信上传服务进行上传的资源,否则无效。
    */
@property (nullable, nonatomic, copy, readonly) NSString *thumbUrl;

/**
 *  图片尺寸
 */
@property (nonatomic, assign, readonly) CGSize size;

/**
 *  图片选项
 *  @discussion 仅在发送时且通过 initWithImage: 方式初始化才有效
 */
@property (nullable, nonatomic ,strong) NIMImageOption *option;

/**
 *  文件大小
 */
@property (nonatomic, assign, readonly) long long fileLength;

/**
*  图片MD5
*/
@property (nullable,nonatomic, copy, readonly) NSString *md5;

@end

参数列表

参数 类型 说明
path NSString 图片本地路径,目前 SDK 没有提供下载大图的方法,但推荐使用这个地址作为图片下载地址, APP 可以使用自己的下载类或者 SDWebImage 做图片的下载和管理
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

图片消息附件初始化提供三种方式:

以 UIImage 对象初始化

原型

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

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

以图片路径初始化

原型

@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

以图片数据初始化

原型

@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

以发送一条图片消息, 数据被 image 引用, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

以发送一条图片消息, 数据在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

以发送一条图片消息, 数据被 image 引用, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

以发送一条图片消息, 数据在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

以发送一条图片消息, 数据以 NSData 形式 data 引用, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

3.音频消息

附件原型:

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

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

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

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

/**
 *  语音的本地路径
 */
@property (nullable, nonatomic, copy, readonly) NSString *path;

/**
 *  语音的远程路径
 */
@property (nullable, nonatomic, copy, readonly) NSString *url;

/**
 *  语音时长,毫秒为单位
 *  @discussion SDK会根据传入文件信息自动解析出duration,但上层也可以自己设置这个值
 */
@property (nonatomic, assign)  NSInteger duration;

/**
*  音频MD5
*/
@property (nullable,nonatomic, copy, readonly) NSString *md5;

@end

参数列表

参数 类型 说明
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

以语音数据初始化

原型

@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

以发送一条语音消息, 语音保存在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

以发送一条语音消息, 语音数据被 data 引用, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

4.视频消息

附件原型:

@interface NIMVideoObject : NSObject<NIMMessageObject>

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


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

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


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

/**
 *  视频展示名
 */
@property (nullable, nonatomic, copy) NSString *displayName;

/**
 *  视频MD5
 */
@property (nullable, nonatomic, copy, readonly) NSString *md5;

/**
 *  视频的本地路径
 *  @discussion 目前 SDK 并不提供视频下载功能,但是建议 APP 使用这个 path 作为视频的下载地址,以便后期 SDK 提供缓存清理等功能
 */
@property (nullable, nonatomic, copy, readonly) NSString *path;

/**
 *  视频的远程路径
 */
@property (nullable, nonatomic, copy, readonly) NSString *url;

/**
 *  视频封面的远程路径
 *  @discussion 只有是上传到云信服务器上的视频才支持封面地址,否则地址无效
 */
@property (nullable, nonatomic, copy, readonly) NSString *coverUrl;

/**
 *  视频封面的本地路径
 */
@property (nullable, nonatomic, copy, readonly) NSString *coverPath;

/**
 *  封面尺寸
 */
@property (nonatomic, assign, readonly) CGSize coverSize;

/**
 *  视频时长,毫秒为单位
 *  @discussion SDK会根据传入文件信息自动解析出duration,但上层也可以自己设置这个值
 */
@property (nonatomic, assign) NSInteger duration;

/**
 *  文件大小
 */
@property (nonatomic, assign, readonly) long long fileLength;

@end

参数列表

参数 类型 说明
displayName NSString 视频的显示名, 由开发者自行定义,供上层 UI 使用
md5 NSString 根据视频数据生成的 MD5
path NSString 视频的本地路径。目前 SDK 并不提供视频下载功能,但是建议 APP 使用这个 path 作为视频的下载地址,以便后期 SDK 提供缓存清理等功能
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

以数据对象初始化

原型

@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

以发送一条视频消息, 视频保存在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

以发送一条视频消息, 视频数据被 data 引用, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

5.文件消息

附件原型:

@interface NIMFileObject : NSObject<NIMMessageObject>

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


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

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


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


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

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


/**
 *  文件显示名
 */
@property (nullable, nonatomic, copy)  NSString *displayName;

/**
 *  文件的本地路径
 */
@property (nullable ,nonatomic, copy, readonly) NSString *path;

/**
 *  文件的远程路径
 */
@property (nullable,nonatomic, copy, readonly) NSString *url;


/**
 *  文件MD5
 */
@property (nullable,nonatomic, copy, readonly) NSString *md5;

/**
 *  文件大小
 */
@property (nonatomic, assign, readonly) long long fileLength;

@end

参数列表

参数 类型 说明
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

以数据对象初始化

原型

@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

以发送一条文件消息, 文件保存在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

以发送一条视频消息, 视频数据被 data 引用, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

6.位置消息

附件原型:

@interface NIMLocationObject : NSObject<NIMMessageObject>

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

/**
 *  维度
 */
@property (nonatomic, assign, readonly) double latitude;

/**
 *  经度
 */
@property (nonatomic, assign, readonly) double longitude;

/**
 *  标题
 */
@property (nullable, nonatomic, copy, readonly) NSString *title;
@end
参数列表
参数 类型 说明
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];

以发送一条视频消息, 视频数据被 data 引用, 至好友 Id 为 user 的业务场景进行示例:

// 构造出具体会话
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];

7.提示消息

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

提示消息附件内部没有额外的信息字段,提示内容建议放入 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];

8.自定义消息

除了 SDK 预定义的几种消息类型,上层APP开发者如果想要实现更多的消息类型,不可避免需要使用自定义消息这种类型。由于 SDK 并不能预测上层 APP 的应用场景,所以 NIMCustomObject 采取消息透传的方式以提供给上层开发者最大的自由度。

SDK 只负责发送和收取由 NIMCustomObject 中 id attachment 序列化和反序列化后的字节流,在发送端,SDK 获取 encodeAttachment 后得到的字节流发送至对面端;在接收端,SDK 读取字节流,并通过上层 APP 设置的反序列化对象进行解析。

附件原型:

@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 接口序列化后的结果进行透传

文件上传托管:

为了方便 APP 在自定义消息类型中进行文件的上传,SDK 也提供了三个接口文件上传 即只要 APP 实现上传相关的接口,资源的上传就可以由 SDK 自动完成

如需要上传资源需要实现的接口有:

文件下载托管雷同:

如需要下载资源需要实现的接口有:

以发送一条自定义消息, 自定义封装在 MyCustomAttach 中 , 至好友 Id 为 user 的业务场景进行示例,同时需要上传和下载托管,分别为 uploadURLdownloadURL:

// MyCustomAttach.h
@interface MyCustomAttach : NSObject<NIMCustomAttachment>
@property (nonatomic,copy) NSString *filePath;

@property (nonatomic,copy) NSString *uploadURL;
@property (nonatomic,copy) NSString *downloadURL;
@end

// MyCustomAttach.m
@implementation MyCustomAttach

// 实现 NIMCustomAttachment
- (NSString *)encodeAttachment
{
    NSDictionary *dict = @{
                            @"path"      :  self.filePath,
                            @"upload"    :  self.uploadURL,
                            @"download"  :  self.downloadURL,
                            };

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
                                                    options:0
                                                        error:nil];
    return [[NSString alloc] initWithData:jsonData
                                encoding:NSUTF8StringEncoding];
}

// 上传托管
- (BOOL)attachmentNeedsUpload
{
    // 如果没有拿到上传地址,则需要上传
    return self.uploadURL.length == 0;
}

- (NSString *)attachmentPathForUploading
{
    return self.filePath;
}

- (void)updateAttachmentURL:(NSString *)urlString
{
    self.uploadURL = urlString;
}

// 下载托管
- (BOOL)attachmentNeedsDownload
{
    return ![[NSFileManager defaultManager] fileExistsAtPath:self.filePath];
}

- (NSString *)attachmentURLStringForDownloading
{
    return self.downloadURL;
}

- (NSString *)attachmentPathForDownloading
{
    return self.filePath;
}

@end
// 构造出具体会话
NIMSession *session  = [NIMSession session:@"user" type:NIMSessionTypeP2P];
// 获得文件附件对象
MyCustomAttach *attachment = [[MyCustomAttach alloc] init];
NIMCustomObject *object    = [[NIMCustomObject 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];

9.通知消息

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

附件原型:

@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

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

当不需要一些通知时,开发者可以实现 NIMSDKConfig 的委托 delegate,来控制哪些通知需要忽略。具体请参考 初始化 章节

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

10.机器人消息

机器人类型消息分为机器人上行、下行消息,分别表示发送给机器人和机器人下发的消息。客户端构建机器人上行消息并调用发送接口发送机器人消息,在收到机器人下行消息之后通过解析附件中的 response 属性获取机器人具体响应内容。

附件原型:

@interface NIMRobotObject : NSObject<NIMMessageObject>

/**
*  机器人消息附件对象构造方法
* 
*  @param content 机器人识别内容
*
*  @param robotId 机器人 Id
*
*  @discussion content 参数不是用来做 UI 显示的, 显示 (如对话气泡) 请用 message.text 字段
*
*  @return  机器人消息附件对象实例
*/
- (instancetype)initWithRobot:(NSString *)content
                    robotId:(NSString *)robotId;


/**
 *  机器人消息附件对象构造方法
 *
 *  @param robotId  机器人 Id
 *
 *  @param modelId  模块 Id
 *
 *  @param param    模块跳转参数
 *
 *  @return  机器人消息附件对象实例
 */
- (instancetype)initWithRobotId:(NSString *)robotId
                        modelId:(NSString *)modelId
                          param:(NSString *)param;


/**
 *  判断此消息是否是属于机器人回复的消息
 */
@property (nonatomic, assign, readonly) BOOL isFromRobot;

/**
 *  当该消息为用户上行发送给机器人时,此字段为目标机器人 Id,
 *  当该消息为机器人回复的消息时, 此字段为本消息所属机器人 Id
 */
@property (nullable, nonatomic, copy, readonly) NSString *robotId;


/**
 *  机器人回复的消息结果,只在机器人下行消息,此字段有效
 */
@property (nullable, nonatomic, copy, readonly) NSDictionary *response;

/**
 *  机器人回复的消息所属的提问消息 Id ,只在机器人下行消息,此字段有效
 */
@property (nullable, nonatomic, copy, readonly) NSString *responseForMessageId;

@end

参数列表

参数 类型 说明
isFromRobot BOOL 是否是属于机器人回复的消息,用来判断机器人消息的上下行
robotId NSString 当该消息为用户上行发送给机器人时,此字段为目标机器人 Id, 当该消息为机器人回复的消息时, 此字段为本消息所属机器人 Id
response NSDictionary 机器人回复的消息结果,只在机器人下行消息,此字段有效
responseForMessageId NSString 机器人回复的消息所属的提问消息 Id ,只在机器人下行消息,此字段有效

机器人上行消息附件初始化提供两种方式:

通过文本内容与机器人进行对话

原型

@interface NIMRobotObject : NSObject<NIMMessageObject>
/**
 *  机器人消息附件对象构造方法
 * 
 *  @param content 机器人识别内容
 *
 *  @param robotId 机器人 Id
 *
 *  @discussion content 参数不是用来做 UI 显示的, 显示 (如对话气泡) 请用 message.text 字段
 *
 *  @return  机器人消息附件对象实例
 */
- (instancetype)initWithRobot:(NSString *)content
                    robotId:(NSString *)robotId;
@end

通过机器人跳转的模块 Id 初始化

原型

@interface NIMFileObject : NSObject<NIMMessageObject>
/**
 *  机器人消息附件对象构造方法
 *
 *  @param robotId  机器人 Id
 *
 *  @param modelId  模块 Id
 *
 *  @param param    模块跳转参数
 *
 *  @return  机器人消息附件对象实例
 */
- (instancetype)initWithRobotId:(NSString *)robotId
                        modelId:(NSString *)modelId
                        param:(NSString *)param;
@end

以发送一条机器人消息, 对话文本为 hello , 对话机器人 Id 为 robot,到群 Id myTeam 的业务场景进行示例:

// 构造出具体会话
NIMSession *session = [NIMSession session:@"myTeam" type:NIMSessionTypeTeam];
// 获得机器人附件对象
NIMRobotObject *object = [[NIMRobotObject alloc] initWithRobot:@"hello" robotId:@"robot"];
// 构造出具体消息并注入附件
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = object;
// 错误反馈对象
NSError *error = nil;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:&error];

接收消息

收消息过程会通过 chatManager 的回调函数通知上层

原型

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

参数列表

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

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

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

原型

@protocol NIMChatManager <NSObject>
- (BOOL)fetchMessageAttachment:(NIMMessage *)message
                         error:(NSError **)error
@end

参数列表

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

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

下载进度原型

@protocol NIMChatManagerDelegate <NSObject>
- (void)fetchMessageAttachment:(NIMMessage *)message
                      progress:(float)progress
@end

参数列表

参数 类型 说明
message NIMMessage 正在下载附件的消息
progress float 下载进度,范围为 0 ~ 1

下载完成原型

@protocol NIMChatManagerDelegate <NSObject>
- (void)fetchMessageAttachment:(NIMMessage *)message
          didCompleteWithError:(NSError *)error;
@end

参数列表

参数 类型 说明
message NIMMessage 正在下载附件的消息
error NSError 下载出错原因

下载过程取消下载原型

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

参数列表

参数 类型 说明
message NIMMessage 正在下载附件的消息

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

/**
 *  本地错误码 (IM 和通用) Domain NIMLocalErrorDomain
 */
typedef NS_ENUM(NSInteger, NIMLocalErrorCode) {
/**
     *  主动取消任务
     */
    NIMLocalErrorCodeManualCancelTask = 19,
}

聊天室接收消息

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

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

消息转发

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

@protocol NIMChatManager <NSObject>
- (BOOL)forwardMessage:(NIMMessage *)message
             toSession:(NIMSession *)session
                 error:(NSError **)error
@end
参数 类型 说明
message NIMMessage 需要转发的消息
session NIMSession 需要转发到的会话
error NSError 出错原因

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

已读回执

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

发送已读回执

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

接受已读回执

@protocol NIMChatManagerDelegate <NSObject>
- (void)onRecvMessageReceipt:(NIMMessageReceipt *)receipt;
@end

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

消息撤回

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

@protocol NIMChatManager <NSObject>
- (void)revokeMessage:(NIMMessage *)message
           completion:(NIMRevokeMessageBlock)completion;
@end
参数 类型 说明
message NIMMessage 需要撤回的消息
completion NIMRevokeMessageBlock 完成回调

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

以下情况消息撤回会失败

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

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

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

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

接口原型

@interface NIMSDKConfig : NSObject
@property (nonatomic,assign) BOOL shouldConsiderRevokedMessageUnreadCount;
@end

监听全员广播消息

网易云通信支持全员广播消息,支持离线,没有推送。广播消息由服务端接口发起,对应用内的所有用户发送一条广播。客户端不支持发送, 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 原型

@interface NIMBroadcastMessage : NSObject

/**
 *  系统广播 id,全局唯一
 */
@property (nonatomic,assign,readonly)               int64_t     broadcastId;

/**
 *  发起者 id
 */
@property (nullable,nonatomic,copy,readonly)        NSString    *sender;

/**
 *  时间
 */
@property (nonatomic,assign,readonly)               NSTimeInterval timestamp;

/**
 *  内容
 */
@property (nullable,nonatomic,copy,readonly)         NSString    *content;
@end

参数列表

参数 类型 说明
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 内负责下载并管理这个词库。垃圾词汇命中后支持三种替换规则:

开发者使用该功能步骤如下: 1.于后台配置反垃圾词库,词库格式以及说明见后台相关文档。 2.调用检测接口如下:

*本地反垃圾检测接口

@protocol NIMAntispamManager <NSObject>

/**
 *  本地反垃圾检查器
 *
 *  @param option        本地反垃圾检查选项
 *  @param error         错误提示
 *  @discussion          此扩展不会漫游到其他端,上层需要保证 NSDictionary 可以转换为 JSON。
 *  @return              本地反垃圾检查结果,本地反垃圾列表会在每次登录后同步更新
 *                       因为网络问题,或者没有登录,都会导致本地反垃圾列表无效的情况,error 中会包含具体出错原因
 */
- (NIMLocalAntiSpamCheckResult *)checkLocalAntispam:(NIMLocalAntiSpamCheckOption *)option
                                              error:(NSError **)error;

@end

参数列表

参数 类型 说明
option NIMLocalAntiSpamCheckOption 本地反垃圾选项,这个选项用于反垃圾的本地检查,可以用这个选项进行一些字符串的本地替换操作

这里说明一下返回结果为 NIMLocalAntiSpamCheckResult 类型,具体类型分为如下几种情况。

/**
 * 本地反垃圾检查结果类型
 */
typedef NS_ENUM (NSInteger, NIMLocalAntiSpamOperate){
    /* 本地反垃圾列表不存在 */
    NIMAntiSpamOperateFileNotExists,
    /* 本地替换 */
    NIMAntiSpamResultLocalReplace,
    /* 本地屏蔽 */
    NIMAntiSpamResultLocalForbidden,
    /* 服务器屏蔽 */
    NIMAntiSpamResultServerForbidden,
    /* 没有命中词库,检查通过 */
    NIMAntiSpamResultNotHit,
};
/**
 * 本地反垃圾检查选项
 * @discussion 这个选项用于反垃圾的本地检查,可以用这个选项进行一些字符串的本地替换操作
 */
@interface NIMLocalAntiSpamCheckResult : NSObject

/**
 * 结果类型
 */
@property (nonatomic, assign, readonly)            NIMLocalAntiSpamOperate type;

@end