Opening App Screens
Push notifications, in-app messages and emails can carry a link that should open a specific screen of your app. How the link reaches your app depends on the channel, so this page covers each channel separately.
Push notifications and in-app messages
What it is
The link of a push notification or an in-app message button is the exact string entered in the panel. There is no redirect and no tracking wrapper: myapp://orders/42 or https://www.example.com/orders/42 reaches the device unchanged. Clicks are reported by the SDK, not by a redirect.
You can use two kinds of links:
- A custom URL scheme, for example
myapp://orders/42. Only your app understands it. - An HTTPS link on your own domain, for example
https://www.example.com/orders/42. On iOS this works as a Universal Link and on Android as an App Link, so the same link also opens your website when the app is not installed.
How it works
- The contact taps the push notification or an in-app message button.
- The SDK reports the click to Positive User. On some platforms this needs a call from your code, see Platform differences.
- The SDK passes the link to your code (a delegate, handler or callback, depending on the platform).
- Your code opens the matching screen.
Handling the link in your own code is the recommended setup on every platform. It does not depend on how the operating system routes links, and it works the same for custom schemes and HTTPS links.
Platform differences
| Platform | Push notification tap | Push click counted when | In-app message button tap |
|---|---|---|---|
| iOS | The SDK passes the full payload to your RemoteNotificationDelegate. The link is in data["link"]. The SDK does not open it. | The tapped notification is passed to handleNotification(userInfo:), or the SDK is the notification center delegate. | The SDK passes the URL to your inAppNotificationClickDelegate first. Return true if you handled it. Otherwise the SDK opens it with UIApplication.open(_:) when iOS reports it can open it. |
| Android | Tapping a notification opens your launcher activity, with the payload, including link, in the intent extras. A notification shown by the SDK clears the activity stack of your app when tapped. | Your launcher activity calls handleRouteFromNotification(intent). | With a click handler set, the SDK passes the URL to it and does not open it. The click is then not reported to Positive User. Without a handler, the SDK reports the click and opens the URL in Chrome Custom Tabs or with a view intent. |
| Flutter | Banner shown in your app in the foreground: the onTap(type, link) callback of buildNotification receives the link. System notification: read the link with getPushMessage(message.data)?.link in FirebaseMessaging.onMessageOpenedApp or getInitialMessage(). | Automatically for the banner shown in your app. For a system notification, after you call notificationClickedEvent. | The same onTap(type, link) callback receives the button link. |
iOS
- Write one function in your app that takes a
URLand opens the matching screen. - Call it from your
RemoteNotificationDelegatewith thelinkfrom the payload. - Call it from your
inAppNotificationClickDelegateand returntrue.
final class LinkRouter: NSObject, RemoteNotificationDelegate, InAppNotificationClickDelegate {
@discardableResult
func open(_ url: URL) -> Bool {
// map the URL to a screen of your app, return false if you do not know it
return true
}
// Push notification tap
func didReceiveRemoteNotification(with id: String, data: [AnyHashable: Any]) {
guard !id.isEmpty, let link = data["link"] as? String,
!link.isEmpty, link != "None", // a push without a link carries "None"
let url = URL(string: link) else { return }
open(url)
}
// In-app message button tap
func inAppNotificationDidClick(url: URL) -> Bool {
open(url)
}
}
let linkRouter = LinkRouter()
UserSDK.default?.notificationDelegate = linkRouter
UserSDK.default?.inAppNotificationClickDelegate = linkRouter
If the SDK opens a custom scheme link itself, it does so only when canOpenURL returns true, which requires the scheme in your app's LSApplicationQueriesSchemes. Handling the link in the delegate avoids that requirement.
Details: Push Notifications on iOS and In-App Messages on iOS.
Android
On Android, read the payload from the intent of your launcher activity for push notifications, and pass the intent to UserCom.getInstance().handleRouteFromNotification(intent) there to count the click. For in-app messages, set an in-app click handler. With a handler set, in-app clicks are not reported to Positive User.
See Android push notifications and Android in-app messages.
Flutter
On Flutter, route the link in the onTap callback for banners and in-app messages shown in your app. For a tap on a system notification, onTap is not called: read the link with getPushMessage(message.data)?.link in FirebaseMessaging.onMessageOpenedApp and getInitialMessage(), and call notificationClickedEvent to count the click. When you pass a payload with data['from'] == 'user_com_channel' to buildNotification without a pushMessageBuilder, the SDK opens the link itself with launchUrl and does not call onTap.
See Flutter push notifications.
Links on your own domain
If you use HTTPS links on your own domain, you host the association file on that domain: apple-app-site-association for iOS and assetlinks.json for Android. Positive User is not involved in this setup.
Email
What it is
Links in emails are tracked redirect links: each link points to your workspace domain on Positive User, for example https://<your-workspace>.user.com/emails/c/..., which records the click and redirects to the target. The device first sees the tracking domain, not your domain, so your own Universal Links and App Links do not open the app from an email.
How it works
To open your app from email links, Positive User hosts the association files for the tracking domain, and your app declares that domain.
- Send the following to Positive User support or your Customer Success Manager:
- iOS: your Apple Team ID and the bundle ID of the app.
- Android: the package name and the SHA-256 fingerprints of your app signing certificates. If you use Play App Signing, take the fingerprint of the app signing key from Play Console.
- Positive User publishes
apple-app-site-associationandassetlinks.jsonon the tracking domain. - Add the tracking domain to your app: an
applinks:entry in the Associated Domains entitlement on iOS, an intent filter withandroid:autoVerify="true"on Android. - Handle the incoming link in your app as a Universal Link or App Link. Your app receives the target URL from the email, not the tracking URL, so you route it the same way as any other link to your domain.
Unsubscribe links always open in the browser, so recipients can unsubscribe. On iOS, Positive User excludes /emails/unsubscribe/* in the apple-app-site-association file it hosts. You do not need to do anything.
Send a test email to yourself and tap a link on a device with the app installed. The app opens on the expected screen, and the click is recorded in the email campaign statistics.