跳到主要内容

用户信息

要在 IMKit UI 上展示用户头像、昵称等,需要应用层(App)主动向 IMKit SDK 提供用户信息

IMKit 使用 UserDataService 类统一管理以下数据。App 需要使用 UserDataService 向 IMKit 提供数据,用于在 UI 上展示。

  • 用户信息:包含昵称、头像
  • 群组信息:包含群组名称、群组头像
  • 群成员用户信息:仅支持群用户昵称
提示

用户信息、群组信息、群成员用户信息必须由应用开发者主动从 App 服务端获取,并提供给 SDK。融云不提供 App 用户与群组信息托管服务。融云服务端的用户昵称及头像仅用于推送服务。

本文仅描述了应用层(App)如何使用 IMKit SDK 提供用户信息:

用户信息提供者流程

用户信息、群组信息、群组成员信息流程完全一致,此处以用户信息为例

  1. 展示消息,并检查是否有对应的用户信息
    1. IMKit 在收发消息时,会在会话列表和聊天页面展示消息内容,并展示对应的用户信息,此时 IMKit 检查内部是否缓存的有对应的用户信息
  2. 正常展示头像名称
    1. IMKit 有用户信息就正常展示
  3. 向 App 索要用户信息
    1. IMKit 没有缓存的用户信息,就需要从 App 获取用户信息
    2. IMKit 触发 UserDataProvider.fetchUserInfo
  4. 获取用户信息
    1. App 从 APPServer 获取用户信息
    2. 备注:App 可能会缓存用户信息,例如 App 缓存了通讯录。如果 App 缓存了用户信息,就不需要从 APPServer 获取了
  5. 返回用户信息
    1. APPServer 将用户信息返给 App,App 可以视情况将用户信息缓存
  6. 返回用户信息
    1. App 将用户信息返给 IMKit
    2. App 通过 UserDataProvider.fetchUserInfo 将用户信息 return 给 IMKit
  7. 正常展示头像名称
    1. IMKit 获取用户信息,缓存起来,刷新对应的消息 UI
    2. IMKit 拿到用户信息,内部通过 UserDataListener.onUserInfoChanged 来刷新消息 UI

App 主动刷新用户信息流程

  1. 发现某个用户的信息发生变化
    1. IMKit 将用户信息缓存起来之后,是不会主动更新的,因为 IMKit 不知道在什么时机更新
    2. App 发现某个用户信息发生了变化之后,主动通知 IMKit
  2. 刷新用户信息
    1. App 调用 UserDataService updateUserInfo 刷新 IMKit 的用户信息
  3. 更新对应用户的名称和头像
    1. IMKit 拿到新的用户信息,更新缓存,并更新 UI

从 IMKit 获取用户信息流程

  1. 从 IMKit 获取用户信息
    1. App 可以从 IMKit 获取缓存的用户信息
  2. 检测是否有用户信息
    1. IMKit 检查本地是否有缓存用户信息
  3. 返回用户信息
    1. IMKit 有缓存,直接返回
  4. 向 App 索要用户信息
    1. IMKit 没有缓存,就走用户信息提供者流程

继续走用户信息提供者的流程

刷新用户信息

如果 App 本地持有用户信息数据(例如当前登录用户的昵称和头像),可直接刷新本地缓存和数据库中存储的用户信息(头像与昵称)。刷新后,IMKit UI 会展示最新的用户信息

刷新用户信息必须在 IMKit 已成功建立 IM 连接后操作,否则无法刷新本地数据。可能适用场景如下:

  • App 首次启动,并成功建立 IM 连接以后,可以将自身业务所需的用户信息批量提供给 SDK,由 SDK 写入缓存与本地数据库,供后续使用。
  • 在 IM 建立连接后,如果用户昵称、头像等信息变动,由 App 服务端通知客户端(例如使用消息),客户端调用接口刷新用户信息。
    let userInfo = new UserInfoModel("userId","用户名称","用户头像")
RongIM.getInstance().userDataService().updateUserInfo(userInfo);

如果 App 本地不持有数据,推荐在 IMKit 需要展示数据时动态提供用户信息。

动态提供用户信息

SDK 设计了「用户信息提供者」UserDataProvider 接口类。如果 IMKit 无法从 userDataService 中获取用户信息,将触发 UserDataProvider.fetchUserInfo 回调方法。App 应在该回调中提供 SDK 所需要的用户头像与昵称。

获取用户信息数据后,SDK 会自动设置、刷新用户头像与昵称,以及实现相关 UI 展示。

let userDataProvider: UserDataProvider = {

fetchUserInfo(userId: string): Promise<UserInfoModel> {
// app 拿到用户信息后通过 Promise 返给 IMKit
// App 可以从数据库或者 APPServer 获取用户信息
return new Promise((resolve: Function) => {
let userInfo = new UserInfoModel(userId, "用户名称", "用户头像")
resolve(userInfo);
});
},

fetchGroupInfo(groupId: string): Promise<GroupInfoModel> {
// app 拿到群组信息后通过 Promise 返给 IMKit
// App 可以从数据库或者 APPServer 获取信息
return new Promise((resolve: Function) => {
let info = new GroupInfoModel(groupId, "群组名称", "群组头像")
resolve(info);
});
},

fetchGroupMemberInfo(groupId: string, userId: string): Promise<GroupMemberInfoModel> {
// app 拿到群组成员信息后通过 Promise 返给 IMKit
// App 可以从数据库或者 APPServer 获取信息
return new Promise((resolve: Function) => {
let info = new GroupMemberInfoModel(groupId, userId, "群成员名称", "群成员头像")
resolve(info);
});
},

fetchGroupMemberInfos(groupId: string): Promise<Array<GroupMemberInfoModel>> {
// app 拿到群组所有成员信息后通过 Promise 返给 IMKit
// App 可以从数据库或者 APPServer 获取信息
return new Promise((resolve: Function) => {
let array = new Array<GroupMemberInfoModel>();
for (let i = 0; i < 10; i++) {
let userId = "userId" + i;
let info = new GroupMemberInfoModel(groupId, userId, "群成员名称", "群成员头像")
array.push(info);
}
resolve(array);
});
}

}

RongIM.getInstance().userDataService().setUserDataProvider(userDataProvider);

在 App 的生命周期中,如果 SDK 获取过用户的信息,便会在内存中缓存该信息。允许持久化存储后,SDK 优先从本地数据库中获取用户信息,App 下次启动时数据仍然可用。SDK 在处理对应信息时默认行为如下:

  1. 当 SDK 需要在 UI 上显示用户信息时,首先从内存中查询已获取的数据。
  2. 如果 SDK 可从缓存或本地数据库中查询到所需信息,将直接将数据返回 UI 层并刷新 UI。
  3. 如果 SDK 未能从缓存或本地数据库查询到所需信息,则将触发 UserDataProvider 的回调方法,并尝试从应用层获取信息。收到应用层提供的相应信息后,SDK 将刷新 UI。

获取用户信息

App 可以主动调用 UserDataServicegetUserInfo 方法获取用户信息。SDK 的行为如下:

  1. 首先尝试从本地缓存获取应用层提供的数据。如果在设置用户信息提供者时,已授权 SDK 在本地数据库中存储用户信息,SDK 还会尝试从本地数据库中获取用户信息。
  2. 如果本地没有相关信息的数据,SDK 会触发 UserInfoProviderfetchUserInfo 回调方法。如果您的 App 应用层已在该回调中提供数据,则 SDK 可成功获取用户信息 UserInfoModel
let userInfo = await RongIM.getInstance().userDataService().getUserInfo("userId")