Skip to main content

Friend Management

This document guides developers on how to use RC IM iOS IMLib SDK to implement friend-related functions such as adding friends, deleting friends, viewing friend lists, and managing friends.

tip

Friend management features are supported starting from version 5.12.0.

Service Activation

The user profile hosting service is enabled by default, allowing you to directly use friend management features.

Friend Event Monitoring

To receive notifications for friend additions/deletions, friend request status changes, complete friend list clearance, and multi-device synchronization of friend information changes, you need to set up a friend event listener delegate after initializing the IMLib SDK but before establishing a connection, and implement the relevant delegate methods of the RCFriendEventDelegate protocol.

You can call addFriendEventDelegate to set up the friend event listener. To stop receiving friend events, call removeFriendEventDelegate to remove the listener.

tip

In the user profile hosting service, SDK notification callbacks triggered by friend operations are considered status notifications. Therefore, regardless of whether your application implements friend event monitoring, the server will synchronize status with the client SDK to ensure local friend relationship status remains up-to-date. These notifications will be counted in message distribution and downstream data statistics.

Sample Code

// Add friend event listener
[[RCCoreClient sharedCoreClient] addFriendEventDelegate:self];

// Remove friend event listener
[[RCCoreClient sharedCoreClient] removeFriendEventDelegate:self];

// -------- Callback Events ----------

// Friend addition callback


- (void)onFriendAdd:(NSString *)userId
name:(NSString *)name
portraitUri:(NSString *)portraitUri
directionType:(RCDirectionType)directionType
operationTime:(long long)operationTime {

}

// Friend deletion callback


- (void)onFriendDelete:(NSArray<NSString *> *)userIds
directionType:(RCDirectionType)directionType
operationTime:(long long)operationTime {

}

// Friend request status change callback


- (void)onFriendApplicationStatusChanged:(NSString *)userId
applicationType:(RCFriendApplicationType)applicationType
applicationStatus:(RCFriendApplicationStatus)status
directionType:(RCDirectionType)directionType
operationTime:(long long)operationTime
extra:(NSString *)extra {

}

// Complete friend list clearance callback (Note: This operation can only be initiated by the server)


- (void)onFriendCleared:(long long)operationTime {

}

// Multi-device synchronization of friend information changes


- (void)onFriendInfoChangedSync:(NSString *)userId
remark:(NSString *)remark
extProfile:(NSDictionary<NSString *,NSString *> *)extProfile
operationTime:(long long)operationTime {

}


## Friend Online Status and Profile Changes

The IMLib SDK automatically handles online status and profile changes between friends.
If you need to receive change notifications, you can call `addSubscribeEventDelegate` to set up a change event listener after SDK initialization but before establishing a connection.

Subscription event changes should be processed according to the [RCSubscribeType] subscription type:


- `RCSubscribeTypeFriendOnlineStatus` represents friend online status.


- `RCSubscribeTypeFriendUserProfile` represents friend profile changes.

:::tip
You must enable "Client-side Friend Profile Change Notifications" and "Client-side Friend Online Status Change Notifications" in the developer console to use this feature and receive real-time notifications about friends' online status and profile changes. These notifications will be counted in one-to-one chat message distribution and downstream data statistics.
:::


#### Sample Code
```objectivec
// Add listener delegate
[[RCCoreClient sharedCoreClient] addSubscribeEventDelegate:self];

// Remove listener delegate
// [[RCCoreClient sharedCoreClient] removeSubscribeEventDelegate:self];

// ---------- Event Callbacks ----------

// Event change callback


- (void)onEventChange:(NSArray<RCSubscribeInfoEvent *> *)subscribeEvents {
// Check RCSubscribeInfoEvent's subscribeType:
// RCSubscribeTypeFriendOnlineStatus for user status subscription events
// RCSubscribeTypeFriendUserProfile for friend profile change events
}

// Subscription data synchronization completed


- (void)onSubscriptionSyncCompleted:(RCSubscribeType)type {
// Use type to distinguish subscription types:
// RCSubscribeTypeFriendOnlineStatus for friend online status
// RCSubscribeTypeFriendUserProfile for friend profile changes
}


## Friend Operations


### Adding Friends

You can call the `addFriend` interface to add a specified user as a friend by their userId. The extra parameter allows you to include additional information with the friend request that will be sent to the recipient.
User userIds can be obtained using RC's [User Search] feature.

:::tip
A user can add up to **3000** friends.
:::


#### Sample Code
```objectivec
// Friend's userId to add
NSString *userId = @"userId1";
// Add as mutual friend (currently only mutual friends are supported)
RCDirectionType directionType = RCDirectionTypeBoth;
// Additional information for the friend request (max 128 characters)
NSString *extra = @"Friend request";
[[RCCoreClient sharedCoreClient] addFriend:userId
directionType:directionType
extra:extra
success:^(RCErrorCode processCode) {
// Friend request successful
if (processCode == RC_SUCCESS) {
// Friend added successfully
} else {
// Waiting for friend approval
}
} error:^(RCErrorCode errorCode) {
// Friend request failed
}];


### Setting Friend Addition Permissions

Use `setFriendAddPermission` to configure the current user's friend addition permissions. If not set, the AppKey's default permissions will apply.


#### Permission Explanation


- The default AppKey permission is **Require User Approval for Friend Addition**.


- User-specific permissions override AppKey defaults. If a user hasn't set permissions, the AppKey defaults will apply.


#### RCFriendAddPermission Enumeration

| **Enum Value** | **Description** |
|--------------|------|
| RCFriendAddPermissionFree | Anyone can add directly |
| RCFriendAddPermissionNeedVerify | Require user approval |
| RCFriendAddPermissionNoOneAllowed | No one can add |


#### Sample Code

```objc
// Set permission to require approval
RCFriendAddPermission permission = RCFriendAddPermissionNeedVerify;

// Set friend addition permission
[[RCCoreClient sharedCoreClient] setFriendAddPermission:permission success:^{
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];


### Retrieving Friend Addition Permissions

Use `getFriendAddPermission` to retrieve the current user's friend addition permissions.


#### Sample Code
```objc
// Get friend addition permission
[[RCCoreClient sharedCoreClient] getFriendAddPermission:^(RCFriendAddPermission permission) {
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];


##### Different permission settings result in two workflows:


###### Scenario 1: No Approval Required for Friend Addition
1. Users A and B call `addFriendEventDelegate` to set up friend event listeners.
2. User B sets their permission to "Anyone can add directly" via `setFriendAddPermission` (see [RCFriendAddPermission]).
3. When User A calls `addFriend` to add B, the success callback's `processCode` returns `RC_SUCCESS` (0), indicating direct friend addition. Both users receive the [onFriendAdd] callback.


###### Scenario 2: Adding Friends Requires Consent
1. Users A and B call `addFriendEventDelegate` to set up friend event listeners.
2. User B sets their permission to "Requires user consent to add friends" via `setFriendAddPermission` (see [RCFriendAddPermission]).
3. When User A calls `addFriend` to add B, the success callback's `processCode` returns `RC_FRIEND_NEED_ACCEPT` (25461), indicating pending approval from User B. Both users receive the [onFriendApplicationStatusChanged] callback (with the `status` parameter as `RCFriendApplicationStatusUnHandled`).
4. After receiving the [onFriendApplicationStatusChanged] callback, User B can choose to accept or reject:
- If User B calls `acceptFriendApplication` to accept, both parties receive the [onFriendAdd] callback, confirming successful friend addition.
- If User B calls `refuseFriendApplication` to reject, both receive [onFriendApplicationStatusChanged] (with `status` as `RCFriendApplicationStatusRefused`).


### Removing Friends

Use `deleteFriends` to remove multiple friend relationships. Successful removal triggers the [onFriendDelete] callback for both parties.

Each call supports removing up to **100** friends.


#### Sample Code
```objectivec
// Friend user ID list
NSArray *userIds = @[@"userId1", @"userId2"];
// Friend type (currently only RCDirectionTypeBoth supported)
RCDirectionType directionType = RCDirectionTypeBoth;

// Remove friends
[[RCCoreClient sharedCoreClient] deleteFriends:userIds directionType:directionType success:^{
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];


### Checking Friend Relationships

Use `checkFriends` to verify friend relationships (currently only bidirectional checks supported).

:::tip
Maximum **20** users per check.
:::


#### Sample Code
```objectivec
// Friend user ID list
NSArray *userIds = @[@"userId1", @"userId2"];
// Friend type (currently only RCDirectionTypeBoth supported)
RCDirectionType directionType = RCDirectionTypeBoth;

// Check relationships
[[RCCoreClient sharedCoreClient] checkFriends:userIds
directionType:directionType
success:^(NSArray<RCFriendRelationInfo *> *friendRelations) {
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];


## Friend Request Operations


### Paginated Friend Request List

Use `getFriendApplications` to view all sent/received friend requests.


- The success callback's `result` returns `-1`, indicating total request count is unavailable.


- Requests expire after 7 days. RC stores data for 7 days maximum—new requests must be sent afterward.


#### Interface Prototype
```objectivec


- (void)getFriendApplications:(RCPagingQueryOption *)option
types:(NSArray<NSNumber *> *)types
status:(NSArray<NSNumber *> *)status
success:(void (^)(RCPagingQueryResult<RCFriendApplicationInfo *> *result))successBlock
error:(void (^)(RCErrorCode errorCode))errorBlock;


#### Parameters
Type: [RCPagingQueryOption]

| **Parameter** | **Type** | **Description** |
| --------------------- |---------------------------|---------------------------|
| pageToken | NSString | Pagination token. For initial fetch, pass nil or @"". If the callback's `result.pageToken` isn't `@""`, use it to fetch next page until `pageToken` becomes `@""` (complete). |
| count | NSInteger | Items per page (max 100). |
| order | BOOL | Sort by request time (default NO = descending, YES = ascending). |


#### Sample Code
```objectivec
// Query options
RCPagingQueryOption *option = [[RCPagingQueryOption alloc] init];
option.count = 20; // Items per page
option.order = NO; // Default: descending by request time
// Request types (example: sent + received)
NSArray<NSNumber *> *types = @[@(RCFriendApplicationTypeSent), @(RCFriendApplicationTypeReceived)];
// Status filter (example: unhandled)
NSArray<NSNumber *> *status = @[@(RCFriendApplicationStatusUnHandled)];

// Fetch requests
[[RCCoreClient sharedCoreClient] getFriendApplications:option
types:types
status:status
success:^(RCPagingQueryResult<RCFriendApplicationInfo *> *result) {
if (result.pageToken.length > 0) {
// Fetch next page
[self getFriendApplications:result.pageToken];
} else {
// Complete
for (RCFriendApplicationInfo *info in result.data) {
if (info.applicationType == RCFriendApplicationTypeSent) {
// Sent request
}
if (info.applicationType == RCFriendApplicationTypeReceived) {
// Received request
}
if (info.applicationStatus == RCFriendApplicationStatusUnHandled) {
// Pending request
}
}
}
} error:^(RCErrorCode errorCode) {
// Failure
}];


### Accepting Friend Requests

Call `acceptFriendApplication` to accept a request. Success triggers [onFriendAdd] for both parties.


#### Sample Code
```objc
NSString *userId = @"userId1"; // Friend's user ID

[[RCCoreClient sharedCoreClient] acceptFriendApplication:userId success:^{
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];


### Rejecting Friend Requests

Call `refuseFriendApplication` to reject a request. Success triggers [onFriendApplicationStatusChanged] (with `status` as `RCFriendApplicationStatusRefused`).


#### Sample Code
```objc
NSString *userId = @"userId1"; // Friend's user ID

[[RCCoreClient sharedCoreClient] refuseFriendApplication:userId success:^{
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];


## Managing Friend Information


### Fetching Friend List

Use `getFriends` to retrieve the current user's friend list.


#### Sample Code
```objc
RCQueryFriendsDirectionType directionType = RCQueryFriendsDirectionTypeBoth; // Currently only bidirectional

[[RCCoreClient sharedCoreClient] getFriends:directionType success:^(NSArray<RCFriendInfo *> *friendInfos) {
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];


You can use `setFriendInfo` to set a friend's alias and extended information.

:::tip


- You must first configure the [Friend Custom Attributes] in the RC Console before using extended information keys. Otherwise, the settings will fail. A maximum of **10** extended information keys can be configured.


- After successfully modifying friend information, other devices logged in by the same user will receive the multi-device callback [onFriendInfoChangedSync] for friend information changes.
:::


#### Sample Code

```objc
// Friend user ID
NSString *userId = @"userId1";
// Alias, up to 64 characters. Pass nil or empty string to clear the alias.
NSString *remark = @"Alias";
// Extended information. To clear, set the value corresponding to the key to an empty string @""
NSDictionary *extProfile = @{@"key1": @"value1", @"key2": @"value2"};

// Set friend information
[[RCCoreClient sharedCoreClient] setFriendInfo:userId
remark:remark
extProfile:extProfile
success:^{
// Success
} error:^(RCErrorCode errorCode, NSArray<NSString *> * _Nullable errorKeys) {
// Failure
// When errorCode == RC_SERVICE_INFORMATION_AUDIT_FAILED, errorKeys returns the attribute names that failed moderation (e.g., remark)
}];


### Get Friend Information by User ID

You can use `getFriendsInfo` to get friend information by user ID.
The API supports querying up to **100** users per call.


#### Sample Code
```objc
// Friend user ID list
NSArray *userIds = @[@"userId1", @"userId2"];

// Get friend information
[[RCCoreClient sharedCoreClient] getFriendsInfo:userIds success:^(NSArray<RCFriendInfo *> *friendInfos) {
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];

Search Friend Information by Nickname

You can use searchFriendsInfo to search for friend information by nickname.

By default, the search first matches the friend's alias remark, then the friend's name name. If either field matches, the search result is returned.

Sample Code

// Nickname keyword, cannot be empty and must not exceed 64 characters
NSString *name = @"name";

// Search friend information
[[RCCoreClient sharedCoreClient] searchFriendsInfo:name success:^(NSArray<RCFriendInfo *> *friendInfos) {
// Success
} error:^(RCErrorCode errorCode) {
// Failure
}];