let utils = Utils(
messageListConfig: MessageListConfig(draftMessagesEnabled: true)
)
let streamChat = StreamChat(chatClient: chatClient, utils: utils)
Draft Messages
The SwiftUI SDK provides a way to create and manage draft messages.
Drafts are disabled by default. In order to enable this feature, you need to enable the draftMessagesEnabled
flag when initializing Utils
.
Drafts on SwiftUI are available since version 4.75.0.
Draft messages are synchronized across devices and work seamlessly offline as well.
Basic Usage
When draft messages are enabled, the logic of saving and deleting drafts will be handled automatically by the SDK. When a user starts typing a message and then navigates away from the conversation, the message content is automatically saved as a draft, for both Channels and Threads.
When the user returns to the conversation, the draft message will be loaded automatically into the composer. If the user clears the composer content or publishes the message, the draft will be deleted.
The draft messages user flow is described in the following diagram:
flowchart LR
A[User Action]
A -->|Leave Channel| F[Update Channel Draft]
A -->|Leave Thread| E[Update Thread Draft]
A -->|Clear Composer Content| D[Delete Draft]
A -->|Publish Message| D[Delete Draft]
Customization
By default, the only additional UI added to the SDK when drafts are enabled is a preview of the draft message in the channel list and thread list. When a draft is saved, the draft message is shown in the channel list and thread list until the message is published or deleted.
The channel draft preview is displayed in the ChatChannelListItem
when thechannel.draftMessage
exists, and the thread draft preview is displayed in the ChatThreadListItem
when the thread.parentMessage.draftReply
exists.
You can customize the drafts preview by swapping the ChatChannelListItem
and ChatThreadListItem
components through the ViewFactory.makeChannelListItem()
and the ViewFactory.makeThreadListItem()
methods, respectively.
Draft List Query
At the moment, the SDK does not provide a default UI component to render the list of drafts from the current user. However, you can easily build your own component by using the ChatClient.shared.currentUserController()
to fetch the drafts.
The current user controller has a loadDraftMessages()
method that is responsible to query the drafts. It accepts a query: DraftListQuery
parameter that allows you to customize the query.
The DraftListQuery
has the following properties:
pagination
: The initial pagination information. By default isPagination(pageSize: 25, offset: 0)
sorting
: The sorting criteria for the drafts. By default is[.init(key: .createdAt, isAscending: false)]
Fetching Drafts
Below is an example on how to fetch the drafts with the default query:
// Load the draft messages for the current user
let currentUserController = chatClient.currentUserController()
currentUserController.loadDraftMessages { result in
switch result {
case .success(let drafts):
print("Draft messages loaded: \(drafts)")
case .failure(let error):
print("Failed to load draft messages: \(error)")
}
}
Pagination
In case the currentUserController.hasLoadedAllDrafts
is false
, you can load the next page of drafts by calling currentUserController.loadMoreDraftMessages()
. This method has an optional completion handler that will be called when the page finishes loading.
currentUserController.loadMoreDraftMessages { result in
switch result {
case .success(let drafts):
print("Draft messages loaded: \(drafts)")
case .failure(let error):
print("Failed to load more draft messages: \(error)")
}
}
Delegate
Whenever the drafts are updated or deleted, the CurrentChatUserControllerDelegate
will be notified in the following function:
func currentUserController(
_ controller: CurrentChatUserController,
didChangeDraftMessages draftMessages: [DraftMessage]
)
To see a full drafts list example implementation, you can check our Demo App example here. It is in UIKit, but should give you an idea on how to implement the same logic in SwiftUI.
Draft Events
By default, the SDK will react whenever a draft is updated or deleted. But, in case your app needs additional logic, these are the available draft events:
DraftUpdatedEvent
: Triggered when a draft is updated.DraftDeletedEvent
: Triggered when a draft is deleted.