Skip to main content

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;
ParameterTypeDescription
messageRCMessageThe received message object.
nLeftintWhen 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).
offlinebooleanWhether the current message is an offline message.
hasPackagebooleanWhether there are still undelivered message packages (Package) on the server.

The following conditions indicate that offline message reception is complete:

  • hasPackage is NO: 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

tip

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.

StatusDescription
isReadWhether 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.
isListenedWhether it has been listened to, only for voice messages.
isDownloadedWhether it has been downloaded, only for media messages.
isRetrievedWhether 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

  1. If the number of received messages is small, it is recommended to refresh the UI when nLeft == 0, i.e., refresh in batches.
  2. 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).
  3. 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

tip

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];