Starter Deal! First 3 month from only  $9.9 /month!
Starter Deal! First 3 month from only  $9.9 /month!
Grab It Now 
Chat
  • Web
    • TUIKit
      • Overview
      • Installaton
        • TUIKit
          • Vue
          • React
        • TUIChat Only
          • Vue
      • Features
        • Reactions
        • Read Receipt
        • Typing Status
        • User Online Status
      • Themes
        • Setting UI Styles
          • Web
          • Mobile
      • Customization
        • Customize Messages
      • Localization
    • SDK
      • Install Chat SDK
      • Initialize Chat SDK
      • Login and Logout
      • Client APIs
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Historical Message
        • Forward Messages
        • Modify a Message
        • Delete Messages
        • Clear History Message
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Targeted Group Message
        • Do not Notify
        • Key-Value Extensions
        • Translation
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
        • Group Counter
      • Community Topic
        • Community Management
      • User Profile and Relationship Chain
        • User Profile
        • User Status
        • Friend Management
        • Friend List
        • Block List
  • Android
    • Run Demo
    • UIKit
      • Overview
      • Getting Started
      • Installation
        • TUIKit
        • TUIChat Only
      • Features
        • Reactions
        • Read Receipt
        • User Online Status
        • Search Messages
      • Customization
        • Customize Messages
        • Customize Emojis and Stickers
      • Localization
    • SDK
      • Install Chat SDK
      • Initialize Chat SDK
      • Login and Logout
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Retrieve Messages
        • Forward Messages
        • Modify a Message
        • Insert a Message
        • Delete Messages
        • Clear History Messages
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Metions
        • Targeted Group Message
        • Do not Notify
        • Key-Value Extensions
        • Reactions
        • Translation
        • Pin Messages
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Draft
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Manage Group
        • Profile
        • Manage Members
        • Member Profile
        • Attribute
        • Counter
      • Community and Topic
        • Manage Community
        • Permission Group
      • User
        • User Profile
        • User Status
        • Manage Friends
        • Friend Group
        • Block Lists
      • Local Search
        • Search Messages
        • Search Friends
        • Search Groups
        • Search Group Members
      • Signaling
      • API Reference
        • Java
  • iOS and macOS
    • Run Demo
    • UIKit
      • Overview
      • Getting Started
      • Installation
        • TUIKit
        • TUIChat Only
      • Features
        • Reactions
        • Read Receipt
        • User Online Status
        • Search Messages
      • Customization
        • Customize Messages
        • Customize Emojis and Stickers
      • Localization
    • SDK
      • Installation
        • iOS
        • macOS
      • Initialize Chat SDK
      • Login and Logout
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Retrieve Messages
        • Forward Messages
        • Modify a Message
        • Insert a Message
        • Delete Messages
        • Clear History Messages
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Metions
        • Targeted Group Messages
        • Do not Notify
        • Key-Value Extensions
        • Reactions
        • Translation
        • Pin Messages
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Draft
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Manage Group
        • Profile
        • Manage Members
        • Member Profile
        • Attribute
        • Counter
      • Community and Topic
        • Manage Community
        • Permission Group
      • User
        • User Profile
        • User Status
        • Manage Friends
        • Friend Group
        • Block Lists
      • Local Search
        • Search Messages
        • Search Friends
        • Search Groups
        • Search Group Members
      • Signaling
      • API Reference
        • Swift
        • Objective-C
  • Windows
    • SDK
      • Install Chat SDK
      • Initialize Chat SDK
      • Login and Logout
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Retrieve Messages
        • Forward Messages
        • Modify a Message
        • Insert a Message
        • Delete Messages
        • Clear History Messages
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Metions
        • Targeted Group Messages
        • Do not Notify
        • Key-Value Extensions
        • Reactions
        • Translation
        • Pin Messages
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Draft
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Manage Group
        • Profile
        • Manage Members
        • Member Profile
        • Attribute
        • Counter
      • Community and Topic
        • Manage Community
        • Permission Group
      • User
        • User Profile
        • User Status
        • Manage Friends
        • Friend Group
        • Block Lists
      • Local Search
        • Search Messages
        • Search Friends
        • Search Groups
        • Search Group Members
      • Signaling
      • API Reference
        • C++
        • C
  • Flutter
    • Run Demo
    • UIKIT
      • Overview
      • Installation
        • integrated
      • Features
        • Local Search
        • Offline Push
        • Online Status
        • Typing Status
        • Message Read Receipt
        • Message Reactions
        • Internationalization
        • Adding Custom Messages
        • Emoji & Stickers
      • Customization
        • Modifying UI Themes
        • Setting UI Styles
    • SDK
      • Install Chat SDK
        • Install
      • Initialize Chat SDK
        • Initialize
      • Login And Logout
        • Login and Logout
      • Message
        • Message Overview
        • Sending Message
        • Receiving Message
        • Historical Message
        • Forwarding Message
        • Modifying Message
        • Message Inserting
        • Deleting Message
        • Clearing Messages
        • Recalling Message
        • Online Message
        • Read Receipt
        • Querying Message
        • Group @ Message
        • Targeted Group Message
        • Notification Muting
        • Message Extension
      • Conversation
        • Conversation Overview
        • Conversation List
        • Getting Conversation
        • Conversation Unread Count
        • Pinning Conversation to the Top
        • Deleting Conversation
        • Conversation Draft
        • Conversation Group
      • Group
        • Group Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
      • User
        • User Profile
        • Friend Management
        • Friend List
        • Blocklist
      • Offline Push
        • Offline Push
      • Signaling
        • Signaling Management
      • Local Search
        • Searching for Message
        • Searching for Friend
        • Searching Group
        • Searching for Group Member
      • API Reference
        • Client APIs
  • React Native
    • Run Demo
    • SDK
      • SDK Integration
      • Initialization
      • Login and Logout
      • Message
        • Message Overview
        • Sending Message
        • Receiving Message
        • Historical Message
        • Forwarding Message
        • Modifying Message
        • Message Inserting
        • Deleting Message
        • Clearing Messages
        • Recalling Message
        • Online Message
        • Read Receipt
        • Querying Message
        • Group @ Message
        • Targeted Group Message
        • Notification Muting
        • Message Extension
      • Group
        • Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
        • Community Management
      • User
        • User Profile
        • Friend Management
        • Friend List
        • Blocklist
      • Offline Push
        • Offline Push
      • Local Search
        • Searching for Message
        • Searching for Friend
        • Searching Group
        • Searching for Group Member
      • Signaling
        • Signaling Management
  • Unity(Game Solution)
    • Run Demo
    • SDK
      • SDK Integration
      • Initialization
      • Login and Logout
      • Message
        • Message Overview
        • Sending Message
        • Receiving Message
        • Historical Message
        • Forwarding Message
        • Modifying Message
        • Deleting Message
        • Clearing Messages
        • Recalling Message
        • Online Message
        • Read Receipt
        • Querying Message
        • Group @ Message
        • Targeted Group Message
        • Notification Muting
        • Message Extension
      • Conversation
        • Conversation Overview
        • Conversation List
        • Getting Conversation
        • Conversation Unread Count
        • Pinning Conversation to the Top
        • Deleting Conversation
        • Conversation Draft
        • Conversation Mark
        • Conversation Group
      • Group
        • Group Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
        • Group Counter
      • User
        • User Profile
        • User Status
        • Friend Management
        • Friend List
        • Blocklist
  • Unreal Engine(Game Solution)
    • SDK
      • SDK Integration
  • Free Demos
  • Server APIs
    • Generating UserSig
    • RESTful APIs
      • RESTful API Overview
      • RESTful API List
      • Message Related
        • Send Message
          • Sending One-to-One Messages to One User
          • Sending One-to-One Messages to Multiple Users
          • Sending Ordinary Messages in a Group
          • Sending System Messages in a Group
          • Broadcast Message of Audio-Video Group
          • Importing One-to-One Messages
          • Importing Group Messages
        • Historical Message
          • Modifying Historical One-to-one Messages
          • Modifying Historical Group Messages
          • Pulling Historical One-to-one Messages
          • Pulling Historical Group Messages
        • Delete Message
          • Deleting Messages Sent by a Specified User
        • Withdraw Message
          • Recalling One-to-One Messages
          • Recalling Group Messages
        • Read Receipt
          • Marking One-to-One Messages as Read
          • Pulling Group Message Read Receipt Details
          • Pulling Read Receipts for Group Messages
        • Message Extension
          • Pulling the Message Extension of a One-to-One Message
          • Configuring Message Extension for a One-to-One Message
          • Pulling Message Extension of a Group Message
          • Configuring Message Extension for a Group Message
        • Pushing to All Users
          • API for Pushing to All Users
          • Pushing to All Users
          • Setting Application Attribute Names
          • Getting Application Attribute Names
          • Getting User Attributes
          • Setting User Attributes
          • Deleting User Attributes
          • Getting User Tags
          • Adding User Tags
          • Deleting User Tags
          • Deleting All Tags of a User
      • Session Related
        • Conversation List
          • Pulling a conversation list
        • Session Unread Count
          • Setting the Unread Message Count of a Member
          • Querying Unread One-to-One Message Count
        • Delete Session
          • Deleting a conversation
        • Session Grouping Tag
          • Creating Conversation Group Data
          • Updating Conversation Group Data
          • Deleting Conversation Group Data
          • Creating or Updating Conversation Mark Data
          • Searching for Conversation Group Marks
          • Pulling Conversation Group Mark Data
      • Group Related
        • Group Management
          • Getting All Groups in an App
          • Creating a Group
          • Disbanding a Group
          • Getting the Groups a User Has Joined
        • Group Information
          • Getting Group Profiles
          • Modifying the Profile of a Group
          • Importing a Group Profile
        • Group Member Management
          • Adding Group Members
          • Deleting Group Members
          • Banning Group Members
          • Unbanning Group Members
          • Bulk Muting and Unmuting
          • Getting the List of Muted Group Members
          • Changing Group Owner
          • Querying the Roles of Users in a Group
          • Importing Group Members
        • Group Member Information
          • Getting Group Member Profiles
          • Modifying the Profile of a Group Member
        • Group Custom Attributes
          • Getting Group Custom Attributes
          • Modifying Group Custom Attributes
          • Clearing Group Custom Attributes
          • Resetting Group Custom Attributes
          • Deleting Group Custom Attributes
        • Live Group Management
          • Getting the Number of Online Users in an Audio-Video Group
          • Getting the List of Online Members in Audio-Video Group
          • Setting Audio-Video Group Member Marks
          • Getting the List of Banned Group Members.
        • Community Management
          • Creating Topic
          • Deleting Topic
          • Getting Topic Profile
          • Modifying Topic Profile
          • Importing Topic Profiles
        • Group Counter
          • Getting Group Counters
          • Updating Group Counters
          • Deleting Group Counters
      • User Management
        • Account Management
          • Importing a Single Account
          • Importing Multiple Accounts
          • Deleting Accounts
          • Querying Accounts
        • User Information
          • Setting Profiles
          • Pulling Profiles
        • User Status
          • Invalidating Account Login States
          • Querying Account Online Status
        • Friend Management
          • Adding Friends
          • Importing Friends
          • Updating Friends
          • Deleting Friends
          • Deleting All Friends
          • Verifying Friends
          • Pulling Friends
          • Pulling Specified Friends
        • Friend Lists
          • Adding Lists
          • Deleting Lists
          • Pulling Lists
        • Blocklist
          • Blocklisting Users
          • Unblocklisting Users
          • Pulling a Blacklist
          • Verifying Users on a Blocklist
      • Global Mute Management
        • Setting Global Mute
        • Querying Global Mute
      • Operations Management
        • Pulling Operations Data
        • Downloading Recent Messages
        • Getting Server IP Addresses
      • Chatbots
        • Pulling Chatbot Accounts
        • Creating Chatbot Accounts
        • Deleting Chatbot Accounts
    • Webhooks
      • Webhook Overview
      • Webhook Command List
      • Operations Management Callbacks
        • API Overclocking Alarm Callbacks
      • Online Status Webhooks
        • Status Change Webhooks
      • Relationship Chain Webhooks
        • After a Profile Is Updated
        • Before a Friend Is Added
        • Before a Friend Request Is Responded
        • After a Friend Is Added
        • After a Friend Is Deleted
        • After a User Is Added to Blocklist
        • After a User Is Removed from Blocklist
      • One-to-One Message Webhooks
        • Before a One-to-One Message Is Sent
        • After a One-to-One Message Is Sent
        • After a One-to-One message Is Marked as Read
        • After A One-to-One Message Is Recalled
      • Group Webhooks
        • Before a Group Is Created
        • After a Group Is Created
        • Before Applying to Join a Group
        • Before Inviting a User to a Group
        • After a User Joins a Group
        • After a User Leaves a Group
        • Before Group Message Is Sent
        • After a Group Message Is Sent
        • After a Group Is Full
        • After a Group Is Disbanded
        • After Group Profile Is Modified
        • Callback After Recalling Group Messages
        • Webhook for Online and Offline Status of Audio-Video Group Members
        • Webhook for Exceptions When Group Messages Are Sent
        • Before a Topic Is Created
        • After a Topic Is Created
        • After a Topic Is Deleted
        • Topic Profile Change Webhook
        • Callback After Group Member Profile Changed
        • Callback After Group Attribute Changed
        • Callback After Read Receipt
        • Callback After the Group Owner Changed
      • Webhook Mutual Authentication Configuration Guide
        • Apache Mutual Authentication Configuration
        • Nginx Mutual Authentication Configuration
      • Chatbot webhooks
        • Chatbot Passthrough Message Callback
  • Console Guide
    • Creating and Upgrading an Application
    • Basic Configuration
    • Feature Configuration
    • Account Management
    • Group Management
    • Webhook Configuration
  • Product Introduction
    • Message Management
      • One-to-One Message
      • Message Storage
      • Offline Push
      • Group Message
      • Message Formats
    • Account System
      • Login Authentication
      • Online Status Management
    • Group Related
      • Group System
      • Group Management
    • User Profile and Relationship Chain
      • Profile Management
      • Relationship Chain Management
  • Purchase Guide
    • Billing Overview
    • Pricing
  • Error Codes
Chat

Receive a Message

Feature Description

The addSimpleMsgListener API is used to listen for and receive text and custom messages, with the callback defined in the V2TIMSimpleMsgListener protocol.
The addAdvancedMsgListener API is used to listen for and receive all types of messages (text, custom, and rich media messages), with the callback defined in the V2TIMAdvancedMsgListener protocol.

Setting a Message Listener

The SDK provides the V2TIMSimpleMsgListener simple message listener and the V2TIMAdvancedMsgListener advanced message listener. They differ in that:
1. The simple message listener can only receive text and custom messages. You can use it if your business only requires these two types of messages.
2. The advanced message listener can receive all types of messages. You can use it if your business also requires rich media, merged, and other messages.
Note:
1. addSimpleMsgListener and addAdvancedMsgListener are exclusive. Do not use both of them; otherwise, unpredictable logic bugs will occur.
2. A message listener must be added first to receive the following types of messages.

Simple message listener

Adding a listener

The receiver calls the addSimpleMsgListener (Android / iOS and macOSWindows) to add the simple message listener. We recommend it be called early, such as after the chat page is initialized, to ensure timely message receiving in the application.
Sample code:
Android
iOS and macOS
Windows
V2TIMManager.getInstance().addSimpleMsgListener(simpleMsgListener);
// `self` is id<V2TIMSignalingListener>
[[V2TIMManager sharedInstance] addSimpleMsgListener:self];
class SimpleMsgListener final : public V2TIMSimpleMsgListener {
// Members ...
};

// Note that `simpleMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
SimpleMsgListener simpleMsgListener;
V2TIMManager::GetInstance()->AddSimpleMsgListener(&simpleMsgListener);

Listener callback event

After adding the simple message listener, the receiver can receive different types of messages in the callback of V2TIMSimpleMsgListener (Android / iOS and macOSWindows), as described below:
Android
iOS and macOS
Windows
public abstract class V2TIMSimpleMsgListener {
// Received the one-to-one text message
public void onRecvC2CTextMessage(String msgID, V2TIMUserInfo sender, String text) {}

// Received the custom one-to-one (signaling) message
public void onRecvC2CCustomMessage(String msgID, V2TIMUserInfo sender, byte[] customData) {}

// Received the group text message
public void onRecvGroupTextMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, String text) {}

// Received the custom group (signaling) message
public void onRecvGroupCustomMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, byte[] customData) {}
}
/// Basic message callback of the IM SDK
@protocol V2TIMSimpleMsgListener <NSObject>
@optional

/// Received a one-to-one text message
- (void)onRecvC2CTextMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info text:(NSString *)text;

/// Received a custom one-to-one (signaling) message
- (void)onRecvC2CCustomMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info customData:(NSData *)data;

/// Received a group text message
- (void)onRecvGroupTextMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info text:(NSString *)text;

/// Received a custom group (signaling) message
- (void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data;
@end
class SimpleMsgListener final : public V2TIMSimpleMsgListener {
public:
SimpleMsgListener() = default;
~SimpleMsgListener() override = default;

// Received the one-to-one text message
void OnRecvC2CTextMessage(const V2TIMString& msgID, const V2TIMUserFullInfo& sender,
const V2TIMString& text) override {}

// Received the custom one-to-one (signaling) message
void OnRecvC2CCustomMessage(const V2TIMString& msgID, const V2TIMUserFullInfo& sender,
const V2TIMBuffer& customData) override {}

// Received the group text message
void OnRecvGroupTextMessage(const V2TIMString& msgID, const V2TIMString& groupID,
const V2TIMGroupMemberFullInfo& sender, const V2TIMString& text) override {}

// Received the custom group (signaling) message
void OnRecvGroupCustomMessage(const V2TIMString& msgID, const V2TIMString& groupID,
const V2TIMGroupMemberFullInfo& sender,
const V2TIMBuffer& customData) override {}
};

Removing a listener

To stop receiving messages, the receiver can call removeSimpleMsgListener (Android / iOS and macOSWindows) to remove the simple message listener.
Sample code:
Android
iOS and macOS
Windows
V2TIMManager.getInstance().removeSimpleMsgListener(simpleMsgListener);
// `self` is id<V2TIMSignalingListener>
[[V2TIMManager sharedInstance] removeSimpleMsgListener:self];
class SimpleMsgListener final : public V2TIMSimpleMsgListener {
// Members ...
};

// `simpleMsgListener` is the instance of SimpleMsgListener
V2TIMManager::GetInstance()->RemoveSimpleMsgListener(&simpleMsgListener);

Advanced message listener

Adding a listener

The receiver calls the addAdvancedMsgListener (Android / iOS and macOSWindows) to add the advanced message listener. We recommend it be called early, such as after the chat page is initialized, to ensure timely message receiving in the application.
Sample code:
Android
iOS and macOS
Windows
V2TIMManager.getMessageManager().addAdvancedMsgListener(advancedMsgListener);
// `self` is id<V2TIMAdvancedMsgListener>
[[V2TIMManager sharedInstance] addAdvancedMsgListener:self];
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
// Members ...
};

// Note that `advancedMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
AdvancedMsgListener advancedMsgListener;
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(&advancedMsgListener);

Listener callback event

After adding the advanced message listener, the receiver can receive different types of messages in the callback of V2TIMAdvancedMsgListener (Android / iOS and macOSWindows), as described below:
Android
iOS and macOS
Windows
public abstract class V2TIMAdvancedMsgListener {
// Received a new message
public void onRecvNewMessage(V2TIMMessage msg) {}

// one-to-one message read notification (a notification is received when the receiver calls `markC2CMessageAsRead`)
public void onRecvC2CReadReceipt(List<V2TIMMessageReceipt> receiptList) {}

// Message read receipt notification (if read receipts are supported, the notification is received when the receiver calls `sendMessageReadReceipts`)
public void onRecvMessageReadReceipts(List<V2TIMMessageReceipt> receiptList) {}

// Received a message recall notification
public void onRecvMessageRevoked(String msgID) {}

// The message content is modified.
public void onRecvMessageModified(V2TIMMessage msg) {}
}
/// Advanced message listener
@protocol V2TIMAdvancedMsgListener <NSObject>
@optional
/// Received a new message
- (void)onRecvNewMessage:(V2TIMMessage *)msg;

/// Message read receipt notification (if read receipts are supported, the notification is received when the receiver calls `sendMessageReadReceipts`)
- (void)onRecvMessageReadReceipts:(NSArray<V2TIMMessageReceipt *> *)receiptList;

/// One-to-one message read notification (a notification is received when the receiver calls `markC2CMessageAsRead`)
- (void)onRecvC2CReadReceipt:(NSArray<V2TIMMessageReceipt *> *)receiptList;

/// Received a message recall notification
- (void)onRecvMessageRevoked:(NSString *)msgID;

/// The message content is modified
- (void)onRecvMessageModified:(V2TIMMessage *)msg;
@end
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
public:
AdvancedMsgListener() = default;
~AdvancedMsgListener() override = default;

// Received a new message
void OnRecvNewMessage(const V2TIMMessage& message) override {}

// one-to-one message read notification (a notification is received when the receiver calls `markC2CMessageAsRead`)
void OnRecvC2CReadReceipt(const V2TIMMessageReceiptVector& receiptList) override {}

// Message read receipt notification (if read receipts are supported, the notification is received when the receiver calls `sendMessageReadReceipts`)
void OnRecvMessageReadReceipts(const V2TIMMessageReceiptVector& receiptList) override {}

// Received a message recall notification
void OnRecvMessageRevoked(const V2TIMString& messageID) override {}

// The message content is modified.
void OnRecvMessageModified(const V2TIMMessage& message) override {}
};

Removing a listener

To stop receiving messages, the receiver can call removeAdvancedMsgListener (Android / iOS and macOSWindows) to remove the advanced message listener.
Sample code:
Android
iOS and macOS
Windows
V2TIMManager.getMessageManager().removeAdvancedMsgListener(advancedMsgListener);
// `self` is id<V2TIMAdvancedMsgListener>
[[V2TIMManager sharedInstance] removeAdvancedMsgListener:self];
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
// Members ...
};

// `advancedMsgListener` is the instance of AdvancedMsgListener
V2TIMManager::GetInstance()->GetMessageManager()->RemoveAdvancedMsgListener(&advancedMsgListener);

Receiving a Text Message

Receiving a message with the simple message listener

One-to-one text message

The receiver can receive a one-to-one text message by using the simple message listener in the following steps:
1. Call addSimpleMsgListener to set the event listener.
2. Listen for the onRecvC2CTextMessage callback (Android / iOS and macOSWindows) to receive text messages.
3. To stop receiving messages, call removeSimpleMsgListener to remove the listener. This step is optional and can be performed as needed.
Sample code:
Android
iOS and macOS
Windows
// Set the event listener
V2TIMManager.getInstance().addSimpleMsgListener(simpleMsgListener);

// Receive the one-to-one text message
/**
* Received the one-to-one text message
*
* @param msgID Unique message ID
* @param sender Sender information
* @param text The sent content
*/
public void onRecvC2CTextMessage(String msgID, V2TIMUserInfo sender, String text) {
// Parse the message and display it on the UI
}
// Set the event listener
[[V2TIMManager sharedInstance] addSimpleMsgListener:self];

/// Receive the one-to-one text message
/// @param msgID Message ID
/// @param info Sender information
/// @param text Text content
- (void)onRecvC2CTextMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info text:(NSString *)text {
// Parse the message and display it on the UI
}
class SimpleMsgListener final : public V2TIMSimpleMsgListener {
public:
/**
* Receive the one-to-one text message
*
* @param msgID Unique message ID
* @param sender Sender information
* @param text The sent content
*/
void OnRecvC2CTextMessage(const V2TIMString& msgID, const V2TIMUserFullInfo& sender,
const V2TIMString& text) override {
// Parse the message and display it on the UI
std::cout << "text:" << std::string{text.CString(), text.Size()} << std::endl;
}
// Other members ...
};

// Note that `simpleMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
SimpleMsgListener simpleMsgListener;
V2TIMManager::GetInstance()->AddSimpleMsgListener(&simpleMsgListener);

Group text message

The receiver can receive a group text message by using the simple message listener in the following steps:
1. Call addSimpleMsgListener to set the event listener.
2. Listen for the onRecvGroupTextMessage callback (Android / iOS and macOSWindows) to receive text messages.
3. To stop receiving messages, call removeSimpleMsgListener to remove the listener. This step is optional and can be performed as needed.
Sample code:
Android
iOS and macOS
Windows
// Set the event listener
V2TIMManager.getInstance().addSimpleMsgListener(simpleMsgListener);

// Receive the group text message
/**
* Received the group text message
*
* @param msgID Unique message ID
* @param groupID Group ID
* @param sender The group member information of the sender
* @param text The sent content
*/
public void onRecvGroupTextMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, String text) {
// Parse the message and display it on the UI
}
// Set the event listener
[[V2TIMManager sharedInstance] addSimpleMsgListener:self];

/// Receive the group text message
/// @param msgID Message ID
/// @param groupID Group ID
/// @param info Sender information
/// @param text Text content
- (void)onRecvGroupTextMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info text:(NSString *)text {
// Parse the message and display it on the UI
}
class SimpleMsgListener final : public V2TIMSimpleMsgListener {
public:
/**
* Received the group text message
*
* @param msgID Unique message ID
* @param groupID Group ID
* @param sender The group member information of the sender
* @param text The sent content
*/
void OnRecvGroupTextMessage(const V2TIMString& msgID, const V2TIMString& groupID,
const V2TIMGroupMemberFullInfo& sender, const V2TIMString& text) override {
// Parse the message and display it on the UI
std::cout << "text:" << std::string{text.CString(), text.Size()} << std::endl;
}
// Other members ...
};

// Note that `simpleMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
SimpleMsgListener simpleMsgListener;
V2TIMManager::GetInstance()->AddSimpleMsgListener(&simpleMsgListener);

Receiving a message with the advanced message listener

The receiver can receive a one-to-one or group text message by using the advanced message listener in the following steps:
1. Call addAdvancedMsgListener to set the event listener.
2. Listen for the onRecvNewMessage callback (Android / iOS and macOSWindows) to receive text messages.
3. To stop receiving messages, call removeAdvancedMsgListener to remove the listener. This step is optional and can be performed as needed.
Sample code:
Android
iOS and macOS
Windows
// Set the event listener
V2TIMManager.getMessageManager().addAdvancedMsgListener(advancedMsgListener);

/**
* Received a new message
* @param msg Message
*/
public void onRecvNewMessage(V2TIMMessage msg) {
// Parse the `groupID` and `userID`
String groupID = msg.getGroupID();
String userID = msg.getUserID();

// Determine whether it's a one-to-one chat or group chat
// If `groupID` is not empty, the message is from a group chat; if `userID` is not empty, the message is from a one-to-one chat.

// Parse the text message in `msg`
if (msg.getElemType() == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) {
V2TIMTextElem textElem = msg.getTextElem();
String text = textElem.getText();
Log.i("onRecvNewMessage", "text:" + text);
}
}
// Set the event listener
[[V2TIMManager sharedInstance] addAdvancedMsgListener:self];

/// Receive the message
/// @param msg Message object
- (void)onRecvNewMessage:(V2TIMMessage *)msg {
// Parse the `groupID` and `userID`
NSString *groupID = msg.groupID;
NSString *userID = msg.userID;

// Determine whether it's a one-to-one chat or group chat
// If `groupID` is not empty, the message is from a group chat; if `userID` is not empty, the message is from a one-to-one chat.

// Parse the text message in `msg`
if (msg.elemType == V2TIM_ELEM_TYPE_TEXT) {
V2TIMTextElem *textElem = msg.textElem;
NSString *text = textElem.text;
NSLog(@"onRecvNewMessage, text: %@", text);
}
}
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
public:
/**
* Received a new message
*
* @param message Message
*/
void OnRecvNewMessage(const V2TIMMessage& message) override {
// Parse the `groupID` and `userID`
V2TIMString groupID = message.groupID;
V2TIMString userID = message.userID;

// Determine whether it's a one-to-one chat or group chat
// If `groupID` is not empty, the message is from a group chat;
// if `userID` is not empty, the message is from a one-to-one chat.
// Parse the text message in `message`
if (message.elemList.Size() == 1) {
V2TIMElem* elem = message.elemList[0];
if (elem->elemType == V2TIMElemType::V2TIM_ELEM_TYPE_TEXT) {
auto textElem = static_cast<V2TIMTextElem*>(elem);
V2TIMString text = textElem->text;
// Parse the message and display it on the UI
std::cout << "text:" << std::string{text.CString(), text.Size()} << std::endl;
}
}
}
// Other members ...
};

// Note that `advancedMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
AdvancedMsgListener advancedMsgListener;
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(&advancedMsgListener);

Receiving a Custom Message

Receiving a message with the simple message listener

Custom one-to-one message

The receiver can receive a custom one-to-one message by using the simple message listener in the following steps:
1. Call addSimpleMsgListener to set the event listener.
2. Listen for the onRecvC2CCustomMessage callback (Android / iOS and macOSWindows) to receive custom one-to-one messages.
3. To stop receiving messages, call removeSimpleMsgListener to remove the listener. This step is optional and can be performed as needed.
Sample code:
Android
iOS and macOS
Windows
/**
* Receive the custom one-to-one message
* @param msgID Message ID
* @param sender Sender information
* @param customData The sent content
*/
public void onRecvC2CCustomMessage(String msgID, V2TIMUserInfo sender, byte[] customData) {
Log.i("onRecvC2CCustomMessage", "msgID:" + msgID + ", from:" + sender.getNickName() + ", content:" + new String(customData));
}
/// Receive the custom one-to-one message
/// @param msgID Message ID
/// @param info Sender information
/// @param data The binary content of the custom message
- (void)onRecvC2CCustomMessage:(NSString *)msgID sender:(V2TIMUserInfo *)info customData:(NSData *)data {
NSLog(@"onRecvC2CCustomMessage, msgID: %@, sender: %@, customData: %@", msgID, info, data);
}
class SimpleMsgListener final : public V2TIMSimpleMsgListener {
public:
/**
* Receive the custom one-to-one message
*
* @param msgID Message ID
* @param sender Sender information
* @param customData The sent content
*/
void OnRecvC2CCustomMessage(const V2TIMString& msgID, const V2TIMUserFullInfo& sender,
const V2TIMBuffer& customData) override {
// Parse the message and display it on the UI
std::cout << "customData:"
<< std::string{reinterpret_cast<const char*>(customData.Data()), customData.Size()}
<< std::endl;
}
// Other members ...
};

// Note that `simpleMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
SimpleMsgListener simpleMsgListener;
V2TIMManager::GetInstance()->AddSimpleMsgListener(&simpleMsgListener);

Custom group message

The receiver can receive a custom group message by using the simple message listener in the following steps:
1. Call addSimpleMsgListener to set the event listener.
2. Listen for the onRecvGroupCustomMessage callback (Android / iOS and macOSWindows) to receive custom group messages.
3. To stop receiving messages, call removeSimpleMsgListener to remove the listener. This step is optional and can be performed as needed.
Android
iOS and macOS
Windows
/**
* Receive the custom group message
* @param msgID Message ID
* @param groupID Group ID
* @param sender The group member information of the sender
* @param customData The sent content
*/
public void onRecvGroupCustomMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, byte[] customData) {
Log.i("onRecvGroupCustomMessage", "msgID:" + msgID + ", groupID:" + groupID + ", from:" + sender.getNickName() + ", content:" + new String(customData));
}
/// Receive the custom group message
/// @param msgID Message ID
/// @param groupID Group ID
/// @param info Sender information
/// @param text The binary content of the custom message
- (void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data {
NSLog(@"onRecvGroupCustomMessage, msgID: %@, groupID: %@, sender: %@, customData: %@", msgID, groupID, info, data);
}
class SimpleMsgListener final : public V2TIMSimpleMsgListener {
public:
/**
* Receive the custom group message
*
* @param msgID Message ID
* @param groupID Group ID
* @param sender The group member information of the sender
* @param customData The sent content
*/
void OnRecvGroupCustomMessage(const V2TIMString& msgID, const V2TIMString& groupID,
const V2TIMGroupMemberFullInfo& sender,
const V2TIMBuffer& customData) override {
// Parse the message and display it on the UI
std::cout << "customData:"
<< std::string{reinterpret_cast<const char*>(customData.Data()), customData.Size()}
<< std::endl;
}
// Other members ...
};

// Note that `simpleMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
SimpleMsgListener simpleMsgListener;
V2TIMManager::GetInstance()->AddSimpleMsgListener(&simpleMsgListener);

Receiving a message with the advanced message listener

The receiver can receive a custom one-to-one or group message by using the advanced message listener in the following steps:
1. Call addAdvancedMsgListener to set the event listener.
2. Listen for the onRecvNewMessage callback (Android / iOS and macOSWindows) to receive custom messages.
3. To stop receiving messages, call removeAdvancedMsgListener to remove the listener. This step is optional and can be performed as needed.
Sample code:
Android
iOS and macOS
Windows
// Set the event listener
V2TIMManager.getMessageManager().addAdvancedMsgListener(v2TIMAdvancedMsgListener);

// Receive the message
public void onRecvNewMessage(V2TIMMessage msg) {
// Parse the `groupID` and `userID`
String groupID = msg.getGroupID();
String userID = msg.getUserID();

// Determine whether it's a one-to-one chat or group chat
// If `groupID` is not empty, the message is from a group chat; if `userID` is not empty, the message is from a one-to-one chat.

// Parse the custom message in `msg`
if (msg.getElemType() == V2TIMMessage.V2TIM_ELEM_TYPE_CUSTOM) {
V2TIMCustomElem customElem = msg.getCustomElem();
String data = new String(customElem.getData());
Log.i("onRecvNewMessage", "customData:" + data);
}
}
// Set the event listener
[[V2TIMManager sharedInstance] addAdvancedMsgListener:self];

/// Receive the message
/// @param msg Message object
- (void)onRecvNewMessage:(V2TIMMessage *)msg {
// Parse the `groupID` and `userID`
NSString *groupID = msg.groupID;
NSString *userID = msg.userID;

// Determine whether it's a one-to-one chat or group chat
// If `groupID` is not empty, the message is from a group chat; if `userID` is not empty, the message is from a one-to-one chat.

// Parse the custom message in `msg`
if (msg.elemType == V2TIM_ELEM_TYPE_CUSTOM) {
V2TIMCustomElem *customElem = msg.customElem;
NSData *customData = customElem.data;
NSLog(@"onRecvNewMessage, customData: %@", customData);
}
}
class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
public:
/**
* Receive the message
*
* @param message Message
*/
void OnRecvNewMessage(const V2TIMMessage& message) override {
// Parse the `groupID` and `userID`
V2TIMString groupID = message.groupID;
V2TIMString userID = message.userID;

// Determine whether it's a one-to-one chat or group chat
// If `groupID` is not empty, the message is from a group chat;
// if `userID` is not empty, the message is from a one-to-one chat.

// Parse the custom message in `message`
if (message.elemList.Size() == 1) {
V2TIMElem* elem = message.elemList[0];
if (elem->elemType == V2TIMElemType::V2TIM_ELEM_TYPE_CUSTOM) {
auto customElem = static_cast<V2TIMCustomElem*>(elem);
V2TIMBuffer data = customElem->data;
// Parse the message and display it on the UI
std::cout << "data:"
<< std::string{reinterpret_cast<const char*>(data.Data()), data.Size()}
<< std::endl;
}
}
}
// Other members ...
};

// Note that `advancedMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
AdvancedMsgListener advancedMsgListener;
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(&advancedMsgListener);

Receiving a Rich Media Message

The receiver can receive a rich media message only by using the advanced message listener in the following steps:
1. Call the addAdvancedMsgListener API to set the advanced message listener.
2. Listen for the onRecvNewMessage callback (Android / iOS and macOSWindows) to receive the V2TIMMessage message.
3. Parse the elemType attribute in the V2TIMMessage message and then parse the message again according to the type to get the specific content of the elements in the message.
4. To stop receiving messages, call removeAdvancedMsgListener to remove the listener. This step is optional and can be performed as needed.

Image message

The image in an image message can be in three formats: original, large, and thumbnail. The latter two are automatically generated by the SDK during message sending and can be ignored.
Large image: A large image is an image obtained after the original image is proportionally compressed. After the compression, the height or width (whichever is shorter) is equal to 720 pixels.
Thumbnail: A thumbnail is an image obtained after the original image is proportionally compressed. After the compression, the height or width (whichever is shorter) is equal to 198 pixels.
After the image message is received, we recommend you call the SDK's downloadImage (Android / iOS and macOSWindows) to download the image and then render it to the UI layer.
To avoid repeated download and save resources, we recommend you set the uuid attribute value of the V2TIMImage object to the image download path to identify the image.
The following sample code demonstrates how to parse the image content from V2TIMMessage:
Android
iOS and macOS
Windows
public void onRecvNewMessage(V2TIMMessage msg) {
if (msg.getElemType() == V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE) {
// Image message
V2TIMImageElem v2TIMImageElem = msg.getImageElem();
// The image in an image message can be in three formats: original, large, and thumbnail. The latter two are automatically generated by the SDK during message sending and can be ignored.
// Large image: A large image is an image obtained after the original image is proportionally compressed. After the compression, the height or width (whichever is shorter) is equal to 720 pixels.
// Thumbnail: A thumbnail is an image obtained after the original image is proportionally compressed. After the compression, the height or width (whichever is shorter) is equal to 198 pixels.
List<V2TIMImageElem.V2TIMImage> imageList = v2TIMImageElem.getImageList();
for (V2TIMImageElem.V2TIMImage v2TIMImage : imageList) {
// Image ID, which is an internal ID and can be used as an external cache key
String uuid = v2TIMImage.getUUID();
// Image types, encompassing three distinct varieties: V2TIM_IMAGE_TYPE_ORIGIN (Original), V2TIM_IMAGE_TYPE_THUMB (Thumbnail), and V2TIM_IMAGE_TYPE_LARGE (Large).
int imageType = v2TIMImage.getType();
// Image size (bytes)
int size = v2TIMImage.getSize();
// Image width
int width = v2TIMImage.getWidth();
// Image height
int height = v2TIMImage.getHeight();
// Set the image download path `imagePath`. Here, `uuid` can be used as an identifier to avoid repeated download.
String imagePath = "/sdcard/im/image/" + "myUserID" + uuid;
File imageFile = new File(imagePath);
// Determine whether there is a downloaded image file in `imagePath`
if (!imageFile.exists()) {
// Download the image
v2TIMImage.downloadImage(imagePath, new V2TIMDownloadCallback() {
@Override
public void onProgress(V2TIMElem.V2ProgressInfo progressInfo) {
// Callback for download progress. `v2ProgressInfo.getCurrentSize()` indicates the downloaded file size, and `v2ProgressInfo.getTotalSize()` indicates the total file size.
}
@Override
public void onError(int code, String desc) {
// Download failed
}
@Override
public void onSuccess() {
// Downloaded
}
});
} else {
// The image already exists.
}
}
}
}
- (void)onRecvNewMessage:(V2TIMMessage *)msg {
if (msg.elemType == V2TIM_ELEM_TYPE_IMAGE) {
V2TIMImageElem *imageElem = msg.imageElem;
// The list of original images, large images, and thumbnails
NSArray<V2TIMImage *> *imageList = imageElem.imageList;
for (V2TIMImage *timImage in imageList) {
// Image ID, which is an internal ID and can be used as an external cache key
NSString *uuid = timImage.uuid;
// Image type
V2TIMImageType type = timImage.type;
// Image size (bytes)
int size = timImage.size;
// Image width
int width = timImage.width;
// Image height
int height = timImage.height;
// Set the image download path `imagePath`. Here, `uuid` can be used as an identifier to avoid repeated download.
NSString *imagePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat: @"testImage%@", timImage.uuid]];
// Determine whether there is a downloaded image file in `imagePath`
if (![[NSFileManager defaultManager] fileExistsAtPath:imagePath]) {
// Download the image
[timImage downloadImage:imagePath progress:^(NSInteger curSize, NSInteger totalSize) {
// Download progress
NSLog(@"Image download progress: curSize: %lu,totalSize:%lu",curSize,totalSize);
} succ:^{
// Downloaded successfully
NSLog(@"Image downloaded");
} fail:^(int code, NSString *msg) {
// Download failed
NSLog(@"Failed to download the image: code: %d,msg:%@",code,msg);
}];
} else {
// The image already exists.
}
NSLog(@"Image information: uuid:%@, type:%ld, size:%d, width:%d, height:%d", uuid, (long)type, size, width, height);
}
}
}
class DownloadCallback final : public V2TIMDownloadCallback {
public:
using SuccessCallback = std::function<void()>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
using DownLoadProgressCallback = std::function<void(uint64_t, uint64_t)>;

DownloadCallback() = default;
~DownloadCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback,
DownLoadProgressCallback download_progress_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
download_progress_callback_ = std::move(download_progress_callback);
}
void OnSuccess() override {
if (success_callback_) {
success_callback_();
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
void OnDownLoadProgress(uint64_t currentSize, uint64_t totalSize) override {
if (download_progress_callback_) {
download_progress_callback_(currentSize, totalSize);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
DownLoadProgressCallback download_progress_callback_;
};

class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
public:
void OnRecvNewMessage(const V2TIMMessage& message) override {
if (message.elemList.Size() == 1) {
V2TIMElem* elem = message.elemList[0];
if (elem->elemType == V2TIMElemType::V2TIM_ELEM_TYPE_IMAGE) {
// Image message
auto imageElem = static_cast<V2TIMImageElem*>(elem);
// The image in an image message can be in three formats: original, large, and thumbnail.
// The latter two are automatically generated by the SDK during message sending and can be ignored.
// Large image: A large image is an image obtained after the original image is proportionally compressed.
// After the compression, the height or width (whichever is shorter) is equal to 720 pixels.
// Thumbnail: A thumbnail is an image obtained after the original image is proportionally compressed.
// After the compression, the height or width (whichever is shorter) is equal to 198 pixels.
V2TIMImageVector imageList = imageElem->imageList;
for (size_t i = 0; i < imageList.Size(); ++i) {
V2TIMImage& image = imageList[i];
// Image ID, which is an internal ID and can be used as an external cache key
V2TIMString uuid = image.uuid;
// Image type
V2TIMImageType type = image.type;
// Image size (bytes) when type == V2TIMImageType::V2TIM_IMAGE_TYPE_ORIGIN
uint64_t size = image.size;
// Image width
uint32_t width = image.width;
// Image height
uint32_t height = image.height;
// Set the image download path `imagePath`.
// Here, `uuid` can be used as an identifier to avoid repeated download.
std::filesystem::path imagePath = u8"./File/Image/"s + uuid.CString();
// Determine whether there is a downloaded image file in `imagePath`
if (!std::filesystem::exists(imagePath)) {
std::filesystem::create_directories(imagePath.parent_path());
auto callback = new DownloadCallback{};
callback->SetCallback(
[=]() {
// Downloaded
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Download failed
delete callback;
},
[=](uint64_t currentSize, uint64_t totalSize) {
// Callback for download progress.
// `currentSize` indicates the downloaded file size,
// and `totalSize` indicates the total file size.
});
image.DownloadImage(imagePath.string().c_str(), callback);
} else {
// The image already exists.
}
}
}
}
}
// Other members ...
};

// Note that `advancedMsgListener` should not be released before the IM SDK is uninitialized,
// otherwise the message callback cannot be called.
AdvancedMsgListener advancedMsgListener;
V2TIMManager::GetInstance()->GetMessageManager()->AddAdvancedMsgListener(&advancedMsgListener);

Video message

After a video message is received, a video preview is displayed on the chat page, and the video is played back after the user clicks the message. Two steps are required:
1. Download the video screenshot. We recommend you call the SDK's downloadSnapshot (Android / iOS and macOSWindows) for download.
2. Download the video. We recommend you call the SDK's downloadVideo (Android / iOS and macOSWindows) for download.
To avoid repeated download and save resources, we recommend you set the videoUUID attribute value of the V2TIMVideoElem object to the video download path to identify the video.
The following sample code demonstrates how to parse the video content from V2TIMMessage:
Android
iOS and macOS
Windows
public void onRecvNewMessage(V2TIMMessage msg) {
if (msg.getElemType() == V2TIMMessage.V2TIM_ELEM_TYPE_VIDEO) {
// Video message
V2TIMVideoElem v2TIMVideoElem = msg.getVideoElem();
// Video screenshot ID, which is an internal ID and can be used as an external cache key
String snapshotUUID = v2TIMVideoElem.getSnapshotUUID();
// Video screenshot file size
int snapshotSize = v2TIMVideoElem.getSnapshotSize();
// Video screenshot width
int snapshotWidth = v2TIMVideoElem.getSnapshotWidth();
// Video screenshot height
int snapshotHeight = v2TIMVideoElem.getSnapshotHeight();
// Video ID, which is an internal ID and can be used as an external cache key
String videoUUID = v2TIMVideoElem.getVideoUUID();
// Video file size
int videoSize = v2TIMVideoElem.getVideoSize();
// Video duration
int duration = v2TIMVideoElem.getDuration();
// Set the video screenshot file path. Here, `uuid` can be used as an identifier to avoid repeated download.
String snapshotPath = "/sdcard/im/snapshot/" + "myUserID" + snapshotUUID;
File snapshotFile = new File(snapshotPath);
if (!snapshotFile.exists()) {
v2TIMVideoElem.downloadSnapshot(snapshotPath, new V2TIMDownloadCallback() {
@Override
public void onProgress(V2TIMElem.V2ProgressInfo progressInfo) {
// Callback for download progress. `v2ProgressInfo.getCurrentSize()` indicates the downloaded file size, and `v2ProgressInfo.getTotalSize()` indicates the total file size.
}
@Override
public void onError(int code, String desc) {
// Download failed
}
@Override
public void onSuccess() {
// Downloaded
}
});
} else {
// The file already exists.
}

// Set the video file path. Here, `uuid` can be used as an identifier to avoid repeated download.
String videoPath = "/sdcard/im/video/" + "myUserID" + videoUUID;
File videoFile = new File(videoPath);
if (!videoFile.exists()) {
v2TIMVideoElem.downloadVideo(videoPath, new V2TIMDownloadCallback() {
@Override
public void onProgress(V2TIMElem.V2ProgressInfo progressInfo) {
// Callback for download progress. `v2ProgressInfo.getCurrentSize()` indicates the downloaded file size, and `v2ProgressInfo.getTotalSize()` indicates the total file size.
}
@Override
public void onError(int code, String desc) {
// Download failed
}
@Override
public void onSuccess() {
// Downloaded
}
});
} else {
// The file already exists.
}
}
}
- (void)onRecvNewMessage:(V2TIMMessage *)msg {
if (msg.elemType == V2TIM_ELEM_TYPE_VIDEO) {
V2TIMVideoElem *videoElem = msg.videoElem;
// Video screenshot ID, which is an internal ID and can be used as an external cache key
NSString *snapshotUUID = videoElem.snapshotUUID;
// Video screenshot file size
int snapshotSize = videoElem.snapshotSize;
// Video screenshot width
int snapshotWidth = videoElem.snapshotWidth;
// Video screenshot height
int snapshotHeight = videoElem.snapshotHeight;
// Video ID, which is an internal ID and can be used as an external cache key
NSString *videoUUID = videoElem.videoUUID;
// Video file size
int videoSize = videoElem.videoSize;
// Video duration
int duration = videoElem.duration;
// Set the video screenshot file path. Here, `uuid` can be used as an identifier to avoid repeated download.
NSString *snapshotPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat: @"testVideoSnapshot%@",snapshotUUID]];
if (![[NSFileManager defaultManager] fileExistsAtPath:snapshotPath]) {
// Download the video screenshot
[videoElem downloadSnapshot:snapshotPath progress:^(NSInteger curSize, NSInteger totalSize) {
// Download progress
NSLog(@"%@", [NSString stringWithFormat:@"Video screenshot download progress: curSize: %lu,totalSize:%lu",curSize,totalSize]);
} succ:^{
// Downloaded successfully
NSLog(@"Video screenshot downloaded");
} fail:^(int code, NSString *msg) {
// Download failed
NSLog(@"%@", [NSString stringWithFormat:@"Failed to download the video screenshot: code: %d,msg:%@",code,msg]);
}];
} else {
// The video screenshot already exists.
}
NSLog(@"Video screenshot information: snapshotUUID:%@, snapshotSize:%d, snapshotWidth:%d, snapshotWidth:%d, snapshotPath:%@", snapshotUUID, snapshotSize, snapshotWidth, snapshotHeight, snapshotPath);

// Set the video file path. Here, `uuid` can be used as an identifier to avoid repeated download.
NSString *videoPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat: @"testVideo%@",videoUUID]];
if (![[NSFileManager defaultManager] fileExistsAtPath:videoPath]) {
// Download the video
[videoElem downloadVideo:videoPath progress:^(NSInteger curSize, NSInteger totalSize) {
// Download progress
NSLog(@"%@", [NSString stringWithFormat:@"Video download progress: curSize: %lu,totalSize:%lu",curSize,totalSize]);
} succ:^{
// Downloaded successfully
NSLog(@"Video downloaded");
} fail:^(int code, NSString *msg) {
// Download failed
NSLog(@"%@", [NSString stringWithFormat:@"Failed to download the video: code: %d,msg:%@",code,msg]);
}];
} else {
// The video already exists.
}
NSLog(@"Video information: videoUUID:%@, videoSize:%d, duration:%d, videoPath:%@", videoUUID, videoSize, duration, videoPath);
}
}
class DownloadCallback final : public V2TIMDownloadCallback {
public:
using SuccessCallback = std::function<void()>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
using DownLoadProgressCallback = std::function<void(uint64_t, uint64_t)>;

DownloadCallback() = default;
~DownloadCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback,
DownLoadProgressCallback download_progress_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
download_progress_callback_ = std::move(download_progress_callback);
}
void OnSuccess() override {
if (success_callback_) {
success_callback_();
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
void OnDownLoadProgress(uint64_t currentSize, uint64_t totalSize) override {
if (download_progress_callback_) {
download_progress_callback_(currentSize, totalSize);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
DownLoadProgressCallback download_progress_callback_;
};

class AdvancedMsgListener final : public V2TIMAdvancedMsgListener {
public:
void OnRecvNewMessage(const V2TIMMessage& message) override {
if (message.elemList.Size() == 1) {
V2TIMElem* elem = message.elemList[0];
if (elem->elemType == V2TIMElemType::V2TIM_ELEM_TYPE_VIDEO) {
// Video message
auto videoElem = static_cast<V2TIMVideoElem*>(elem);
// Video ID, which is an internal ID and can be used as an external cache key
V2TIMString videoUUID = videoElem->videoUUID;
// Video file size
uint64_t videoSize = videoElem->videoSize;
// Video type
V2TIMString videoType = videoElem->videoType;
// Video duration
uint32_t duration = videoElem->duration;
// Video screenshot ID, which is an internal ID and can be used as an external cache key
V2TIMString snapshotUUID = videoElem->snapshotUUID;
// Video screenshot file size
uint64_t snapshotSize = videoElem->snapshotSize;
// Video screenshot width
uint32_t snapshotWidth = videoElem->snapshotWidth;
// Video screenshot height
uint32_t snapshotHeight = videoElem->snapshotHeight;

// Set the video file path. Here, `uuid` can be used as an identifier to avoid repeated download.
std::filesystem::path videoPath = u8"./File/Video/"s + videoUUID.CString();
if (!std::filesystem::exists(videoPath)) {
std::filesystem::create_directories(videoPath.parent_path());
auto callback = new DownloadCallback{};
callback->SetCallback(
[=]() {
// Downloaded
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Download failed
delete callback;
},
[=](uint64_t currentSize, uint64_t totalSize) {
// Callback for download progress.
// `currentSize` indicates the downloaded file size,
// and `totalSize` indicates the total file size.
});
videoElem->DownloadVideo(videoPath.string().c_str(), callback);
} else {
// The file already exists.
}

// Set the video screenshot file path. Here, `uuid` can be used as an identifier to avoid repeated download.
std::filesystem::path snapshotPath = u8"./File/Snapshot/"s + snapshotUUID.CString();
if (!std::filesystem::exists(snapshotPath)) {
std::filesystem::create_directories(snapshotPath.parent_path());
auto callback = new DownloadCallback{};
callback->SetCallback(
[=]() {
// Downloaded
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Download failed
delete callback;
},
[=](uint64_t currentSize, uint64_t totalSize) {
// Callback for download progress.
// `currentSize` indicates the downloaded file size,
// and `totalSize` indicates the total file size.
});
videoElem->DownloadSnapshot(snapshotPath.string()