ZIM SDK supports friend management, allowing users to directly add and delete friends, view their friends list, send friend requests to other users, accept or reject friend requests, view friend request lists, check their friend relationship with other users, and query or modify friend information.
After logging in to the ZIM SDK, users can use the addFriendByUserID API to directly add other users as friends without requiring their consent. This allows users to set friend remarks and attributes for the added user.
Note
You can set up to 5 friend attributes, and the corresponding key values must be k0, k1, k2, k3, and k4. It is recommended that you agree in advance on the actual meanings of each attribute and maintain consistency.
After successfully adding a friend, both users will receive the callback friendListChanged to notify them that they have become friends.
Batch deleting friends
After logging in to the ZIM SDK, users can use the deleteFriendsByUserIDs API to batch delete up to 20 friends in a one-way or two-way deletion manner.
In this example, one-way deletion and two-way deletion are explained.
One-way deletion: If user A deletes user B in a one-way manner, user B is no longer a friend of user A, but not vice versa.
Note
At this time, if user A sends a friend request to user B, user B does not need to agree, and user A can become user B's friend directly.
Two-way deletion: If user A deletes user B in a two-way manner, they are no longer friends with each other.
// Batch deleting friends
// When the type is set to BOTH: Perform a two-way deletion
// When the type is set to SINGLE: Perform a one-way deletion
ZIMFriendDeleteConfig zimFriendDeleteConfig = new ZIMFriendDeleteConfig();
zimFriendDeleteConfig.type = ZIMFriendDeleteType.BOTH;
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("zego");
ZIM.getInstance().deleteFriends(arrayList, zimFriendDeleteConfig, new ZIMFriendsDeletedCallback() {
@Override
public void onFriendsDeletedCallback(ArrayList<ZIMErrorUserInfo> errorUserList, ZIMError zimError) {
// Delete result callback.
}
});
// Batch deleting friends
// When the type is set to BOTH: Perform a two-way deletion
// When the type is set to SINGLE: Perform a one-way deletion
ZIMFriendDeleteConfig zimFriendDeleteConfig = new ZIMFriendDeleteConfig();
zimFriendDeleteConfig.type = ZIMFriendDeleteType.BOTH;
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("zego");
ZIM.getInstance().deleteFriends(arrayList, zimFriendDeleteConfig, new ZIMFriendsDeletedCallback() {
@Override
public void onFriendsDeletedCallback(ArrayList<ZIMErrorUserInfo> errorUserList, ZIMError zimError) {
// Delete result callback.
}
});
dart
// Batch delete friends
// type is both: bilateral deletion
// type is single: unilateral deletion
try{
ZIMFriendDeleteConfig friendDeleteConfig = ZIMFriendDeleteConfig();
friendDeleteConfig.type = ZIMFriendDeleteType.single;
List<String> list = [];
list.add('zego');
ZIMFriendsDeletedResult result = await ZIM.getInstance()!.deleteFriends(list, friendDeleteConfig);
// Handle success logic
} on PlatformException catch (onError){
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
// Batch delete friends
// type is both: bilateral deletion
// type is single: unilateral deletion
try{
ZIMFriendDeleteConfig friendDeleteConfig = ZIMFriendDeleteConfig();
friendDeleteConfig.type = ZIMFriendDeleteType.single;
List<String> list = [];
list.add('zego');
ZIMFriendsDeletedResult result = await ZIM.getInstance()!.deleteFriends(list, friendDeleteConfig);
// Handle success logic
} on PlatformException catch (onError){
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
objective-c
// Batch delete friends
// type is ZIMFriendDeleteTypeBoth: bilateral deletion
// type is ZIMFriendDeleteTypeSingle: unilateral deletion
ZIMFriendDeleteConfig *friendDeleteConfig = [[ZIMFriendDeleteConfig alloc] init];
friendDeleteConfig.type = ZIMFriendDeleteTypeBoth;
[[ZIM getInstance] deleteFriendsByUserIDs:@[@"userID1",@"userID2"] config:friendDeleteConfig callback:^(NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
// Batch delete friends
// type is ZIMFriendDeleteTypeBoth: bilateral deletion
// type is ZIMFriendDeleteTypeSingle: unilateral deletion
ZIMFriendDeleteConfig *friendDeleteConfig = [[ZIMFriendDeleteConfig alloc] init];
friendDeleteConfig.type = ZIMFriendDeleteTypeBoth;
[[ZIM getInstance] deleteFriendsByUserIDs:@[@"userID1",@"userID2"] config:friendDeleteConfig callback:^(NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
objective-c
// Batch delete friends
// type is ZIMFriendDeleteTypeBoth: bilateral deletion
// type is ZIMFriendDeleteTypeSingle: unilateral deletion
ZIMFriendDeleteConfig *friendDeleteConfig = [[ZIMFriendDeleteConfig alloc] init];
friendDeleteConfig.type = ZIMFriendDeleteTypeBoth;
[[ZIM getInstance] deleteFriendsByUserIDs:@[@"userID1",@"userID2"] config:friendDeleteConfig callback:^(NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
// Batch delete friends
// type is ZIMFriendDeleteTypeBoth: bilateral deletion
// type is ZIMFriendDeleteTypeSingle: unilateral deletion
ZIMFriendDeleteConfig *friendDeleteConfig = [[ZIMFriendDeleteConfig alloc] init];
friendDeleteConfig.type = ZIMFriendDeleteTypeBoth;
[[ZIM getInstance] deleteFriendsByUserIDs:@[@"userID1",@"userID2"] config:friendDeleteConfig callback:^(NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
// Batch delete friends
// type is ZIM_FRIEND_DELETE_TYPE_BOTH: delete in both directions
// type is ZIM_FRIEND_DELETE_TYPE_SINGLE: delete in one direction
zim::ZIMFriendDeleteConfig config;
config.type = ZIM_FRIEND_DELETE_TYPE_BOTH;
std::vector<std::string> userIDs;
userIDs.emplace_back("userID1");
zim::ZIM::getInstance()->deleteFriends(userIDs, config, [=](
const std::vector<zim::ZIMErrorUserInfo>& errorUserList, const zim::ZIMError& errorInfo) {
if(errorInfo.code == ZIMErrorCodeSuccess) {
// ......
} else {
// ......
}
});
// Batch delete friends
// type is ZIM_FRIEND_DELETE_TYPE_BOTH: delete in both directions
// type is ZIM_FRIEND_DELETE_TYPE_SINGLE: delete in one direction
zim::ZIMFriendDeleteConfig config;
config.type = ZIM_FRIEND_DELETE_TYPE_BOTH;
std::vector<std::string> userIDs;
userIDs.emplace_back("userID1");
zim::ZIM::getInstance()->deleteFriends(userIDs, config, [=](
const std::vector<zim::ZIMErrorUserInfo>& errorUserList, const zim::ZIMError& errorInfo) {
if(errorInfo.code == ZIMErrorCodeSuccess) {
// ......
} else {
// ......
}
});
After successfully deleting a friend, depending on the deletion type, the related users will receive the callback friendListChanged to notify them that the user is no longer a friend.
Send friend requests
After logging in to the ZIM SDK, users can use the sendFriendApplicationToUserID API to send friend requests to other users and set friend remarks and attributes.
Note
You can set up to 5 friend attributes, and the corresponding key values must be k0, k1, k2, k3, and k4. It is recommended that you agree in advance on the actual meanings of each attribute and maintain consistency.
The target user will receive the friendApplicationListChanged callback, indicating that a user has requested to become friends. The user can choose to accept or reject the request within 7 days.
Note
If you need to adjust the friend application validity period, please contact the ZEGOCLOUD technical support team.
java
// Received friend request list callback
public void onFriendApplicationListChanged(ZIM zim,
ArrayList<ZIMFriendApplicationInfo> friendApplicationInfoList, ZIMFriendApplicationListChangeAction action) {
}
// Received friend request list callback
public void onFriendApplicationListChanged(ZIM zim,
ArrayList<ZIMFriendApplicationInfo> friendApplicationInfoList, ZIMFriendApplicationListChangeAction action) {
}
// Received friend request list callback
zim.on('friendApplicationListChanged', (zim, data) => {
// action as 0 means new application
const { action, applicationList } = data;
});
// Received friend request list callback
zim.on('friendApplicationListChanged', (zim, data) => {
// action as 0 means new application
const { action, applicationList } = data;
});
Accept friend requests
After logging in to ZIM SDK, users can call the acceptFriendApplicationFromUserID API, passing the ID of the user who initiated the request, to accept a friend request.
Both the requesting user and the requested user will not only receive the friendApplicationUpdated to know that the other user has become their friend.
Both the requesting user and the requested user will receive the friendApplicationUpdated callback to know that the application has been rejected.
Query friend list
After logging in to the ZIM SDK, users can use the queryFriendListWithConfig API to retrieve the paginated complete friends list.
The query results are returned through ZIMFriendListQueriedCallback, and the returned friends list is sorted in descending order based on the time of friend relationship creation.
java
// Query Friends List
ZIMFriendListQueryConfig config = new ZIMFriendListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIM.getInstance().queryFriendList(config, new ZIMFriendListQueriedCallback() {
@Override
public void onFriendListQueried(ArrayList<ZIMFriendInfo> friendList, int nextFlag, ZIMError errorInfo) {
}
});
// Query Friends List
ZIMFriendListQueryConfig config = new ZIMFriendListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIM.getInstance().queryFriendList(config, new ZIMFriendListQueriedCallback() {
@Override
public void onFriendListQueried(ArrayList<ZIMFriendInfo> friendList, int nextFlag, ZIMError errorInfo) {
}
});
dart
// Query friend information list
try{
ZIMFriendListQueryConfig config = ZIMFriendListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIMFriendListQueriedResult result = await ZIM.getInstance()!.queryFriendList(config);
// Handle success logic
} on PlatformException catch (onError){
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
// Query friend information list
try{
ZIMFriendListQueryConfig config = ZIMFriendListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIMFriendListQueriedResult result = await ZIM.getInstance()!.queryFriendList(config);
// Handle success logic
} on PlatformException catch (onError){
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
objective-c
// Query the list of friend information
ZIMFriendListQueryConfig *queryConfig = [[ ZIMFriendListQueryConfig alloc] init];
queryConfig.count = 100;
queryConfig.nextFlag = 0;
[[ZIM getInstance] queryFriendListWithConfig:queryConfig callback:^(NSArray<ZIMFriendInfo *> * _Nonnull friendList, unsigned int nextFlag, ZIMError * _Nonnull errorInfo) {
}];
// Query the list of friend information
ZIMFriendListQueryConfig *queryConfig = [[ ZIMFriendListQueryConfig alloc] init];
queryConfig.count = 100;
queryConfig.nextFlag = 0;
[[ZIM getInstance] queryFriendListWithConfig:queryConfig callback:^(NSArray<ZIMFriendInfo *> * _Nonnull friendList, unsigned int nextFlag, ZIMError * _Nonnull errorInfo) {
}];
objective-c
// Query the list of friend information
ZIMFriendListQueryConfig *queryConfig = [[ ZIMFriendListQueryConfig alloc] init];
queryConfig.count = 100;
queryConfig.nextFlag = 0;
[[ZIM getInstance] queryFriendListWithConfig:queryConfig callback:^(NSArray<ZIMFriendInfo *> * _Nonnull friendList, unsigned int nextFlag, ZIMError * _Nonnull errorInfo) {
}];
// Query the list of friend information
ZIMFriendListQueryConfig *queryConfig = [[ ZIMFriendListQueryConfig alloc] init];
queryConfig.count = 100;
queryConfig.nextFlag = 0;
[[ZIM getInstance] queryFriendListWithConfig:queryConfig callback:^(NSArray<ZIMFriendInfo *> * _Nonnull friendList, unsigned int nextFlag, ZIMError * _Nonnull errorInfo) {
}];
// Query friend information list
zim.queryFriendList({ count: 100, nextFlag: 0 } as ZIMFriendListQueryConfig).then(res => {
const { friendList, nextFlag } = res;
});
// Query friend information list
zim.queryFriendList({ count: 100, nextFlag: 0 } as ZIMFriendListQueryConfig).then(res => {
const { friendList, nextFlag } = res;
});
After logging in to the ZIM SDK, users can use the queryFriendApplicationListWithConfig API to retrieve the friend request list and understand the status of each request. The friend request list includes both the requests initiated by the user to other users and the requests initiated by other users to the user.
The query results are returned through ZIMFriendApplicationListQueriedCallback.
java
// Query friend application information list
ZIMFriendApplicationListQueryConfig config = new ZIMFriendApplicationListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIM.getInstance().queryFriendApplicationList(config, new ZIMFriendApplicationListQueriedCallback() {
@Override
public void onFriendApplicationListQueried(ArrayList<ZIMFriendApplicationInfo> applicationList, int nextFlag, ZIMError errorInfo) {
}
});
// Query friend application information list
ZIMFriendApplicationListQueryConfig config = new ZIMFriendApplicationListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIM.getInstance().queryFriendApplicationList(config, new ZIMFriendApplicationListQueriedCallback() {
@Override
public void onFriendApplicationListQueried(ArrayList<ZIMFriendApplicationInfo> applicationList, int nextFlag, ZIMError errorInfo) {
}
});
dart
// Query friend application information list
try {
ZIMFriendApplicationListQueryConfig config = ZIMFriendApplicationListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIMFriendApplicationListQueriedResult result = await ZIM.getInstance()!.queryFriendApplicationList(config);
// Handle success logic
} on PlatformException catch (onError) {
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
// Query friend application information list
try {
ZIMFriendApplicationListQueryConfig config = ZIMFriendApplicationListQueryConfig();
config.count = 3000;
config.nextFlag = 0;
ZIMFriendApplicationListQueriedResult result = await ZIM.getInstance()!.queryFriendApplicationList(config);
// Handle success logic
} on PlatformException catch (onError) {
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
After a successful update, the user can receive the friendInfoUpdated callback to know that the friend's information has been updated.
Update friend attributes
After logging in to the ZIM SDK, users can update friend attributes using the updateFriendAttributes API.
Note
You can set up to 5 friend attributes, and the corresponding key values must be k0, k1, k2, k3, and k4. It is recommended that you agree in advance on the actual meanings of each attribute and maintain consistency.
After logging in to the ZIM SDK, users can update friend attributes using the friendInfoUpdated API.
Check friend relationships
After logging in to the ZIM SDK, users can use the checkFriendsRelationByUserID API to batch check their friend relationships with up to 20 other users.
ZEGOCLOUD allows one-way or two-way check of friendships. In this example, the friendship between users A and B is checked.
One-way check: Only checks whether user B is in the friend list of user A.
Two-way check: Checks whether users A and B are in the friend list of the other.
// Check friend relationships with other users
// When the type is set to BOTH: Perform a two-way check
// When the type is set to SINGLE: Perform a one-way check
ArrayList<String> userIDs = new ArrayList<>();
userIDs.add("zego");
ZIMFriendRelationCheckConfig config = new ZIMFriendRelationCheckConfig();
config.type = ZIMFriendRelationCheckType.BOTH;
ZIM.getInstance().checkFriendsRelation(userIDs, config, new ZIMFriendsRelationCheckedCallback() {
@Override
public void onFriendsChecked(ArrayList<ZIMFriendRelationInfo> relationInfos, ArrayList<ZIMErrorUserInfo> errorUserList, ZIMError errorInfo) {
}
});
// Check friend relationships with other users
// When the type is set to BOTH: Perform a two-way check
// When the type is set to SINGLE: Perform a one-way check
ArrayList<String> userIDs = new ArrayList<>();
userIDs.add("zego");
ZIMFriendRelationCheckConfig config = new ZIMFriendRelationCheckConfig();
config.type = ZIMFriendRelationCheckType.BOTH;
ZIM.getInstance().checkFriendsRelation(userIDs, config, new ZIMFriendsRelationCheckedCallback() {
@Override
public void onFriendsChecked(ArrayList<ZIMFriendRelationInfo> relationInfos, ArrayList<ZIMErrorUserInfo> errorUserList, ZIMError errorInfo) {
}
});
dart
// Check friend relationship with other users
// type is both: bidirectional
// type is single: unidirectional
try {
ZIMFriendAttributesUpdatedResult result = await ZIM.getInstance()!.updateFriendAttributes(
{'k1':'v1','k2':'v2'}, 'zego');
// Handle success logic
} on PlatformException catch (onError) {
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
// Check friend relationship with other users
// type is both: bidirectional
// type is single: unidirectional
try {
ZIMFriendAttributesUpdatedResult result = await ZIM.getInstance()!.updateFriendAttributes(
{'k1':'v1','k2':'v2'}, 'zego');
// Handle success logic
} on PlatformException catch (onError) {
// Handle failure logic
onError.code; // Handle according to the official error code table
onError.message; // Error message
}
objective-c
// Check friend relationship with other users
// type is ZIMFriendRelationCheckTypeBoth: bidirectional
// type is ZIMFriendRelationCheckTypeSingle: unidirectional
ZIMFriendRelationCheckConfig *checkConfig = [[ZIMFriendRelationCheckConfig alloc] init];
checkConfig.type = ZIMFriendRelationCheckTypeSingle;
[[ZIM getInstance] checkFriendsRelationByUserIDs:@[@"userID1",@"userID2"] config:checkConfig callback:^(NSArray<ZIMFriendRelationInfo *> * _Nonnull relationInfos, NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
// Check friend relationship with other users
// type is ZIMFriendRelationCheckTypeBoth: bidirectional
// type is ZIMFriendRelationCheckTypeSingle: unidirectional
ZIMFriendRelationCheckConfig *checkConfig = [[ZIMFriendRelationCheckConfig alloc] init];
checkConfig.type = ZIMFriendRelationCheckTypeSingle;
[[ZIM getInstance] checkFriendsRelationByUserIDs:@[@"userID1",@"userID2"] config:checkConfig callback:^(NSArray<ZIMFriendRelationInfo *> * _Nonnull relationInfos, NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
objective-c
// Check friend relationship with other users
// type is ZIMFriendRelationCheckTypeBoth: bidirectional
// type is ZIMFriendRelationCheckTypeSingle: unidirectional
ZIMFriendRelationCheckConfig *checkConfig = [[ZIMFriendRelationCheckConfig alloc] init];
checkConfig.type = ZIMFriendRelationCheckTypeSingle;
[[ZIM getInstance] checkFriendsRelationByUserIDs:@[@"userID1",@"userID2"] config:checkConfig callback:^(NSArray<ZIMFriendRelationInfo *> * _Nonnull relationInfos, NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
// Check friend relationship with other users
// type is ZIMFriendRelationCheckTypeBoth: bidirectional
// type is ZIMFriendRelationCheckTypeSingle: unidirectional
ZIMFriendRelationCheckConfig *checkConfig = [[ZIMFriendRelationCheckConfig alloc] init];
checkConfig.type = ZIMFriendRelationCheckTypeSingle;
[[ZIM getInstance] checkFriendsRelationByUserIDs:@[@"userID1",@"userID2"] config:checkConfig callback:^(NSArray<ZIMFriendRelationInfo *> * _Nonnull relationInfos, NSArray<ZIMErrorUserInfo *> * _Nonnull errorUserList, ZIMError * _Nonnull errorInfo) {
}];
// Check friend relationship with other users
// type is 0: bidirectional
// type is 1: unidirectional
const config: ZIMFriendRelationCheckConfig = { type: 0 };
zim.checkFriendsRelation(['userID1', 'userID2'], config).then(res => {
const { relationInfos, errorUserList } = res;
})
// Check friend relationship with other users
// type is 0: bidirectional
// type is 1: unidirectional
const config: ZIMFriendRelationCheckConfig = { type: 0 };
zim.checkFriendsRelation(['userID1', 'userID2'], config).then(res => {
const { relationInfos, errorUserList } = res;
})
// Check the friend relationship with other users
// type is ZIM_FRIEND_RELATION_CHECK_TYPE_BOTH: bidirectional
// type is ZIM_FRIEND_RELATION_CHECK_TYPE_SINGLE: unidirectional
std::vector<std::string> userIDs;
userIDs.emplace_back("userID1");
zim::ZIMFriendRelationCheckConfig config;
config.type = ZIM_FRIEND_RELATION_CHECK_TYPE_BOTH;
zim::ZIM::getInstance()->checkFriendsRelation(userIDs, config, [=](
const std::vector<zim::ZIMFriendRelationInfo>& relationInfos,
const std::vector<zim::ZIMErrorUserInfo>& errorUserList, const zim::ZIMError& errorInfo) {
if(errorInfo.code == ZIMErrorCodeSuccess) {
// ......
} else {
// ......
}
});
// Check the friend relationship with other users
// type is ZIM_FRIEND_RELATION_CHECK_TYPE_BOTH: bidirectional
// type is ZIM_FRIEND_RELATION_CHECK_TYPE_SINGLE: unidirectional
std::vector<std::string> userIDs;
userIDs.emplace_back("userID1");
zim::ZIMFriendRelationCheckConfig config;
config.type = ZIM_FRIEND_RELATION_CHECK_TYPE_BOTH;
zim::ZIM::getInstance()->checkFriendsRelation(userIDs, config, [=](
const std::vector<zim::ZIMFriendRelationInfo>& relationInfos,
const std::vector<zim::ZIMErrorUserInfo>& errorUserList, const zim::ZIMError& errorInfo) {
if(errorInfo.code == ZIMErrorCodeSuccess) {
// ......
} else {
// ......
}
});
Batch query friend information
After logging in to the ZIM SDK, users can use the queryFriendsInfoByUserIDs API to batch query information for up to 20 friends.
After logging in to the ZIM SDK, users can use the searchLocalFriendsWithConfig API to search for friends based on their usernames and aliases. Users can provide up to 5 keywords to search for friends who match all the provided keywords.