Skip to content

Message storage

Davor Komušanac edited this page Dec 5, 2022 · 12 revisions

Mobile Messaging SDK can utilize the Message Storage to store incoming (mobile terminated) or outgoing (mobile originated) messages. Although the default message storage (MMDefaultMessageStorage class) is implemented within the SDK, it is also possible for you to provide your own custom message storage. The custom implementation requires the conformance with the MessageStorage protocol:

/// The protocol describes implementation of the Message Storage. The Message Storage persists all the messages (both mobile originated and mobile terminated).
@objc public protocol MMMessageStorage {
	/// The queue in which all the hooks(inserts, updates) are dispatched.
	/// The queue must be provided by the particular implementation of this protocol in order to provide thread safety and performance aspects.
	var queue: dispatch_queue_t {get}
	
	/// This method is called by the Mobile Messaging SDK during the initialization process. You implement your custom preparation routine here if needed.
	func start()
	
	/// This method is called by the Mobile Messaging SDK while stopping the currently running session (see also `MobileMessaging.stop()` method). You implement your custom deinitialization routine here if needed.
	func stop()
	
	/// This method is called whenever a new mobile originated message is about to be sent to the server.
	func insert(outgoing messages: [MM_MOMessage])
	
	/// This method is called whenever a new mobile terminated message (either push/remote notifictaion or fetched message) is received by the Mobile Messaging SDK.
	func insert(incoming messages: [MM_MTMessage])
	
	/// This method is used by the Mobile Messaging SDK in order to detect duplicated messages persisted in the Message Storage. It is strongly recommended to implement this method in your custom Message Storage.
	/// - parameter messageId: unique identifier of a MT message. Consider this identifier as a primary key.
	func findMessage(withId messageId: MessageId) -> MMBaseMessage?
	
	/// This method is called whenever the seen status is updated for a particular mobile terminated (MT) message.
	/// - parameter status: actual seen status for a message
	/// - parameter messageId: unique identifier of a MT message
	func update(messageSeenStatus status: MMSeenStatus, for messageId: MessageId)
	
	/// This method is called whenever the delivery report is updated for a particular mobile terminated (MT) message.
	/// - parameter isDelivered: boolean flag which defines whether the delivery report for a message was successfully sent
	/// - parameter messageId: unique identifier of a MT message
	func update(deliveryReportStatus isDelivered: Bool, for messageId: MessageId)
	
	/// This method is called whenever the sending status is updated for a particular mobile originated (MO) message.
	/// - parameter status: actual sending status for a MO message
	/// - parameter messageId: unique identifier of a MO message
	func update(messageSentStatus status: MM_MOMessageSentStatus, for messageId: MessageId)
}

Setting up the message storage

By default, Mobile Messaging SDK doesn't utilize any message storage. In order to set up the SDK to use the default message storage, call the withDefaultMessageStorage() method within the constructor chain while starting the Mobile Messaging session, for example:

// Swift
MobileMessaging.withApplicationCode(<# application code #>, notificationType: <# notification type #>).withDefaultMessageStorage().start()
// Objective-C
[[[MobileMessaging withApplicationCode: <# application code #> notificationType: <# notification type #>] withDefaultMessageStorage] start: nil];

In order to provide the Mobile Messaging SDK with your own custom implementation of the message storage, use following method:

// Swift
MobileMessaging.withApplicationCode(<# application code #>, notificationType: <# notification type #>).withMessageStorage(<# your custom message storage #>).start()
// Objective-C
[[[MobileMessaging withApplicationCode: <# application code #> notificationType: <# notification type #>] withMessageStorage: <# your custom message storage #>] start: nil];

Using the default message storage

The default message storage has a set of convenient methods for accessing messages data:

var messagesCountersUpdateHandler: ((Int, Int) -> Void)?
func countAllMessages(completion: @escaping (Int) -> Void)
func findAllMessages(completion: FetchResultBlock)
func findMessages(withIds messageIds: [MessageId], completion: FetchResultBlock)
func findMessages(withQuery query: MMQuery, completion: FetchResultBlock)

and for removing messages:

func removeAllMessages()
func remove(withIds messageIds: [MessageId])
func remove(withQuery query: MMQuery)

For more information about the Message Storage see the in-code documentation for MMMessageStorage protocol, MMQuery class, MMMessageStorageDelegate protocol, MMMessageStorageFinders protocol, MMMessageStorageRemovers protocol. Default Core Data message storage implementation MMDefaultMessageStorage.

Using queries for filtering and sorting

Query object is used to set up filtering, pagination and sorting for fetched messages data.

Sorting messages by timestamp:

let q = MMQuery()
q.sortDescriptors = [NSSortDescriptor(key: "createdDate", ascending: false)]
MobileMessaging.defaultMessageStorage?.findMessages(withQuery: q) { results in
    // handle fetched messages
}

Filtering out messages that were seen:

let q = MMQuery()
q.predicate = NSPredicate(format: "seenStatusValue == \(MMSeenStatus.NotSeen.rawValue)")
MobileMessaging.defaultMessageStorage?.findMessages(withQuery: q) { results in
    // handle fetched messages
}
Clone this wiki locally