Receiving Messages
You can intercept messages received by the SDK by setting up a message delegate and perform corresponding business operations.
Listening for Message Reception
Applications can set multiple message reception delegates via the addReceiveMessageDelegate method. All received messages will be called back in the delegate method of this RCIMClientReceiveMessageDelegate protocol. It is recommended to register the message listener within the application lifecycle.
[[RCCoreClient sharedCoreClient] addReceiveMessageDelegate:self];
RCIMClientReceiveMessageDelegate can be used to handle receiving real-time messages or offline messages. The protocol provides two delegate methods, and only one of them needs to be implemented to listen for message processing. The SDK will receive all messages including one-to-one chat, group chat, chatroom, and system messages through this method.
The first delegate method provides the nLeft
parameter, which indicates the number of remaining un-received messages. You can optimize your app's experience and performance based on the number of nLeft
, such as waiting for nLeft
to be 0 before refreshing 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 un-received messages, left>=0
@param object The key value set for the message listener
*/
- (void)onReceived:(RCMessage *)message left:(int)nLeft object:(id)object;
When the client successfully connects, the server will send all offline messages? to the client in the form of message packages (Package), with each Package containing up to 200 messages. The client will parse the messages in the Package, push them up one by one, and notify the application. The second delegate method 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 un-received messages, left>=0
@param object The key value set for the message listener
@param offline Whether it is an offline message
@param hasPackage The SDK pulls messages from the server in batches in the form of packages. The existence of a package means that 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 (Package), with each Package containing up to 200 messages. The client will parse the messages in the Package, push them up one by one, and notify the application. nLeft is the number of remaining messages in the currently being parsed message package (Package). |
offline | boolean | Whether the current message is an offline message. |
hasPackage | boolean | Whether there are still undelivered message packages (Package) on the server. |
The following conditions indicate that offline message reception is complete:
hasPackage
isNO
: Indicates that the last package of messages is currently being parsed.nLeft
is 0: Indicates that the last message in the last message package has been received.
Starting from version 5.2.3, the following callback method in RCIMClientReceiveMessageDelegate will be triggered when offline message reception is complete after each successful connection. If there are no offline messages, it will be triggered immediately after the connection is successful.
/*!
Offline message reception completed
*/
- (void)onOfflineMessageSyncCompleted;
The SDK supports removing listeners. To avoid memory leaks, please 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 receivedStatus
of RCMessage to indicate the status of received messages. This property cannot 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 receivedStatusInfo
property, which uses the following attributes to indicate the status of received messages.
Status | Description |
---|---|
isRead | Whether it has been read. This status value will change to read after being read on the current device or other devices. If the message is read on the current device, this status will change to read. Starting from SDK version 5.6.8, as long as the message is read on other devices, this status value on the current device will also change to read. |
isListened | Whether it has been listened to, only for voice messages. |
isDownloaded | Whether it has been downloaded, only for media messages. |
isRetrieved | Whether the message has been received by other devices that are online simultaneously or logged in previously. As long as other devices receive the message first, this status value will change to received. |
Recommendations for Handling Received Messages
- If the number of received messages is small, it is recommended to refresh the UI when
nLeft == 0
, i.e., refresh in batches. - If the number 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 received). - If the number of received messages is large, you can also consider using the iOS function throttling method, i.e., discard other triggers within a certain time period and execute 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 and refresh once more when the conditions
hasPackage == NO && nLeft == 0
are met.
The following discusses the above solutions based on the size of the number of messages.
-
Small number of messages: Assume that the remote server has 200 messages to receive, and the total reception process takes 0.1 seconds.
- Solution 1: The number of UI refreshes is 200/200 = 1 time, i.e., refreshed 1 time within 0.1 seconds.
- Solution 2: The number of UI refreshes is 1 time, regardless of the number of messages, only refresh once, i.e., refreshed 1 time within 0.1 seconds.
- Solution 3: Assume that a fixed refresh of 0.1 seconds is set, then the number of times is 0.1/0.1 + 1 = 2 times, i.e., refreshed 2 times within 0.1 seconds.
-
Large number of messages: Assume that the remote server has 10,000 messages to receive, and the total reception process takes 1 second.
- Solution 1: The number of UI refreshes is 10000/200 = 50 times, i.e., refreshed 50 times within 1 second.
- Solution 2: The number of UI refreshes is 1 time, regardless of the number of messages, only refresh once, i.e., refreshed 1 time within 1 second.
- Solution 3: Assume that a fixed refresh of 0.5 seconds is set, then the number of times is 1/0.5 + 1 = 3 times, i.e., refreshed 3 times within 1 second.
Overall, solutions 1 and 2 are easier to develop, while solution 3 is more difficult. You need to choose the appropriate solution based on the actual situation of the number of received messages.
The above solutions all need to be implemented by yourself.
Disabling Message Deduplication Mechanism
The message deduplication mechanism will automatically remove duplicate messages when the SDK receives one-to-one chat, group chat, system messages, and chatroom messages. When there are a large number of messages locally in the App, the default deduplication mechanism of the SDK may cause message reception stuttering due to performance issues. Therefore, when message reception stuttering occurs, you can try to turn off the SDK's deduplication mechanism.
Why Message Duplication May Occur in Message Reception
This problem may occur when the sender is in a weak network situation. After A sends a message to B, the message successfully reaches the server and is successfully delivered to the receiver B. However, A may not receive the ack returned by the server due to network or other reasons, causing A to think that the message was not sent successfully. At this time, if A resends the message, B will receive a duplicate message (the message content is the same, but the Message UID is different).
Turning Off Message Deduplication
One-to-one chat, group chat, and system messages support turning off message deduplication starting from version 5.3.4. Only available in RCCoreClient
.
Please call after SDK initialization and before establishing an IM connection. Multiple calls will take the last call as the standard.
BOOL enableCheck = NO; // Turn off message deduplication
[[RCCoreClient sharedCoreClient] setCheckDuplicateMessage:enableCheck];
Chatroom messages support turning off message deduplication starting from version 5.8.2. Available in
RCChatRoomClient
.
Please call after SDK initialization and before establishing an IM connection. Multiple calls will take the last call as the standard.
BOOL enableCheck = NO; // Turn off message deduplication
[[RCChatRoomClient sharedChatRoomClient] setCheckChatRoomDuplicateMessage:enableCheck];