用户信息
要在Flutter IMKit的UI界面上展示用户头像、昵称等信息,需要应用层(App)主动向IMKit SDK提供用户信息。
在Flutter IMKit中,使用CustomInfoProvider
函数类型来提供用户、群组和会话的信息。应用需要实现此函数,并通过EngineProvider
设置,用于在UI上展示相关信息。
用户信息提供流程
用户信息、群组信息流程完全一致,此处以用户信息为例:
- IMKit在显示消息或会话时,会在界面上展示用户信息,此时IMKit检查是否有相应的用户信息
- 如果有用户信息,IMKit会正常展示头像和名称
- 如果没有用户信息,IMKit会调用开发者提供的
CustomInfoProvider
函数 - App从本地数据库或远程服务器获取用户信息
- 服务器返回用户信息给App
- App将用户信息返回给IMKit
- IMKit使用返回的信息更新UI界面
用户信息数据结构
在Flutter IMKit中,用户信息使用RCKChatProfileInfo
类表示:
Dart
class RCKChatProfileInfo {
final String id; // 用户或群组ID
final String name; // 名称
final String avatar; // 头像URL
final bool isGroup; // 是否为群组
final String extraInfo; // 额外信息
// 构造函数
RCKChatProfileInfo({
required this.id,
required this.name,
required this.avatar,
this.isGroup = false,
this.extraInfo = '',
});
}
CustomInfoProvider
是一个函数类型,定义如下:
Dart
typedef CustomInfoProvider = Future<RCKChatProfileInfo> Function(
{RCIMIWMessage? message,
RCIMIWConversation? conversation});
设置用户信息提供者
在应用初始化时,您需要实现CustomInfoProvider
函数并设置给IMKit,您还需要自行实现用户信息的缓存机制:
Dart
import 'package:rongcloud_im_kit/rongcloud_im_kit.dart';
import 'package:provider/provider.dart';
// 自定义信息提供者实现
Future<RCKChatProfileInfo> customInfoProvider(
{RCIMIWMessage? message, RCIMIWConversation? conversation}) async {
// 确定目标ID
String targetId = '';
bool isGroup = false;
if (message != null) {
// 从消息中获取用户ID
targetId = message.senderUserId ?? '';
} else if (conversation != null) {
// 从会 话中获取目标ID
targetId = conversation.targetId ?? '';
isGroup = conversation.conversationType == RCIMIWConversationType.group;
}
// 从应用服务器或本地数据库获取用户信息
String name = '未知用户';
String avatar = '';
// 示例:从用户信息提供者中获取信息
if (isGroup) {
// 获取群组信息
final groupInfo = await yourGroupInfoProvider.getGroupInfo(targetId);
name = groupInfo?.groupName ?? targetId;
avatar = groupInfo?.groupAvatar ?? '';
} else {
// 获取用户信息
final userInfo = await yourUserInfoProvider.getUserInfo(targetId);
name = userInfo?.nickname ?? targetId;
avatar = userInfo?.portraitUri ?? '';
}
// 返回用户信息
return RCKChatProfileInfo(
id: targetId,
name: name,
avatar: avatar,
isGroup: isGroup,
);
}
// 在应用初始化后设置给IMKit
Provider.of<RCKEngineProvider>(context, listen: false).customInfoProvider = customInfoProvider;
用户信息缓存
这里给您一个缓存示例实现:
Dart
class UserInfoCache {
// 用户信息缓存
final Map<String, UserInfo> _userCache = {};
// 正在获取的用户ID集合,避免重复请求
final Set<String> _fetchingUserIds = {};
// 获取用户信息,如果缓存中没有则异步获取
Future<UserInfo?> getUserInfo(String userId) async {
// 如果缓存中已有数据,直接返回
if (_userCache.containsKey(userId)) {
return _userCache[userId];
}
// 如果正在获取,等待结果
if (_fetchingUserIds.contains(userId)) {
// 等待直到获取完成
while (_fetchingUserIds.contains(userId)) {
await Future.delayed(const Duration(milliseconds: 100));
}
return _userCache[userId];
}
// 标记为正在获取
_fetchingUserIds.add(userId);
try {
// 从服务器获取用户信息
final userInfo = await _fetchUserInfoFromServer(userId);
if (userInfo != null) {
// 添加到缓存
_userCache[userId] = userInfo;
}
return userInfo;
} finally {
// 清除标记
_fetchingUserIds.remove(userId);
}
}
// 从服务器获取用户信息
Future<UserInfo?> _fetchUserInfoFromServer(String userId) async {
// 实现从服务器获取用户信息的逻辑
// ...
}
}
批量获取用户信息
在某些场景下,如群聊消息列表页面,需要一次性获取多个用户的信息。您可以实现批量获取用户信息的方法:
Dart
class UserInfoProvider {
// ... 其他代码
// 批量获取用户信息
Future<Map<String, UserInfo>> batchGetUserInfo(List<String> userIds) async {
// 过滤掉缓存中已有的用户ID
final idsToFetch = userIds.where((id) => !_userCache.containsKey(id)).toList();
if (idsToFetch.isNotEmpty) {
// 批量获取用户信息的API调用
final fetchedInfos = await _apiService.batchGetUserInfo(idsToFetch);
// 更新缓存
for (var info in fetchedInfos) {
_userCache[info.userId] = info;
}
}
// 返回所有请求的用户信息
return Map.fromEntries(
userIds.map((id) => MapEntry(id, _userCache[id]!))
.where((entry) => entry.value != null)
);
}
}
用户信息更新
当用户信息发生变更时(如头像或昵称更新),您需要更新缓存中的用户信息。以下是一个示例实现:
Dart
class UserInfoProvider {
// ... 其他代码
// 更新用户信息
Future<void> updateUserInfo(UserInfo newUserInfo) async {
// 更新缓存
_userCache[newUserInfo.userId] = newUserInfo;
// 通知IMKit更新UI
notifyListeners();
}
}
示例:完整的用户信息提供者
以下是一个完整的用户信息提供者示例:
Dart
class UserInfoProvider with ChangeNotifier {
final Map<String, UserInfo> _userCache = {};
final Map<String, GroupInfo> _groupCache = {};
final ApiService _apiService;
UserInfoProvider(this._apiService);
// 获取用户信息
Future<UserInfo?> getUserInfo(String userId) async {
if (_userCache.containsKey(userId)) {
return _userCache[userId];
}
// 从服务器获取
final userInfo = await _apiService.getUserInfo(userId);
if (userInfo != null) {
_userCache[userId] = userInfo;
notifyListeners();
}
return userInfo;
}
// 获取群组信息
Future<GroupInfo?> getGroupInfo(String groupId) async {
if (_groupCache.containsKey(groupId)) {
return _groupCache[groupId];
}
// 从服务器获取
final groupInfo = await _apiService.getGroupInfo(groupId);
if (groupInfo != null) {
_groupCache[groupId] = groupInfo;
notifyListeners();
}
return groupInfo;
}
// 实现CustomInfoProvider函数
Future<RCKChatProfileInfo> customInfoProvider(
{RCIMIWMessage? message, RCIMIWConversation? conversation}) async {
String targetId = '';
bool isGroup = false;
if (message != null) {
targetId = message.senderUserId ?? '';
} else if (conversation != null) {
targetId = conversation.targetId ?? '';
isGroup = conversation.conversationType == RCIMIWConversationType.group;
}
if (isGroup) {
final groupInfo = await getGroupInfo(targetId);
return RCKChatProfileInfo(
id: targetId,
name: groupInfo?.name ?? targetId,
avatar: groupInfo?.portraitUri ?? '',
isGroup: true,
);
} else {
final userInfo = await getUserInfo(targetId);
return RCKChatProfileInfo(
id: targetId,
name: userInfo?.name ?? targetId,
avatar: userInfo?.portraitUri ?? '',
isGroup: false,
);
}
}
}
通过以上设置,Flutter IMKit将能够获取并显示正确的用户信息,为用户提供良好的聊天体验。