Manage chat messages
After a chat message arrives, you can read its metadata, delete it, and control who can chat through host privileges.
Read message metadata
Every onChatNewMessageNotify callback receives a ZMVideoSDKChatMessage. In addition to the sender and content shown in Core features, the message exposes the following fields.
let messageID = chatMessage.messageID // String — unique ID; required to delete the message.
let timeMessageWasSent = chatMessage.timeStamp // time_t — when the message was sent.
let isChatToAll = chatMessage.isChatToAll // Bool — true for public messages, false for private.
let currentUserIsSender = chatMessage.isSelfSend // Bool — true if the current user sent the message.
let recipient = chatMessage.receiverUser // ZMVideoSDKUser? — the recipient of a private message; nil when isChatToAll is true.
chatMessage.messageID; // NSString — unique ID; required to delete the message.
chatMessage.timeStamp; // time_t — when the message was sent.
chatMessage.isChatToAll; // BOOL — true for public messages, false for private.
chatMessage.isSelfSend; // BOOL — true if the current user sent the message.
chatMessage.receiverUser; // ZMVideoSDKUser — the recipient of a private message; nil when isChatToAll is true.
Delete a chat message
A user can delete a message they sent, and a host can delete any message in the session. A compliance system can also delete a message under a data-loss-prevention policy. Before exposing a delete control for a given message, ask the SDK whether it can be deleted in the current context.
guard let chatHelper = ZMVideoSDK.shared()?.getChatHelper() else { return }
let messageID = chatMessage.messageID
if chatHelper.canChatMessageBeDeleted(messageID) {
let result = chatHelper.deleteChatMessage(messageID)
if result != .ZMVideoSDKErrors_Success {
// Surface the error to the user.
}
}
ZMVideoSDKChatHelper *chatHelper = [[ZMVideoSDK sharedVideoSDK] getChatHelper];
NSString *messageID = chatMessage.messageID;
if ([chatHelper canChatMessageBeDeleted:messageID]) {
ZMVideoSDKErrors result = [chatHelper deleteChatMessage:messageID];
if (result != ZMVideoSDKErrors_Success) {
// Surface the error to the user.
}
}
Listen for deletions
When any message is deleted, the SDK fires onChatMsgDeleteNotification on every user's device. Remove the message from your UI in this callback so it stays in sync regardless of who initiated the delete.
func onChatMsgDeleteNotification(_ chatHelper: ZMVideoSDKChatHelper!, messageID msgID: String!, deleteBy type: ZMVideoSDKChatMessageDeleteType) {
// Remove the message with id msgID from your UI.
// Optionally show who removed it using type.
}
- (void)onChatMsgDeleteNotification:(ZMVideoSDKChatHelper *)chatHelper messageID:(NSString *)msgID deleteBy:(ZMVideoSDKChatMessageDeleteType)type {
// Remove the message with id msgID from your UI.
// Optionally show who removed it using type.
}
Delete-initiator values
ZMVideoSDKChatMessageDeleteType tells you who deleted the message.
| Value | Meaning |
|---|---|
ZMVideoSDKChatMessageDeleteType_None | Initialization value, not used in a real callback. |
ZMVideoSDKChatMessageDeleteType_BySelf | The message author deleted their own message. |
ZMVideoSDKChatMessageDeleteType_ByHost | The session host deleted the message. |
ZMVideoSDKChatMessageDeleteType_ByDlp | A Data Loss Prevention (DLP) policy removed the message for violating compliance rules. |
Host control: chat privileges
The session host (or a session manager) can change what kind of chat participants are allowed using changeChatPrivilege. Privilege changes fire onChatPrivilegeChanged on every user's device. Use that callback to enable or disable your composer.
guard let chatHelper = ZMVideoSDK.shared()?.getChatHelper() else { return }
// Read the current privilege (any user).
let privilege = chatHelper.getChatPrivilege()
// Change the privilege (host or manager only).
let result = chatHelper.changeChatPrivilege(.publicly)
if result != .ZMVideoSDKErrors_Success {
// Privilege change was rejected — most commonly because the local
// user isn't the host or manager.
}
ZMVideoSDKChatHelper *chatHelper = [[ZMVideoSDK sharedVideoSDK] getChatHelper];
// Read the current privilege (any user).
ZMVideoSDKChatPrivilegeType privilege = [chatHelper getChatPrivilege];
// Change the privilege (host or manager only).
ZMVideoSDKErrors result = [chatHelper changeChatPrivilege:ZMVideoSDKChatPrivilegeType_Publicly];
if (result != ZMVideoSDKErrors_Success) {
// Privilege change was rejected — most commonly because the local
// user isn't the host or manager.
}
Privilege values
ZMVideoSDKChatPrivilegeType controls what kinds of chat participants can send.
| Value | Effect |
|---|---|
ZMVideoSDKChatPrivilegeType_Unknown | Uninitialized. Should not appear in a real session. |
ZMVideoSDKChatPrivilegeType_Publicly_And_Privately | Participants can send public and private chat. |
ZMVideoSDKChatPrivilegeType_Publicly | Participants can send public chat only. Private messaging is off. |
ZMVideoSDKChatPrivilegeType_No_One | Chat is fully disabled for non-host participants. |
React to privilege changes
Handle onChatPrivilegeChanged and update your composer to match the new privilege.
func onChatPrivilegeChanged(_ chatHelper: ZMVideoSDKChatHelper!, chatPrivilegeType privilege: ZMVideoSDKChatPrivilegeType) {
switch privilege {
case .no_One:
hideChatComposer()
case .publicly:
showComposerWithoutPrivateOption()
case .publicly_And_Privately:
showFullComposer()
default:
break
}
}
- (void)onChatPrivilegeChanged:(ZMVideoSDKChatHelper *)chatHelper chatPrivilegeType:(ZMVideoSDKChatPrivilegeType)privilege {
switch (privilege) {
case ZMVideoSDKChatPrivilegeType_No_One:
[self hideChatComposer];
break;
case ZMVideoSDKChatPrivilegeType_Publicly:
[self showComposerWithoutPrivateOption];
break;
case ZMVideoSDKChatPrivilegeType_Publicly_And_Privately:
[self showFullComposer];
break;
default:
break;
}
}
If you only need a boolean "is chat available right now" check rather than the specific privilege value, the isChatDisabled and isPrivateChatDisabled helpers on ZMVideoSDKChatHelper are easier to read at the call site.