Receiving Messages
You can intercept messages received by the SDK by setting up message listeners and perform corresponding business operations.
Listening for Message Reception
Setting Up Message Reception Listeners
You can set up multiple message reception delegates using the addReceiveMessageDelegate method. All received messages will be callbacked through the delegate methods of this RCIMClientReceiveMessageDelegate protocol.
- The timing of delegate setup should occur after initializing the IMLib SDK but before calling the IM connection interface, ensuring offline messages are retrieved immediately after establishing the IM connection with RC's server.
- It is recommended to set the delegate to a singleton object to ensure the delegate remains effective throughout the entire App lifecycle.
[[RCCoreClient sharedCoreClient] addReceiveMessageDelegate:self];
Implementing Message Reception Delegate Methods
RCIMClientReceiveMessageDelegate can be used to handle real-time or offline messages. The protocol provides two delegate methods, and only one needs to be implemented for message processing. The SDK will use this method to receive all types of messages, including one-to-one chats, group chats, chatrooms, and system messages.
Method 1 provides the nLeft parameter, which indicates the number of remaining unreceived messages. You can optimize your App's experience and performance based on the value of nLeft, such as waiting until nLeft is 0 to refresh the UI when receiving a large number of messages.
/*!
Callback method for receiving messages
@param message The currently received message
@param nLeft The number of remaining unreceived messages, left≥0
@param object The key value set for the message listener
*/
- (void)onReceived:(RCMessage *)message left:(int)nLeft object:(id)object;
Method 2 additionally exposes the offline and hasPackage parameters. You can choose the appropriate time to refresh the UI based on nLeft, offline, and hasPackage.
/**
Callback method for receiving messages
@param message The currently received message
@param nLeft The number of remaining unreceived messages, left≥0
@param object The key value set for the message listener
@param offline Whether the message is an offline message
@param hasPackage The SDK pulls messages from the server in batches called packages. The existence of a package means there are still messages on the remote server that have not been pulled by the SDK.
*/
- (void)onReceived:(RCMessage *)message
left:(int)nLeft
object:(id)object
offline:(BOOL)offline
hasPackage:(BOOL)hasPackage;
| Parameter | Type | Description |
|---|---|---|
| message | RCMessage | The received message object. |
| nLeft | int | When the client successfully connects, the server will send all offline messages? to the client in the form of message packages (Packages), with each Package containing up to 200 messages. The client will parse the messages in the Package and notify the app one by one. nLeft indicates the number of remaining messages in the currently parsed message package (Package). |
| offline | boolean | Whether the current message is an offline message. |
| hasPackage | boolean | Whether there are still undelivered message packages (Packages) on the server. |
The following conditions indicate that offline messages have been fully received:
hasPackageisNO: Indicates that the last package of messages is currently being parsed.nLeftis 0: Indicates that the last message in the final message package has been received.
Offline Message Reception Completion Callback
Starting from version 5.2.3, the following callback method in RCIMClientReceiveMessageDelegate will be triggered when offline messages are fully received after each successful connection. If there are no offline messages, it will be triggered immediately after connection.
/*!
Offline message reception completed
*/
- (void)onOfflineMessageSyncCompleted;
The SDK supports removing listeners. To avoid memory leaks, remove the listener when it is no longer needed.
[[RCCoreClient sharedCoreClient] removeReceiveMessageDelegate:self];
Message Reception Status
- Before version 5.6.8, the IMLib SDK used the
receivedStatusproperty of RCMessage to indicate the status of received messages. This property could not properly update the read status of messages in multi-device scenarios and has been deprecated. - Starting from version 5.6.8, the RCMessage class encapsulates the
receivedStatusInfoproperty to represent the status of received messages.
Description of the receivedStatusInfo property:
| Status | Description |
|---|---|
isRead | Whether the message has been read. This status will change to "read" if the message is read on the current device or any other device. If the message is read on the current device, this status will change to "read". Starting from SDK version 5.6.8, if the message is read on any other device, this status on the current device will also change to "read". |
isListened | Whether the message has been listened to, applicable only to voice messages. |
isDownloaded | Whether the message has been downloaded, applicable only to media messages. |
isRetrieved | Whether the message has been received by other devices that are simultaneously online or were previously logged in. If another device receives the message first, this status will change to "received". |
Recommendations for Handling Received Messages
- If the volume of received messages is small, it is recommended to refresh the UI when
nLeft == 0, meaning messages are refreshed in batches. - If the volume of received messages is large, it is recommended to refresh the UI once when
hasPackage == NO && nLeft == 0(i.e., all remote messages have been fully received). - If the volume of received messages is very large, you can also consider using the iOS function throttling (throttle) approach, which involves discarding other triggers within a certain time period and executing only once. The general idea is to start a timer when receiving a large number of messages, refresh at fixed intervals, and close the timer to refresh once more when the conditions
hasPackage == NO && nLeft == 0are met.
The following discusses the above solutions based on two scenarios of message volume.
-
Small Message Volume: Assume the remote server has 200 messages to be received by the client, with a total reception time of 0.1 seconds.
- Solution 1: The number of UI refreshes is 200/200 = 1 time, meaning the UI is refreshed once within 0.1 seconds.
- Solution 2: The number of UI refreshes is 1 time, regardless of the number of messages, meaning the UI is refreshed once within 0.1 seconds.
- Solution 3: Assuming a fixed refresh interval of 0.1 seconds, the number of refreshes is 0.1/0.1 + 1 = 2 times, meaning the UI is refreshed twice within 0.1 seconds.
-
Large Message Volume: Assume the remote server has 10,000 messages to be received by the client, with a total reception time of 1 second.
- Solution 1: The number of UI refreshes is 10000/200 = 50 times, meaning the UI is refreshed 50 times within 1 second.
- Solution 2: The number of UI refreshes is 1 time, regardless of the number of messages, meaning the UI is refreshed once within 1 second.
- Solution 3: Assuming a fixed refresh interval of 0.5 seconds, the number of refreshes is 1/0.5 + 1 = 3 times, meaning the UI is refreshed 3 times within 1 second.
Overall, Solutions 1 and 2 are easier to implement, while Solution 3 is more complex. You need to choose the appropriate solution based on the actual volume of received messages. All solutions require your own implementation.
Disabling Message Deduplication
The message deduplication mechanism automatically removes duplicate messages when the SDK receives one-to-one chats, group chats, system messages, or chatroom messages. When the App has a large number of local messages, the SDK's default deduplication mechanism may cause message reception delays due to performance issues. Therefore, if message reception delays occur, you can try disabling the SDK's deduplication mechanism.
Why Duplicate Messages May Occur During Reception
This issue may occur when the sender is in a weak network condition. For example, when User A sends a message to User B, the message successfully reaches the server and is delivered to the recipient, User B. However, User A may not receive the ack returned by the server due to network issues, causing User A to assume the message was not sent successfully. If User A resends the message, User B will receive a duplicate message (with the same content but a different unique message identifier, MessageUId).
Disabling Message Deduplication
- One-to-one chats, group chats, and system messages support disabling message deduplication starting from version 5.3.4, provided in
RCCoreClient. - Call this after initializing the IMLib SDK but before establishing the IM connection. Multiple calls will take the last one as effective.
BOOL enableCheck = NO; // Disable message deduplication
[[RCCoreClient sharedCoreClient] setCheckDuplicateMessage:enableCheck];
- Chatroom messages support disabling message deduplication starting from version 5.8.2, provided in
RCChatRoomClient. - Call this after initializing the IMLib SDK but before establishing the IM connection. Multiple calls will take the last one as effective.
BOOL enableCheck = NO; // Disable message deduplication
[[RCChatRoomClient sharedChatRoomClient] setCheckChatRoomDuplicateMessage:enableCheck];