管理用户属性
管理用户属性
环信即时通讯 IM 自 v3.8.1 开始支持用户属性管理功能。
用户属性指实时消息互动用户的信息,如用户昵称、头像、邮箱、电话、性别、签名、生日等。例如,在招聘场景下,利用用户属性功能可以存储性别、邮箱、用户类型(面试者)、职位类型(web 研发)等。
本文介绍如何设置、更新、获取、监听和订阅用户属性。
提示
为保证用户信息安全,SDK 仅支持用户设置或更新自己的用户属性。
技术原理
环信即时通讯 IM iOS SDK 通过 userInfoManager 类,提供用户属性相关功能。
updateOwnUserInfo设置和修改当前用户自己的属性信息;fetchUserInfoById获取指定用户的所有用户属性信息。subscribeUsersInfo:completion::订阅非好友用户的属性变更事件。unsubscribeUsersInfo:completion::取消订阅非好友用户的属性变更事件。fetchSubscribedUsers:获取已被订阅用户属性变更事件的用户列表。
前提条件
设置用户属性前,请确保满足以下条件:
使用限制
- 单个用户的全部属性最大不超过 2 KB。
- 单个 app 的全部用户属性数据最大不超过 10 GB。
- 调用设置或获取用户属性的相关接口超过频率限制时,会返回错误码
4EXCEED_SERVICE_LIMIT。
设置当前用户的属性
设置当前用户的所有属性
你可以调用 updateOwnUserInfo 设置当前用户的全部属性:
EMUserInfo *userInfo = [[EMUserInfo alloc] init];
userInfo.userId = EMClient.sharedClient.currentUsername;
userInfo.nickname = @"EM";
userInfo.avatarUrl = @"https://www.EM.io";
userInfo.birth = @"2000.10.10";
userInfo.sign = @"hello world";
userInfo.phone = @"12333333333";
userInfo.mail = @"123456@qq.com";
userInfo.gender = 1;
// 异步方法
[EMClient.sharedClient.userInfoManager updateOwnUserInfo:userInfo completion:^(EMUserInfo *aUserInfo, EMError *aError) {
}];
客户端默认使用以下键名存储用户属性。调用 RESTful 接口设置 或 删除用户属性 时,若希望客户端可正常读取,请保持键名一致。
| 字段 | 类型 | 描述 |
|---|---|---|
nickname | String | 用户昵称。长度在 64 字符内。 |
avatarurl | String | 用户头像 URL 地址。长度在 256 字符内。 |
phone | String | 用户联系方式。长度在 32 字符内。 |
mail | String | 用户邮箱。长度在 64 字符内。 |
gender | Int | 用户性别: - 1:男;- 2:女;- (默认) 0:未知;- 设置为其他值无效。 |
sign | String | 用户签名。长度在 256 字符内。 |
birth | String | 用户生日。长度在 64 字符内。 |
ext | String | 扩展字段。 |
设置当前用户的单个属性
你可以调用 updateOwnUserInfo 设置当前用户的单个属性。例如,修改头像:
NSString *url = @"https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/IMDemo/avatar/Image1.png";
[[EMClient sharedClient].userInfoManager updateOwnUserInfo:url withType:EMUserInfoTypeAvatarURL completion:^(EMUserInfo *aUserInfo, EMError *aError) {
if (aUserInfo && completion) {
completion(aUserInfo);
}
}];
获取用户属性
获取用户的所有属性
你可以调用 fetchUserInfoById 从服务端获取一个或多个用户的全部属性。自 v4.20.0 开始,若返回的用户属性更新时间戳大于本地存储的用户属性更新时间戳,SDK 会触发 EMUserInfoManagerDelegate#onUserInfoUpdate 事件。
// 每次传入的用户 ID 数量不能超过 100。
// 异步方法
[[EMClient sharedClient].userInfoManager fetchUserInfoById:@[EMClient.sharedClient.currentUsername] completion:^(NSDictionary *aUserDatas, EMError *aError) {
}];
获取用户的指定属性
你可以调用 fetchUserInfoById 从服务端获取获取指定用户的一个或多个属性。自 v4.20.0 开始,若返回的用户属性更新时间戳大于本地存储的用户属性更新时间戳,SDK 会触发 EMUserInfoManagerDelegate#onUserInfoUpdate 事件。
// 获取指定用户的指定用户属性。
NSArray<NSString *> *userIds = @[@"user1", @"user2"];
NSArray<NSNumber *> *userInfoTypes = @[@(EMUserInfoTypeAvatarURL),@(EMUserInfoTypePhone),@(EMUserInfoTypeMail)];
// 异步方法
[[EMClient sharedClient].userInfoManager fetchUserInfoById:userIds type:userInfoTypes completion:^(NSDictionary *aUserDatas, EMError *aError) {
}];
订阅非好友用户的属性变更
自 v4.22.0 起,SDK 支持订阅非好友用户的属性变更。订阅后,指定非好友用户的属性发生变化时,应用可以及时收到通知。
该功能适用于以下场景:
- 非好友会话中,需要及时更新对方昵称、头像等属性。
- 临时会话、客服沟通等场景中,需要感知非好友用户的属性变更。
- 群成员展示等场景中,需要维护指定非好友用户的最新用户属性。
提示
本功能只适用于非好友用户。关于当前用户、非好友用户和好友相关的用户属性变更通知详情,请参见 用户属性变更事件。
订阅非好友用户属性变更事件
你可以调用 subscribeUsersInfo 订阅非好友用户的用户属性变更事件。订阅成功后,当这些用户的属性发生变更时,SDK 会触发 EMUserInfoManagerDelegate#onUserInfoUpdate 事件。
NSArray<NSString *> *userIds = @[@"user1", @"user2"];
[[EMClient sharedClient].userInfoManager subscribeUsersInfo:userIds completion:^(EMError *error) {
if (!error) {
NSLog(@"订阅非好友用户属性变更成功");
} else {
NSLog(@"订阅非好友用户属性变更失败:%@", error.errorDescription);
}
}];
取消订阅非好友用户属性变更事件
你可以调用 unsubscribeUsersInfo 取消订阅非好友用户的属性变更事件。
NSArray<NSString *> *userIds = @[@"user1", @"user2"];
[[EMClient sharedClient].userInfoManager unsubscribeUsersInfo:userIds completion:^(EMError *error) {
if (!error) {
NSLog(@"取消订阅非好友用户属性变更成功");
} else {
NSLog(@"取消订阅非好友用户属性变更失败:%@", error.errorDescription);
}
}];
获取已被订阅用户属性变更事件的用户列表
你可以调用 fetchSubscribedUsers 获取已被订阅用户属性变更事件的用户列表。该用户列表中包含被订阅的非好友用户的用户 ID 及其用户属性。
[[EMClient sharedClient].userInfoManager fetchSubscribedUsers:^(NSArray<EMUserInfo *> *users, EMError *error) {
if (!error) {
NSLog(@"已订阅用户属性变更的用户列表:%@", users);
} else {
NSLog(@"获取已订阅用户列表失败:%@", error.errorDescription);
}
}];
内存说明
如果未订阅非好友用户的属性变更,应用通常需要在业务需要时主动调用获取接口拉取资料。为减少不必要的网络请求,建议优先复用本地内存中的用户信息,并按业务需要决定是否重新 拉取服务端数据。
监听用户属性变更
本节从当前用户、好友和非好友用户的角度介绍不同场景下的用户属性变更事件。
当前用户
当前用户的属性发生变更时,SDK 会触发 EMUserInfoManagerDelegate#onSelfUserInfoUpdate 事件。
好友用户
- 若主动 从服务端获取用户属性 或 从服务端获取群成员信息,且返回的用户属性更新时间戳大于本地存储的用户属性更新时间戳,SDK 会触发
EMUserInfoManagerDelegate#onUserInfoUpdate事件。 - 若启用了 登录后自动同步好友列表功能,SDK 会在登录完成后自动从服务端拉取并更新本地好友数据。好友属性发生变更时,SDK 会触发
EMContactManagerDelegate#onFriendInfoChanged事件。 - 若启用了 用户信息自动管理功能,且发送方在发送消息时携带了自己的用户信息,则无论发送方与接收方是否为好友关系,当接收方收到该消息,且消息中携带的发送方用户属性更新时间晚于本地缓存时,SDK 会重新拉取该用户属性,并触发
EMUserInfoManagerDelegate#onUserInfoUpdate事件。
非好友用户
- 若启用了 用户信息自动管理功能,且发送方在发送消息时携带了自己的用户信息,则无论发送方与接收方是否为好友关系,当接收方收到该消息,且消息中携带的发送方用户属性更新时间晚于本地缓存时,SDK 会重新拉取该用户属性,并触发
EMUserInfoManagerDelegate#onUserInfoUpdate事件。 - 若已 订阅非好友用户的属性变更事件,则在订阅成功后,当这些用户的属性发生变更时,SDK 会触发 EMUserInfoManagerDelegate#onUserInfoUpdate 事件。
常见问题
- 我设置了用户昵称(
nickname),但调用客户端或 RESTful API 获取用户属性时,未返回用户昵称,原因是什么?
你可以调用客户端 或RESTful API 设置用户昵称,例如 iOS 为 updateOwnUserInfo,然后通过客户端或RESTful API 获取用户属性,例如 iOS 为 fetchUserInfoById。
设置用户昵称时,请注意以下两点:
- 调用 RESTful 接口设置用户昵称时,若要确保在客户端能够获取设置,请求中必须传
nickname键名。 - 调用 RESTful API 获取用户详情和删除用户账户中返回的响应中的
nickname参数表示为推送昵称,即离线推送时在接收方的客户端推送通知栏中显示的发送方的昵称,与用户属性中的用户昵称不同。不过,我们建议这两种昵称的设置保持一致。因此,修改其中一个昵称时,也需调用相应方法对另一个进行更新,确保设置一致。例如,对于 iOS,更推送昵称的方法为 updatePushDisplayName,对于 RESTful API,详见 离线推送通知的显示属性配置。
- 调用设置或获取用户属性的接口时,上报错误码 4 的原因是什么?
设置和获取用户属性的接口,包括设置当前用户的属性、获取单个或多个用户的用户属性和获取指定用户的指定用户属性,超过调用频率限制时,会上报错误码 4 EMErrorExceedServiceLimit。
相关功能
用户头像管理
如果你的应用场景中涉及用户头像管理,还可以参考如下步骤进行操作:
- 开通第三方文件存储服务。详情可以参考文件储存服务商的文档。
- 将头像文件上传至上述第三方文件存储,并获取存储 URL 地址。
- 将该 URL 地址传入用户属性的头像字段(avatarUrl)。
- 显示头像时,通过调用
fetchUserInfoById获取头像 URL,并在本地 UI 中渲染头像。
名片消息
如果你的场景中涉及名片消息,你也可以使用自定义属性功能,并参考如下示例代码实现:
// 设置自定义消息的 `event` 为 `userCard`,并在 `customExt` 中添加展示名片所需要的用户 ID、昵称和头像等字段。
NSDictionary *messageExt = @{@"userId":EMClient.sharedClient.currentUsername,
@"nickname":@"nickname",
@"avatar":@"https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/IMDemo/avatar/Image1.png"
};
EMCustomMessageBody *body = [[EMCustomMessageBody alloc] initWithEvent:@"userCard" customExt:messageExt];
// 异步方法
EMChatMessage *message = [[EMChatMessage alloc] initWithConversationID:@"conversationID"
from:@"sender"
to:@"receiver"
body:body
ext:nil];
// 发送消息
[[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMChatMessage *message, EMError *error) {}];
如果需要在名片中展示更丰富的信息,可以在 customExt 中增加更多字段。
可参考 GitHub 或 Gitee 中示例项目中的以下类:
EMCustomMessageBodyEMChatMessage
用户属性与用户信息
用户信息指用于业务展示的用户相关信息,包括用户属性、好友备注 和 群成员名片。关于用户信息详情,请参见 用户信息自动管理说明。
