本地最近会话

功能概述

会话NIMSession

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

在使用的时候,不需要去 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会自动生成这个消息对应的本地最近会话。但值得注意的是本地最近会话和会话并不是一一对应的关系,删除最近会话并不会影响会话。

本地最近会话在 SDK 中用 NIMRecentSession 表示

/**
 *  最近会话
 */
@interface NIMRecentSession : NSObject

/**
 *  当前会话
 */
@property (nullable,nonatomic,readonly,copy)   NIMSession  *session;

/**
 *  最后一条消息
 */
@property (nullable,nonatomic,readonly,strong)   NIMMessage  *lastMessage;

/**
 *  未读消息数,为保证线程安全,请在主线程中获取
 */
@property (nonatomic,readonly,assign)   NSInteger   unreadCount;

/**
 *  本地扩展
 */
@property (nullable,nonatomic,readonly,copy) NSDictionary *localExt;

@end

属性列表

参数 类型 说明
session NIMSession 表示的当前会话
lastMessage NIMMessage 当前会话的最后一条消息
unreadCount NSInteger 未读消息数,为保证线程安全,请在主线程中获取
localExt NSDictionary 最近会话的本地扩展,修改后,需要调用 NIMConversationManagerProtocolupdateRecentLocalExt:recentSession: 方法,才可以存储到本地

获取最近会话

获取最近会话列表

获取最近会话列表,一般用于首页显示会话列表

原型

@protocol NIMConversationManager <NSObject>
/**
 *  获取所有最近会话
 *  @discussion 只能在主线程调用
 *  @return 最近会话列表
 */
- (nullable NSArray<NIMRecentSession *> *)allRecentSessions;
@end

示例

//  NIMSessionListViewController.m
- (void)viewDidLoad {
    ...
    NSArray *recentSessions = [NIMSDK sharedSDK].conversationManager.allRecentSessions;
    ...
}

为了保证线程安全,这个方法只能在主线程调用,并且由于最近会话在内部是以字典形式存储的,在取出时,会对其进行排序,在数据量过万的情况下会有一定的耗时。

针对最近会话数量过多的情况,从 v7.0.0版本开始,SDK 提供 异步加载完成回调;

@protocol NIMConversationManagerDelegate <NSObject>
/**
*  最近会话数据库读取完成
*
*  @discussion 所有最近会话读取完成。设置NIMSDKConfig中的asyncLoadRecentSessionEnabled属性为YES时,此回调会执行。
*  该回调执行表示最近会话全部加载完毕可以通过allRecentSessions来取全部对话。
*/
- (void)didLoadAllRecentSessionCompletion;
@end

注意:

获取最近会话列表(自定义)

通过该接口获取的最近会话列表与allRecentSessions接口不同,是基于allRecentSessions接口筛选类型之后重新生成的新对象

该对象返回的最近会话均为新对象,最近会话的所有回调都不会返回该接口返回的会话

该接口只针对有特殊需求用户开放,常规用户请使用allRecentSessions接口获取最近会话列表

@protocol NIMConversationManager <NSObject>
/**
 *  获取所有最近会话
 *  @return 最近会话列表
 *  @discussion SDK 以 map 的形式保存 sessions,调用这个方法时将进行排序,数据量较大 (上万) 时会比较耗时。
 *  通过该接口获取的最近会话列表与allRecentSessions接口不同,是基于allRecentSessions接口筛选类型之后重新生成的新对象
 *  需要用户自行在外部管理,所有回调不回回调该接口查询的任何会话
 */
- (nullable NSArray<NIMRecentSession *> *)allRecentSessionsWithOption:(NIMRecentSessionOption *)option;

属性列表

参数 类型 说明
option NIMRecentSessionOption 检索最近会话选项

示例

// 查询所有最近会话,且返回的最近会话最后一条非通知消息
- (void)getAllRecentSessionTests {
    NIMRecentSessionOption *option = [[NIMRecentSessionOption alloc] init];
    option.filterLastMessageTypes = @[@(NIMMessageTypeNotification)];
    NSArray *sessions = [[NIMKit shareKit].conversationManager allRecentSessionsWithOption:option];
}

获取指定的最近会话

v5.9.0版本开始,支持通过会话id获取对应的会话。

@protocol NIMConversationManager <NSObject>
/**
 *  根据当前 session 返回对应的最近会话信息
 */
- (nullable NIMRecentSession *)recentSessionBySession:(NIMSession *)session
@end

创建最近会话

SDK支持创建最近会话:

@protocol NIMConversationManager <NSObject>
/**
 *  根据当前 session 返回对应的最近会话信息
 */
- (void)addEmptyRecentSessionBySession:(NIMSession *)session
@end

更新最近会话

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

原型

@protocol NIMConversationManager <NSObject>
/**
 *  更新最近会话的本地扩展
 *
 *  @param ext           扩展信息
 *  @param recentSession 要更新的最近会话
 *  @discussion          此扩展不会漫游到其他端,上层需要保证 NSDictionary 可以转换为 JSON。
 */
- (void)updateRecentLocalExt:(nullable NSDictionary *)ext
               recentSession:(NIMRecentSession *)recentSession;

@end

属性列表

参数 类型 说明
ext NSDictionary 扩展信息,上层需要保证能将 NSDictionary 转换为 JSON
recentSession NIMRecentSession 要更新的最近会话

示例

// NTESSessionUtil.m
+ (void)addRecentSessionAtMark:(NIMSession *)session
{
    //为会话添加 有人@你 的的标记
    NIMRecentSession *recent = [[NIMSDK sharedSDK].conversationManager recentSessionBySession:session];
    if (recent)
    {
        NSDictionary *localExt = recent.localExt?:@{};
        NSMutableDictionary *dict = [localExt mutableCopy];
        [dict setObject:@(YES) forKey:NTESRecentSessionAtMark];
        [[NIMSDK sharedSDK].conversationManager updateRecentLocalExt:dict recentSession:recent];
    }
}

监听最近会话变更

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

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

@protocol NIMConversationManagerDelegate <NSObject>
/**
 *  增加最近会话的回调
 *
 *  @param recentSession    最近会话
 *  @param totalUnreadCount 目前总未读数
 *  @discussion 当新增一条消息,并且本地不存在该消息所属的会话时,会触发此回调。
 */
- (void)didAddRecentSession:(NIMRecentSession *)recentSession
           totalUnreadCount:(NSInteger)totalUnreadCount;

/**
 *  最近会话修改的回调
 *
 *  @param recentSession    最近会话
 *  @param totalUnreadCount 目前总未读数
 *  @discussion 触发条件包括: 1.当新增一条消息,并且本地存在该消息所属的会话。
 *                          2.所属会话的未读清零。
 *                          3.所属会话的最后一条消息的内容发送变化。(例如成功发送后,修正发送时间为服务器时间)
 *                          4.删除消息,并且删除的消息为当前会话的最后一条消息。
 */
- (void)didUpdateRecentSession:(NIMRecentSession *)recentSession
              totalUnreadCount:(NSInteger)totalUnreadCount;

/**
 *  删除最近会话的回调
 *
 *  @param recentSession    最近会话
 *  @param totalUnreadCount 目前总未读数
 */
- (void)didRemoveRecentSession:(NIMRecentSession *)recentSession
              totalUnreadCount:(NSInteger)totalUnreadCount;

@end

属性列表

参数 类型 说明
recentSession NIMRecentSession 产生变化的最近会话
totalUnreadCount NSInteger 目前总未读数

未读数

获取未读数

针对单个 NIMRecentSession 的未读数,可以通过 NIMRecentSessionunreadCount 属性直接获取。

针对当前所有NIMRecentSession的总未读数,可以通过 NIMConversationManager 获取消息的总未读数。

@protocol NIMConversationManager <NSObject>
/**
 *  获取所有未读数
 *  @discussion 只能在主线程调用
 *  @return 未读数
 */
- (NSInteger)allUnreadCount;
@end

重置未读数

当 SDK 收到消息后,默认消息为未读消息,未读数累加 1 。因为 SDK 是和 UI 完全隔离的,SDK 无法自动感知何时消息已读,故需要上层开发者根据自己的 UI 逻辑,在恰当的时候,手动调用标记已读 接口来告诉 SDK ,从而 SDK 可以进行清除未读数,标记消息状态等之后的维护工作。 相应的最近会话(如果有的话)未读数会自动置 0 并且触发最近消息修改的回调。

请根据需要来对未读数清零,例如当前正在聊天的会话,不需要显示未读数,必须清零。非当前会话,只有当用户希望主动对某个会话或者全部会话进行清零的时候,才调用接口进行操作。

原型

@protocol NIMConversationManager <NSObject>
/**
 *  设置一个会话里所有消息置为已读。如果处于当前会话聊天界面,每次收到消息都需要调用该接口。
 *
 *  @param session 需设置的会话
 *  @discussion 异步方法,消息会标记为设置的状态
 */
- (void)markAllMessagesReadInSession:(NIMSession *)session;
@end

示例

//  NIMSessionViewController.m
- (void)onRecvMessages:(NSArray *)messages
{
    ....
    //会话页直接监听收到消息后的回调,并由于当前页是在会话,直接认为已读
    if ([session isEqual:self.session])
    {
        //只有当消息所属会话时会话页表示的会话时,才标记已读
        [[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session];
    }
    ....
}

此外,还支持设置所有最近会话的消息为已读。

@protocol NIMConversationManager <NSObject>
/**
 *  设置所有会话消息为已读
 *
 *  @param session 需设置的会话
 *  @discussion 异步方法,消息会标记为设置的状态。
 */
- (void)markAllMessagesRead;
@end

删除最近会话

删除最近会话

SDK 支持删除指定的本地最近会话。但会保留会话内的消息。调用时,总未读消息数会减去当前会话的未读数。

@protocol NIMConversationManager <NSObject>
/**
 *  删除某个最近会话
 *
 *  @param recentSession 待删除的最近会话
 *  @discussion 异步方法,删除最近会话,但保留会话内消息
 */
- (void)deleteRecentSession:(NIMRecentSession *)recentSession
@end

删除漫游消息

SDK 支持删除漫游消息,可以通过以下方法实现:

@protocol NIMConversationManager <NSObject>

/**
 *  删除服务器端最近会话
 *
 *  @param sessions   需要删除的会话列表,内部只能是NIMSession
 *  @param completion 完成的回调
 *  @discussion       调用这个接口成功后,当前会话之前的消息都不会漫游到其他端
 */
- (void)deleteRemoteSessions:(NSArray<NIMSession *> *)sessions
                  completion:(nullable NIMRemoveRemoteSessionBlock)completion;

@end

属性列表

参数 类型 说明
sessions NSArray * 需要删除的会话列表,内部只能是NIMSession
completion NIMRemoveRemoteSessionBlock 远端会话删除错误回调