Guides
Guides

Android: Coroutines

Description on using the SDK asynchronous functionality from Kotlin Coroutines

From version 16.0.0 the Android SDK has extension methods added to the Marigold and MessageStream classes to allow asynchronous functionality to be accessed in a suspendible way from coroutines. Each piece of functionality has two variations, one will return a Result containing the outcome of the call, the other will return desired value or throw an exception if there is an error. Use whichever one best fits your use-case!

Coroutine Extensions

Marigold Extensions:

// Get Device ID
val deviceId = Marigold().getDeviceId()
// or
val deviceId = Marigold().getDeviceIdResult().getOrElse { error ->
    // Handle error
    null
}

// Clear Device
Marigold().clearDevice(Marigold.EVENTS)
// or
Marigold().clearDeviceResult(Marigold.EVENTS).onFailure { error ->
    // Handle error
}

// Enable/Disable Geo IP
Marigold().setGeoIPTrackingEnabled(true)
// or
Marigold().setGeoIPTrackingEnabledResult(true).onFailure { error ->
    // Handle error
}

// Get Recommendations
val recommendations = Marigold().getRecommendations("SECTION_ID")
// or
val recommendations = Marigold().getRecommendationsResult("SECTION_ID").getOrElse { error ->
    // Handle error
    null
}

// Remove Attribute
Marigold().removeDeviceAttribute("ATTRIBUTE_KEY")
// or
Marigold().removeDeviceAttributeResult("ATTRIBUTE_KEY").onFailure { error ->
    // Handle error
}

EngageBySailthru Extensions:

// Clear Attributes
EngageBySailthru().clearAttributes()
// or
EngageBySailthru().clearAttributesResult().onFailure { error ->
    // Handle error
}

// Set User Email
EngageBySailthru().setUserEmail("USER_EMAIL")
// or
EngageBySailthru().setUserEmailResult("USER_EMAIL").onFailure { error ->
    // Handle error
}

// Set User ID
EngageBySailthru().setUserId("USER_ID")
// or
EngageBySailthru().setUserIdResult("USER_ID").onFailure { error ->
    // Handle error
}

// Track Pageview
EngageBySailthru().trackPageview("USER_EMAIL")
// or
EngageBySailthru().trackPageviewResult("USER_EMAIL").onFailure { error ->
    // Handle error
}

// Track Impression
EngageBySailthru().trackImpression("SECTION_ID", listOf(URI("www.example.com/page1"), URI("www.example.com/page2")))
// or
EngageBySailthru().trackImpressionResult("SECTION_ID", listOf(URI("www.example.com/page1"), URI("www.example.com/page2"))).onFailure { error ->
    // Handle error
}

// Track Click
EngageBySailthru().trackClick("SECTION_ID", URI("www.example.com"))
// or
EngageBySailthru().trackClickResult("SECTION_ID", URI("www.example.com")).onFailure { error ->
    // Handle error
}

// Set Attributes
val attributeMap = AttributeMap().apply {
  putString("hello", "there")
}
EngageBySailthru().setAttributes(attributeMap)
// or
EngageBySailthru().setAttributesResult(attributeMap).onFailure { error ->
    // Handle error
}

// Set Profile Vars
val profileVars = JSONObject().apply { 
  put("hello", "there")
}
EngageBySailthru().setProfileVars(profileVars)
// or
EngageBySailthru().setProfileVarsResult(profileVars).onFailure { error ->
    // Handle error
}

// Get Profile Vars
val profileVars = EngageBySailthru().getProfileVars()
// or
val profileVars = EngageBySailthru().getProfileVarsResult().getOrElse { error ->
    // Handle error
    null
}

// Log Purchase
val purchaseItem = PurchaseItem(1, "item", 1234, "item12345", URI("www.example.com/item12345"))
val purchase = Purchase(arrayListOf(purchaseItem))
EngageBySailthru().logPurchase(purchase)
// or
EngageBySailthru().logPurchaseResult(purchase).onFailure { error ->
    // Handle error
}

// Log Abandoned Cart
val purchaseItem = PurchaseItem(1, "item", 1234, "item12345", URI("www.example.com/item12345"))
val purchase = Purchase(arrayListOf(purchaseItem))
EngageBySailthru().logAbandonedCart(purchase)
// or
EngageBySailthru().logAbandonedCartResult(purchase).onFailure { error ->
    // Handle error
}

// Handle Sailthru Link
val parsedLink = EngageBySailthru().handleSailthruLink(Uri.parse("SAILTHRU_LINK"))
// or
val parsedLink = EngageBySailthru().handleSailthruLinkResult(Uri.parse("SAILTHRU_LINK")).getOrElse { error ->
    // Handle error
    null
}

MessageStream extensions:

// Get Messages
val messages = MessageStream().getMessages()
// or
val messages = MessageStream().getMessagesResult().getOrElse { error ->
    // Handle error
    arrayListOf()
}

// Get Message
val message = MessageStream().getMessage("MESSAGE_ID")
// or
val message = MessageStream().getMessageResult("MESSAGE_ID").getOrElse { error ->
    // Handle error
    null
}

// Delete Message
MessageStream().deleteMessage(message)
// or
MessageStream().deleteMessageResult(message).onFailure { error ->
    // Handle error
}

// Get Unread Count
val unreadCount = MessageStream().getUnreadMessageCount()
// or
val unreadCount = MessageStream().getUnreadMessageCountResult().getOrElse { error ->
    // Handle error
    null
}

// Set Message Read
MessageStream().setMessageRead(message)
// or
MessageStream().setMessageReadResult(message).onFailure { error ->
    // Handle error
}

// Set Messages Read
MessageStream().setMessagesRead(messages)
// or
MessageStream().setMessagesReadResult(messages).onFailure { error ->
    // Handle error
}

Flows

We have also added flows as an alternative to providing listener implementations to the SDK to handle events. For the NotificationReceived, NotificationTapped and NotificationActionTapped events you can now instead subscribe to these SharedFlow instances to process the events (note that subscribing to the flows will block the current coroutine, so you should launch a separate coroutine for each subscriber).

launch {
  Marigold().notificationReceivedFlow.collect { (context, bundle) ->
      // Handle received event
  }
}

launch {
  Marigold().notificationTappedFlow.collect { (context, bundle) ->
      // Handle tapped event
  }
}

launch {
  Marigold().notificationActionTappedFlow.collect { (context, bundle, actionTapped) ->
      // Handle action tapped event
  }
}