Message sync
This page provides an overview of how messages can be synchronized by using the SBSMMessageCollection
together with other classes. The SBSMMessageCollection
is a class that subscribes to message-related events through the SBSMMessageCollectionDelegate
. The delegate listens to cached events and real-time events in order to direct the way of view implementation.
For example, if SyncManager receives a real-time event that a message has been deleted, it creates a collection event which has the remove action for the message and delivers it to the collection delegate. At the same time, cached events are also given to the delegate. The collection automatically fetches messages from the cache and delivers a collection event which has the insert action for the message to the collection delegate.
Initialization
The following shows how to initialize and use a SBSMMessageCollection
instance:
In the above code sample, the collection instance sets the collection delegate to listen to message events and call the fetchSucceededMessage
method after initialization. At runtime, according to your caching status, the insert event can return multiple times. The first few events are called to fetch the messages from the local cache. If not enough messages are cached, SyncManager waits until background sync synchronizes with the server before delivering the rest of the messages. Then, you may get more events with those messages.
Viewpoint
A viewpoint
is a timestamp option that sets the starting point of the current user’s view. The default value is the LLONG_MAX
, which means that the user sees the most recent messages in the chat room. If the viewpoint is set to the middle of the conversation, then the view starts from the middle of the conversation to enable the user to scroll up and down to see the previous and next messages. The viewpoint can be set at initialization, and can be reset anytime by calling the resetViewpointTimestamp
method.
Direction
The direction
parameter denotes direction and is provided by the SBSMMessageCollection
’s fetchInDirection
. The collection can fetch messages from two directions: previous and next. Previous messages are fetched in the direction of past messages, while next messages are fetched in the direction of the most recent, real-time messages.
Real-time events
SyncManager listens to real-time events from the Chat SDK in order to apply changes and notify the current user. Below is the list of real-time message events that SyncManager listens to through the SBSMMessageCollectionDelegate
's didReceiveEventAction:
callback method:
Real-time message events
Event | Action with description |
---|---|
channel:didReceiveMessage: |
|
channel:didUpdateMessage: |
|
channel:messageWasDeleted: |
|
Note: The collection has an array that holds all the messages that should be shown in the view. If a message isn’t shown in the view, it means that the collection isn’t holding it because background sync synchronization hasn’t been completed at that time.
fetchInDirection method
The fetchInDirection
method fetches messages from the local cache and delivers them to the delegate. If not enough messages are cached, it waits until background sync synchronizes with Sendbird server before bringing the retrieved messages. The fetchInDirection
should be called when:
- A collection is created.
- A connection is established.
- The app goes to the foreground.
- The scroll reaches the top or the bottom.
- The app returns from a locked screen when still in the foreground.
The fetchInDirection
subscribes to background sync to pull data from the local cache. As this method doesn’t directly interact with Sendbird server, while online, it waits until background sync synchronizes data in the server to the cache before retrieving new data. However, after synchronization is completed by background sync, the fetchInDirection
can refresh the view with new data. Therefore, the fetchInDirection
can not only read cached data, but also update data in the view.
The fetchAllNextMessages
behaves similarly to fetchInDirection(SBSMMessageDirectionNext)
, except it fetches the most recent messages, regardless of the fetch limit set in the SBSMMessageCollection
instance. This method can be used to fetch messages when a user, who had scrolled to the bottom of the screen and was looking at the most recent messages, comes online.
The method to fetch messages when a user comes online from offline should depend on their scroll point. Regardless of whether the user is connecting to a network, coming to the foreground from the background, or turning on their screen, this should be implemented in the SBDConnectionDelegate
, which listens for state changes from offline to online.
Message lifecycle
Once a message is created, it has its own lifecycle. When a message has been sent but not yet received any response from Sendbird server through its callback, the requestState
of the message is pending
. Once the server responds, the requestState
of the message is set as succeeded
or failed
. SyncManager internally keeps track of the request state of a message so as to update the view accordingly.
For each requestState, a message in a view can be displayed as follows:
pending
: displays the message content with a progress animation.failed
: displays the message content with a context menu such as resend or delete.succeeded
: displays the message content with its read receipt.
Note: Pending and failed messages temporarily have a
messageId
of 0. When they are successfully sent to the server, they get their own unique message ID, and are delivered and replaced as succeeded messages in the collection delegate by theirreqId
. The purpose of areqId
is to ensure messages are listed in the order of their time sent.
Send a message
As messages are sent by the Chat SDK, SyncManager cannot check whether a message has been successfully sent. Therefore, the SBSMMessageCollection
provides the handleSendMessageResponse
block so that SyncManager recognizes the delivery status.
The handleSendMessageResponse
block conducts different jobs based on the set message resend policy. Below is the the list of acceptable values:
Acceptable values
Value | Description |
---|---|
none | If delivery succeeded: performs the remove event for the pending message and the insert event for the succeeded message. |
manual | If delivery succeeded: performs the remove event for the pending message and the insert event for the succeeded message. |
automatic | If delivery succeeded: performs the remove event for the pending event and the insert event for the succeeded message. |
Update a message
As previously mentioned, SyncManager can't check whether a message has been successfully sent because messages are sent through the Chat SDK. Therefore, the SBSMMessageCollection
provides the updateMessage
method so that SyncManager recognizes the delivery status.
Note: Only succeeded messages can be updated.
Remove a message
Messages can be deleted using the deleteMessage
method in the Chat SDK.
Handle a failed message
According to the request state, the SBSMMessageCollectionDelegate
instance listens to message events through the following callbacks:
Message event callbacks
Event callback | Message delivery status & how SyncManager handles a message |
---|---|
collection:didReceiveEventAction:succeededMessages: |
|
collection:didReceiveEventAction:pendingMessages: |
|
collection:didReceiveEventAction:failedMessages: |
|
Suppose that a new message is requested and successfully sent. In order for this to happen, the insert event should be given to the collection:didReceiveEventAction:pendingMessages:
first. Once the message delivery status is determined as succeeded
via the callback, the remove event is given to the collection:didReceiveEventAction:pendingMessages:
while the insert event is also given to the collection:didReceiveEventAction:succeededMessages:
.
Fetch pending messages
A pending message is a message that hasn't been sent or hasn't been resolved as a success or a failure. A pending message is created when the app is closed before the message is resolved. Then SyncManager saves the message state and resolves it later.
Background sync
SyncManager resolves pending messages through a background sync. It is a process where SyncManager compares and matches message data in the local cache with that in Sendbird server.
SyncManager resolves pending messages in the local cache as a success when it confirms matching messages in Sendbird server. If not, SyncManager resolves them as a failure.
The fetchPendingMessages:
method fetches pending messages from the local cache. Depending on their message state, different message events are delivered to different callback methods.
Message events
Message state | Event | Callback method |
---|---|---|
Pending messages exist |
|
|
Pending messages are successfully sent |
|
|
Pending messages definitely failed |
|
|
Pending messages are resolved |
|
|
Note: It is recommended that the
fetchPendingMessages:
method be called after theSBSMMessageCollection
instantiation so that aSBSMMessageCollection
instance can include pending message events created before the instantiation.
Close the view
As the message list view is closed, the SBSMMessageCollection
instance should be cleared. A SBSMMessageCollection
has the remove
method, which clears all the messages managed by the collection and stops synchronization processes in the collection. If the collection isn’t explicitly dropped, the applicable memory won’t be released and could lead to performance slowdown.