Create message drafts
MessageDraft represents an unpublished message. Use it to:
- Edit text before publishing
- Add channel references, user mentions, and links
- Attach files
Display message elements (mentions, references, links) in your UI by adding a message draft change listener.
- Basics
- Class diagram
- Example
- Internal mention format
Message drafts consist of MessageElement objects, which can be either instances of plainText or link.
plainText elements are simple strings. link elements are used for user mentions, channel references, and URLs. Each link contains text and a reference to the linked element.
Each link implements a MentionTarget interface, which defines the type of mention. Available targets include:
MentionTarget.user(userId: String)MentionTarget.channel(channelId: String)MentionTarget.url(url: String)
Store draft messages locally
Chat SDK does not persist drafts. Implement your own local storage to save drafts across channel switches.
Consider the message Hey, I sent Alex this link on the #offtopic channel. where:
Alexis a reference to the user with the ID ofalex_dlinkis a URL of thewww.pubnub.comwebsite#offtopicis a reference to the channel with the ID ofgroup.offtopic
The list of MessageElement objects returned by the MessageDraftChangeListener is as follows:
By internally leveraging a Markdown-like syntax, the message draft format integrates links directly into the message text using the pattern [link text](link target) understood by the Swift Chat SDK.
| Mention Type | Example |
|---|---|
| user | [John Doe](pn-user://john_doe) |
| channel | [General Chat](pn-channel://group.chat.123) |
| url | [PubNub](https://www.pubnub.com) |
Custom schemas like pn-user:// and pn-channel:// are used to identify user and channel mentions, while traditional URLs are supported as-is.
Adding message elements
You don't use this Markdown-like syntax when adding message elements. It's only a representation of your message elements under the hood.
For more information, refer to Add message element.
Create a draft message
createMessageDraft() creates a message draft (MessageDraft object) that can consist of:
- Plain text
- Files
- Mentioned users
- Referenced channels
- Links
Method signature
This method has the following signature:
1channel.createMessageDraft(
2 userSuggestionSource: UserSuggestionSource = .channel,
3 isTypingIndicatorTriggered: Bool = true,
4 userLimit: Int = 10,
5 channelLimit: Int = 10
6) -> MessageDraftImpl
Input
| Parameter | Description |
|---|---|
userSuggestionSourceType: UserSuggestionSource = .channel or UserSuggestionSource = .globalDefault: UserSuggestionSource = .channel | This parameter refers to the Mentions feature. Data source from which you want to retrieve users. You can choose either the list of channel members (.channel) or users on the app's Admin Portal keyset (.global). |
isTypingIndicatorTriggeredType: BoolDefault: true | This parameter refers to the Typing Indicator feature. Defines if the typing indicator should be enabled when writing the message. |
userLimitType: IntDefault: 10 | This parameter refers to the Mentions feature. Maximum number of usernames (name field from the User object) you can mention in one message. The default value is 10, the min is 1, and max is 100. |
channelLimitType: IntDefault: 10 | This parameter refers to the References feature. Maximum number of channel names (name field from the Channel object) you can reference in one message. The default value is 10, the min is 1, and max is 100. |
Output
| Parameter | Description |
|---|---|
MessageDraftType | Instance of MessageDraftType, which represents a draft version of a message with the content, all links, referenced channels, mentioned users and their names. |
Sample code
Create a draft message containing just plain text.
1
Add message draft change listener
Add a MessageDraftChangeListener to receive draft content changes and suggestions for mentions, channel references, and links.
Method signature
This method has the following signature:
1messageDraft.addChangeListener(_ listener: MessageDraftChangeListener)
2
3public protocol MessageDraftChangeListener: AnyObject {
4 /// Called when there is a change in the message elements or suggested mentions.
5 func onChange(messageElements: [MessageElement], suggestedMentions: any FutureObject<[SuggestedMention]>)
6}
Input
| Parameter | Description |
|---|---|
_ listener | The listener that receives the most current message elements and suggestions list. |
MessageDraftChangeListener
| Parameter | Description |
|---|---|
onChange(messageElements: [MessageElement], suggestedMentions: any FutureObject<[SuggestedMention]>)Type: function |
|
SuggestedMention
A SuggestedMention represents a potential mention suggestion received from MessageDraftChangeListener.
| Parameter | Description |
|---|---|
offsetType: Int | The position from the start of the message draft where the message elements starts. It's counted from the beginning of the message (including spaces), with 0 as the first character. |
replaceFromType: String | The original text at the given offset in the message draft text. |
replaceWithType: String | The suggested replacement for the replaceFrom text. |
targetType: MentionTarget | The message element type. Available types include:
|
Output
This method doesn't return any data.
Sample code
Add the listener to your message draft.
1
Remove message draft change listener
Remove a previously added MessageDraftChangeListener.
Method signature
This method has the following signature:
1messageDraft.removeChangeListener(_ listener: MessageDraftChangeListener)
Input
| Parameter | Description |
|---|---|
_ listener | The listener to remove. |
Output
This method doesn't return any data.
Sample code
Remove a listener from your message draft.
1// Create a message draft.
2// Assuming you have a reference of type "ChannelImpl" named "channel"
3let messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered: channel.type != .public)
4// Define the listener
5let listener = ClosureMessageDraftChangeListener() { elements, suggestedMentions in
6 // updateUI(with:) is your own function for updating UI
7 updateUI(with: elements)
8
9 suggestedMentions.async { result in
10 switch result {
11 case .success(let mentions):
12 // updateSuggestions(with:) is your own function for displaying suggestions
13 updateSuggestions(with: mentions)
14 case .failure(let error):
15 print("Error retrieving suggestions: \(error)")
show all 23 linesAdd message element
addMention() adds a user mention, channel reference or a link specified by a mention target at a given offset.
Method signature
This method has the following signature:
1messageDraft.addMention(
2 offset: Int,
3 length: Int,
4 target: MentionTarget
5)
Input
| Parameter | Description |
|---|---|
offset *Type: IntDefault: n/a | Position of a character in a message where the message element you want to insert starts. It's counted from the beginning of the message (including spaces), with 0 as the first character. |
length *Type: IntDefault: n/a | Number of characters the message element should occupy in the draft message's text. |
target *Type: MentionTargetDefault: n/a | Message element type. Available types include:
|
Output
This method returns no output data.
Sample code
Create the Hello Alex! I have sent you this link on the #offtopic channel. message where Alex is a user mention, link is a URL, and #offtopic is a channel reference.
1
Remove message element
removeMention() removes a user mention, channel reference, or a link at a given offset.
Method signature
This method has the following signature:
1messageDraft.removeMention(offset: Int)
Input
| Parameter | Description |
|---|---|
offset *Type: IntDefault: n/a | Position of the first character of the message element you want to remove. |
Offset value
If you don't provide the position of the first character of the message element to remove, it isn't removed.
Output
This method returns no output data.
Sample code
Remove the URL element from the word link in the Hello Alex! I have sent you this link on the #offtopic channel. message.
1
Update message text
update() replaces the text of a draft message with new content.
Removing message elements
The SDK preserves message elements when possible. If element text is modified, that element is removed.
Method signature
This method has the following signature:
1messageDraft.update(text: String)
Input
| Parameter | Description |
|---|---|
text *Type: stringDefault: n/a | Text of the message that you want to update. |
Output
This method returns no output data.
Sample code
Change the message I sent Alex this picture. to I did not send Alex this picture. where Alex is a user mention.
1
Mention text changes
Changing mention text removes that mention. For finer control, use Insert message text and Remove message text.
Insert suggested message element
Insert a message element from the MessageDraftChangeListener into the MessageDraft object.
Text must match
SuggestedMention.replaceFrom must match the draft text at the specified position, or an exception is thrown.
Method signature
This method has the following signature:
1messageDraft.insertSuggestedMention(
2 mention: SuggestedMention,
3 text: String
4)
Input
| Parameter | Description |
|---|---|
mention *Type: SuggestedMentionDefault: n/a | A user, channel, or URL suggestion obtained from MessageDraftChangeListener. |
text |