logo
In-app Chat
SDK Error Codes
On this page

Render Conversation Messages on the Chat Page


Overview

This article describes how to use the ZIM SDK to render conversation messages on a basic one-on-one chat page.

showMessage.png

Prerequisites

You have already integrated the ZIM SDK into your project and implemented basic message sending and receiving. For details, refer to Quick Start - Implement Basic Message Sending and Receiving.

Message Data Source Overview

The message data sources that need to be rendered on the page mainly include the following:

  1. Historical conversation messages: When you first enter the chat page and view historical messages, you need to query historical conversation messages and render them to the chat interface.
  2. Real-time received messages: Real-time received chat messages need to be rendered to the chat interface.
  3. Local sent messages: Local sent chat messages (including sending, sending successfully, and sending failed statuses) need to be rendered to the chat interface.

Get Message Data and Render to the Chat Interface

As an example of a single chat conversation, when you navigate to the chat page, you need to save the corresponding single chat conversationID (the userID of the other party) and maintain a message list myMessageList for saving the current conversation.

Before obtaining message data, you also need to implement an addMessage utility method to merge message data.

// When there are new messages, update the messages to the message list through this method
- (void)addMessage:(NSArray<ZIMMessage *> *)addList {
    if (!addList || addList.count == 0) return;
    
    NSMutableArray<ZIMMessage *> *mutableList = [self.myMessageList mutableCopy];
    if (!mutableList) {
        mutableList = [NSMutableArray array];
    }
    
    for (ZIMMessage *newMsg in addList) {
        BOOL replaced = NO;
        for (NSInteger i = 0; i < mutableList.count; i++) {
            ZIMMessage *oldMsg = mutableList[i];
            if ((newMsg.messageID && oldMsg.messageID && [newMsg.messageID isEqualToString:oldMsg.messageID]) ||
                (newMsg.localMessageID && oldMsg.localMessageID && [newMsg.localMessageID isEqualToString:oldMsg.localMessageID])) {
                // Replace existing messages
                mutableList[i] = newMsg;
                replaced = YES;
                break;
            }
        }
        if (!replaced) {
            [mutableList addObject:newMsg];
        }
    }
    
    // Sort by orderKey from small to large
    [mutableList sortUsingComparator:^NSComparisonResult(ZIMMessage *msg1, ZIMMessage *msg2) {
        if (msg1.orderKey < msg2.orderKey) return NSOrderedAscending;
        if (msg1.orderKey > msg2.orderKey) return NSOrderedDescending;
        return NSOrderedSame;
    }];
    
    self.myMessageList = [mutableList copy];
}
Note

Each time you call a message-related interface (such as the interfaces shown below), you will get a message list ZIMMessage[]. The obtained message list needs to be merged to obtain a message list without duplicate messages and ordered messages for rendering on the message page. The message sorting rule is to sort by the orderkey property in ZIMMessage (the larger the orderkey, the newer the current message); the de-duplication rule is to determine whether the message object is the same message based on the localMessageID of the message, and replace the new data with the old data when it is duplicated.

Query Historical Messages and Render Them to the Chat Interface

Call the queryHistoryMessageByConversationID interface to query historical messages from new to old (from the most recent message to the oldest message in chronological order) and render them to the chat interface.

ZIMMessageQueryConfig *queryConfig = [[ZIMMessageQueryConfig alloc] init];
queryConfig.count = 20;//
queryConfig.nextMessage = nil;//When the first query is empty, the earliest message in the message list is passed in again when more historical messages are needed
[zim queryHistoryMessageByConversationID:myConversationID 
            conversationType:ZIMConversationTypePeer 
            config:queryConfig 
            callback:callback:^(NSString * _Nonnull conversationID, ZIMConversationType conversationType, NSArray<ZIMMessage *> * _Nonnull messageList, ZIMError * _Nonnull errorInfo){
    [self addMessage:messageList];            
    // update UI
}];

Get Real-time Received Messages and Render Them to the Chat Interface

Listen to the peerMessageReceived interface to get real-time received messages and render them to the chat interface.


- (void)zim:(ZIM *)zim
    peerMessageReceived:(NSArray<ZIMMessage *> *)messageList
                   info:(ZIMMessageReceivedInfo *)info
             fromUserID:(NSString *)fromUserID{
     if(fromUserID != myConversationID){
         return;// Messages from non-current conversations are ignored
     }
     [self addMessage: messageList];
     // update UI
 }

Render Local Sent Messages to the Chat Interface

Listen to the messageSentStatusChanged interface to get the change of the sending status of the local sent message (sending, sending successfully, and sending failed), and render the local sent message and its sending status to the chat interface.

- (void)zim:(ZIM *)zim
    messageSentStatusChanged:
        (NSArray<ZIMMessageSentStatusChangeInfo *> *)messageSentStatusChangeInfoList{
       for(ZIMMessageSentStatusChangeInfo *info in messageSentStatusChangeInfoList){
           if(info.message.conversationID != myConversationID){
               continue;
           }
           [self addMessage:info.message];
       }
       // update UI
}

By following the above steps, you can render historical messages, real-time received messages, and local sent messages (including sending status) in the chat page.

Previous

Subscribe to user online status

Next

Migration solution