{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","settings":"","results":{"codes":[]},"params":[]},"next":{"description":"","pages":[]},"title":"Android: Coroutines","type":"basic","slug":"android-coroutines","excerpt":"Description on using the SDK asynchronous functionality from Kotlin Coroutines","body":"From version 16.0.0 the Android SDK has extension methods added to the `SailthruMobile` 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!\n\n## Coroutine Extensions\n`SailthruMobile` Extensions:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Get Device ID\\nval deviceId = SailthruMobile().getDeviceId()\\n// or\\nval deviceId = SailthruMobile().getDeviceIdResult().getOrElse { error ->\\n    // Handle error\\n    null\\n}\\n\\n// Clear Device\\nSailthruMobile().clearDevice(SailthruMobile.EVENTS)\\n// or\\nSailthruMobile().clearDeviceResult(SailthruMobile.EVENTS).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Set User ID\\nSailthruMobile().setUserId(\\\"USER_ID\\\")\\n// or\\nSailthruMobile().setUserIdResult(\\\"USER_ID\\\").onFailure { error ->\\n    // Handle error\\n}\\n\\n// Set User Email\\nSailthruMobile().setUserEmail(\\\"USER_EMAIL\\\")\\n// or\\nSailthruMobile().setUserEmailResult(\\\"USER_EMAIL\\\").onFailure { error ->\\n    // Handle error\\n}\\n\\n// Enable/Disable Geo IP\\nSailthruMobile().setGeoIPTrackingEnabled(true)\\n// or\\nSailthruMobile().setGeoIPTrackingEnabledResult(true).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Get Recommendations\\nval recommendations = SailthruMobile().getRecommendations(\\\"SECTION_ID\\\")\\n// or\\nval recommendations = SailthruMobile().getRecommendationsResult(\\\"SECTION_ID\\\").getOrElse { error ->\\n    // Handle error\\n    null\\n}\\n\\n// Track Pageview\\nSailthruMobile().trackPageview(URI(\\\"www.example.com\\\"), listOf(\\\"tag1, tag2\\\"))\\n// or\\nSailthruMobile().trackPageviewResult(URI(\\\"www.example.com\\\"), listOf(\\\"tag1, tag2\\\")).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Track Impression\\nSailthruMobile().trackImpression(\\\"SECTION_ID\\\", listOf(URI(\\\"www.example.com/page1\\\"), URI(\\\"www.example.com/page2\\\")))\\n// or\\nSailthruMobile().trackImpressionResult(\\\"SECTION_ID\\\", listOf(URI(\\\"www.example.com/page1\\\"), URI(\\\"www.example.com/page2\\\"))).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Track Click\\nSailthruMobile().trackClick(\\\"SECTION_ID\\\", URI(\\\"www.example.com\\\"))\\n// or\\nSailthruMobile().trackClickResult(\\\"SECTION_ID\\\", URI(\\\"www.example.com\\\")).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Set Attributes\\nval attributeMap = AttributeMap().apply {\\n  putString(\\\"hello\\\", \\\"there\\\")\\n}\\nSailthruMobile().setAttributes(attributeMap)\\n// or\\nSailthruMobile().setAttributesResult(attributeMap).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Remove Attribute\\nSailthruMobile().removeDeviceAttribute(\\\"ATTRIBUTE_KEY\\\")\\n// or\\nSailthruMobile().removeDeviceAttributeResult(\\\"ATTRIBUTE_KEY\\\").onFailure { error ->\\n    // Handle error\\n}\\n\\n// Set Profile Vars\\nval profileVars = JSONObject().apply { \\n  put(\\\"hello\\\", \\\"there\\\")\\n}\\nSailthruMobile().setProfileVars(profileVars)\\n// or\\nSailthruMobile().setProfileVarsResult(profileVars).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Get Profile Vars\\nval profileVars = SailthruMobile().getProfileVars()\\n// or\\nval profileVars = SailthruMobile().getProfileVarsResult().getOrElse { error ->\\n    // Handle error\\n    null\\n}\\n\\n// Log Purchase\\nval purchaseItem = PurchaseItem(1, \\\"item\\\", 1234, \\\"item12345\\\", URI(\\\"www.example.com/item12345\\\"))\\nval purchase = Purchase(arrayListOf(purchaseItem))\\nSailthruMobile().logPurchase(purchase)\\n// or\\nSailthruMobile().logPurchaseResult(purchase).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Log Abandoned Cart\\nval purchaseItem = PurchaseItem(1, \\\"item\\\", 1234, \\\"item12345\\\", URI(\\\"www.example.com/item12345\\\"))\\nval purchase = Purchase(arrayListOf(purchaseItem))\\nSailthruMobile().logAbandonedCart(purchase)\\n// or\\nSailthruMobile().logAbandonedCartResult(purchase).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Handle Sailthru Link\\nval parsedLink = SailthruMobile().handleSailthruLink(Uri.parse(\\\"SAILTHRU_LINK\\\"))\\n// or\\nval parsedLink = SailthruMobile().handleSailthruLinkResult(Uri.parse(\\\"SAILTHRU_LINK\\\")).getOrElse { error ->\\n    // Handle error\\n    null\\n}\\n\\n\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\n`MessageStream` extensions:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Get Messages\\nval messages = MessageStream().getMessages()\\n// or\\nval messages = MessageStream().getMessagesResult().getOrElse { error ->\\n    // Handle error\\n    arrayListOf()\\n}\\n\\n// Get Message\\nval message = MessageStream().getMessage(\\\"MESSAGE_ID\\\")\\n// or\\nval message = MessageStream().getMessageResult(\\\"MESSAGE_ID\\\").getOrElse { error ->\\n    // Handle error\\n    null\\n}\\n\\n// Delete Message\\nMessageStream().deleteMessage(message)\\n// or\\nMessageStream().deleteMessageResult(message).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Get Unread Count\\nval unreadCount = MessageStream().getUnreadMessageCount()\\n// or\\nval unreadCount = MessageStream().getUnreadMessageCountResult().getOrElse { error ->\\n    // Handle error\\n    null\\n}\\n\\n// Set Message Read\\nMessageStream().setMessageRead(message)\\n// or\\nMessageStream().setMessageReadResult(message).onFailure { error ->\\n    // Handle error\\n}\\n\\n// Set Messages Read\\nMessageStream().setMessagesRead(messages)\\n// or\\nMessageStream().setMessagesReadResult(messages).onFailure { error ->\\n    // Handle error\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\n## Flows\nWe 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).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"launch {\\n  SailthruMobile().notificationReceivedFlow.collect { (context, bundle) ->\\n      // Handle received event\\n  }\\n}\\n\\nlaunch {\\n  SailthruMobile().notificationTappedFlow.collect { (context, bundle) ->\\n      // Handle tapped event\\n  }\\n}\\n\\nlaunch {\\n  SailthruMobile().notificationActionTappedFlow.collect { (context, bundle, actionTapped) ->\\n      // Handle action tapped event\\n  }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]","updates":[],"order":5,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"61f35bf3d14481028afc5135","createdAt":"2022-01-28T02:58:59.800Z","user":"5b0b7a46a26e6400036604fd","category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"Android Techniques","slug":"android-techniques","order":9999,"from_sync":false,"reference":false,"_id":"5e69868cbd5dcb006b35867b","createdAt":"2020-03-12T00:47:08.696Z","version":"5e6156bf5e4a51006dcd818c","project":"55e67aaa9cc7c62b00c4a1ea","__v":0},"version":{"version":"1.5","version_clean":"1.5.0","codename":"ST Rebrand","is_stable":true,"is_beta":false,"is_hidden":false,"is_deprecated":false,"categories":["5e6156bf5e4a51006dcd8120","5e6156bf5e4a51006dcd8121","5e6156bf5e4a51006dcd8122","5e6156bf5e4a51006dcd8123","5e6156bf5e4a51006dcd8124","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","5e6156bf5e4a51006dcd8125","5e6156bf5e4a51006dcd8126","5af0fe494ca2730003cbc98a","5af0fe55ec80af0003804ca2","5e69868cbd5dcb006b35867b","5e6986ca2c6652006791b6e8"],"_id":"5e6156bf5e4a51006dcd818c","project":"55e67aaa9cc7c62b00c4a1ea","__v":2,"forked_from":"5b720760c44b7600034b7a08","createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z"},"project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"parentDoc":null}

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 `SailthruMobile` 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 `SailthruMobile` Extensions: [block:code] { "codes": [ { "code": "// Get Device ID\nval deviceId = SailthruMobile().getDeviceId()\n// or\nval deviceId = SailthruMobile().getDeviceIdResult().getOrElse { error ->\n // Handle error\n null\n}\n\n// Clear Device\nSailthruMobile().clearDevice(SailthruMobile.EVENTS)\n// or\nSailthruMobile().clearDeviceResult(SailthruMobile.EVENTS).onFailure { error ->\n // Handle error\n}\n\n// Set User ID\nSailthruMobile().setUserId(\"USER_ID\")\n// or\nSailthruMobile().setUserIdResult(\"USER_ID\").onFailure { error ->\n // Handle error\n}\n\n// Set User Email\nSailthruMobile().setUserEmail(\"USER_EMAIL\")\n// or\nSailthruMobile().setUserEmailResult(\"USER_EMAIL\").onFailure { error ->\n // Handle error\n}\n\n// Enable/Disable Geo IP\nSailthruMobile().setGeoIPTrackingEnabled(true)\n// or\nSailthruMobile().setGeoIPTrackingEnabledResult(true).onFailure { error ->\n // Handle error\n}\n\n// Get Recommendations\nval recommendations = SailthruMobile().getRecommendations(\"SECTION_ID\")\n// or\nval recommendations = SailthruMobile().getRecommendationsResult(\"SECTION_ID\").getOrElse { error ->\n // Handle error\n null\n}\n\n// Track Pageview\nSailthruMobile().trackPageview(URI(\"www.example.com\"), listOf(\"tag1, tag2\"))\n// or\nSailthruMobile().trackPageviewResult(URI(\"www.example.com\"), listOf(\"tag1, tag2\")).onFailure { error ->\n // Handle error\n}\n\n// Track Impression\nSailthruMobile().trackImpression(\"SECTION_ID\", listOf(URI(\"www.example.com/page1\"), URI(\"www.example.com/page2\")))\n// or\nSailthruMobile().trackImpressionResult(\"SECTION_ID\", listOf(URI(\"www.example.com/page1\"), URI(\"www.example.com/page2\"))).onFailure { error ->\n // Handle error\n}\n\n// Track Click\nSailthruMobile().trackClick(\"SECTION_ID\", URI(\"www.example.com\"))\n// or\nSailthruMobile().trackClickResult(\"SECTION_ID\", URI(\"www.example.com\")).onFailure { error ->\n // Handle error\n}\n\n// Set Attributes\nval attributeMap = AttributeMap().apply {\n putString(\"hello\", \"there\")\n}\nSailthruMobile().setAttributes(attributeMap)\n// or\nSailthruMobile().setAttributesResult(attributeMap).onFailure { error ->\n // Handle error\n}\n\n// Remove Attribute\nSailthruMobile().removeDeviceAttribute(\"ATTRIBUTE_KEY\")\n// or\nSailthruMobile().removeDeviceAttributeResult(\"ATTRIBUTE_KEY\").onFailure { error ->\n // Handle error\n}\n\n// Set Profile Vars\nval profileVars = JSONObject().apply { \n put(\"hello\", \"there\")\n}\nSailthruMobile().setProfileVars(profileVars)\n// or\nSailthruMobile().setProfileVarsResult(profileVars).onFailure { error ->\n // Handle error\n}\n\n// Get Profile Vars\nval profileVars = SailthruMobile().getProfileVars()\n// or\nval profileVars = SailthruMobile().getProfileVarsResult().getOrElse { error ->\n // Handle error\n null\n}\n\n// Log Purchase\nval purchaseItem = PurchaseItem(1, \"item\", 1234, \"item12345\", URI(\"www.example.com/item12345\"))\nval purchase = Purchase(arrayListOf(purchaseItem))\nSailthruMobile().logPurchase(purchase)\n// or\nSailthruMobile().logPurchaseResult(purchase).onFailure { error ->\n // Handle error\n}\n\n// Log Abandoned Cart\nval purchaseItem = PurchaseItem(1, \"item\", 1234, \"item12345\", URI(\"www.example.com/item12345\"))\nval purchase = Purchase(arrayListOf(purchaseItem))\nSailthruMobile().logAbandonedCart(purchase)\n// or\nSailthruMobile().logAbandonedCartResult(purchase).onFailure { error ->\n // Handle error\n}\n\n// Handle Sailthru Link\nval parsedLink = SailthruMobile().handleSailthruLink(Uri.parse(\"SAILTHRU_LINK\"))\n// or\nval parsedLink = SailthruMobile().handleSailthruLinkResult(Uri.parse(\"SAILTHRU_LINK\")).getOrElse { error ->\n // Handle error\n null\n}\n\n", "language": "kotlin" } ] } [/block] `MessageStream` extensions: [block:code] { "codes": [ { "code": "// Get Messages\nval messages = MessageStream().getMessages()\n// or\nval messages = MessageStream().getMessagesResult().getOrElse { error ->\n // Handle error\n arrayListOf()\n}\n\n// Get Message\nval message = MessageStream().getMessage(\"MESSAGE_ID\")\n// or\nval message = MessageStream().getMessageResult(\"MESSAGE_ID\").getOrElse { error ->\n // Handle error\n null\n}\n\n// Delete Message\nMessageStream().deleteMessage(message)\n// or\nMessageStream().deleteMessageResult(message).onFailure { error ->\n // Handle error\n}\n\n// Get Unread Count\nval unreadCount = MessageStream().getUnreadMessageCount()\n// or\nval unreadCount = MessageStream().getUnreadMessageCountResult().getOrElse { error ->\n // Handle error\n null\n}\n\n// Set Message Read\nMessageStream().setMessageRead(message)\n// or\nMessageStream().setMessageReadResult(message).onFailure { error ->\n // Handle error\n}\n\n// Set Messages Read\nMessageStream().setMessagesRead(messages)\n// or\nMessageStream().setMessagesReadResult(messages).onFailure { error ->\n // Handle error\n}", "language": "kotlin" } ] } [/block] ## 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). [block:code] { "codes": [ { "code": "launch {\n SailthruMobile().notificationReceivedFlow.collect { (context, bundle) ->\n // Handle received event\n }\n}\n\nlaunch {\n SailthruMobile().notificationTappedFlow.collect { (context, bundle) ->\n // Handle tapped event\n }\n}\n\nlaunch {\n SailthruMobile().notificationActionTappedFlow.collect { (context, bundle, actionTapped) ->\n // Handle action tapped event\n }\n}", "language": "kotlin" } ] } [/block]