As a senior professional, implementing deferred deep linking in numerous applications, I will slice the internal mechanisms operating under the hood to make this functionality possible in both Android and iOS. We will look through the system APIs and processes followed by the attribution services such as Branch or AppsFlyer that make this very capability of deferred deep linking possible.
Android Internals
Key sections of how Deferred Deep Linking is implemented within Android are:
- Install Referrer API: This API is critical to the Deferred Deep Linking flow. It allows the app to query information regarding the referrer upon installing a new app from the Play store.
Key API: com.android.installreferrer.api.InstallReferrerClient
How it works:
val client = InstallReferrerClient.newBuilder(context).build()
client.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(responseCode: Int) {
when (responseCode) {
InstallReferrerClient.InstallReferrerResponse.OK -> {
val response = referrerClient.installReferrer
val referrerUrl = response.installReferrer
// Process the referrer URL
}
// Handle other response codes
}
}
override fun onInstallReferrerServiceDisconnected() {
// Handle disconnection
}
})
The structure of the information is embedded in the referrer URL.
The referrer URL can be well formed using some encoded information for a deep link.
Attribution tools can decode this information.
- Content Providers: Usually, Attribution SDKs use Content Providers to save information and read it between app starts:
class DeepLinkProvider : ContentProvider() {
override fun query(uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
// Implement query to retrieve stored deep link data
}
// Implement other ContentProvider methods
}
- INSTALL_REFERRER Broadcast: Android, upon app installation, fires a broadcast intent called INSTALL_REFERRER. We can intercept this broadcast and retrieve information about the installation.
class InstallReferrerReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == "com.android.vending.INSTALL_REFERRER") {
val referrerString = intent.getStringExtra("referrer")
// Process referrer string
}
}
}
iOS Internals
On iOS, the process relies on some features of the system:
- Universal Links: iOS works with Universal Links which build on Associated Domains Entitlement. It enables claiming the ownership of certain web domains an app owns.
Key API: UIApplicationDelegate
methods
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let incomingURL = userActivity.webpageURL {
// Process the incoming URL
return true
}
return false
}
- SKStoreProductViewController:
The majority of attribution services take advantage of
SKStoreProductViewController
to send users to the App Store but retain context in deferred scenarios.
import StoreKit
let storeViewController = SKStoreProductViewController()
storeViewController.loadProduct(withParameters: [SKStoreProductParameterITunesItemIdentifier: appId]) { success, error in
if success {
self.present(storeViewController, animated: true, nil)
}
}
- App Clip Experiences While this isn't directly relevant to deferred deep linking, because App Clips allow functionality to be offered even before complete installation, that functionality can be used to provide a much more seamless d experience.
Key API: NSUserActivity
The Info.plist :
if let userActivity = userActivity {
// Handle the user activity, which might contain deep link info handleUserActivity(userActivity)
}
- KeyChain and UserDefaults These are the storage mechanisms used in iOS for the saving of deep link data for launches and installations.
import Security
func storeDeepLinkData(_ data: Data) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "DeepLinkData",
kSecValueData as String: data
]
SecItemAdd(query as CFDictionary, nil)
}
Attribution Service Integration
Platforms like Branch and AppsFlyer take advantage of these platform-specific mechanisms even further:
They utilize the Install Referrer API and broadcast receivers in Android and the Universal Links iOS to grasp install and deep link data.
They apply server-side storage to maintain deep link data sandwiched between the initial click and app open.
They offer SDKs that take care of this plumped up complexity, offering the same developers a smooth unified API.
Key Considerations
Timing and Race Conditions: Both platforms require stable handling of situations in which app initialization and deep link data resolution may occur in a different order.
Privacy and Data Retention: With increased scrutiny in this area, responsible data handling for users' data in line with regulation, and not least GDPR and CCPA.
This is because of its complex nature, which would require thorough testing under all possible scenarios: from a fresh install, reopening, and time delay.
Conclusion
Deferred deep linking cannot simply be explained as advanced functionality, implemented over a mix of APIs native to the OS, infrastructure necessary for attribution services, and of course, implemented meticulously. Such insight helps us be more resilient and reduces the resources that deep linking actually brings to bear into our apps—user acquisition and engagement.
Top comments (0)