Integrating Branch analytics into a mobile application
Branch — not just an MMP (Mobile Measurement Partner). Core value — deep linking infrastructure: Universal Links on iOS and App Links on Android work correctly even in edge cases where standard mechanisms fail. Install attribution — secondary function that comes with the package.
Typical situation: user clicks a banner in Instagram Stories on iOS, goes to App Store, installs app. Standard attribution through Universal Links loses UTM parameters during App Store redirect. Branch solves this through deferred deep link — on first app open, SDK "learns" where user came from and opens the right screen.
iOS SDK connection
Via CocoaPods or SPM (BranchPlugin). Configuration in AppDelegate:
import Branch
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Branch.getInstance().setIdentity(userId) // if user authorized
Branch.getInstance().initSession(launchOptions: launchOptions) { params, error in
guard error == nil, let params = params, params["+clicked_branch_link"] as? Bool == true else { return }
let screen = params["screen"] as? String
let itemId = params["item_id"] as? String
// navigate to right screen
NavigationRouter.shared.navigate(to: screen, itemId: itemId)
}
return true
}
// Universal Links
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
Branch.getInstance().continue(userActivity)
return true
}
// URL Schemes
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
Branch.getInstance().application(app, open: url, options: options)
return true
}
+clicked_branch_link — flag in params distinguishing Branch deeplink from normal first launch. Without this check, there will be navigation somewhere on every first app open.
Android SDK connection
// build.gradle (app)
implementation("io.branch.sdk.android:library:5.+")
Add Branch Key metadata in AndroidManifest.xml and intent-filter for App Links. In Application.onCreate():
Branch.getAutoInstance(this)
In target Activity:
override fun onStart() {
super.onStart()
Branch.sessionBuilder(this).withCallback { referringParams, error ->
if (error != null) return@withCallback
if (referringParams?.getBoolean("+clicked_branch_link") == true) {
val screen = referringParams.getString("screen")
// navigate
}
}.withData(intent.data).init()
}
Creating deeplinks and attribution
Branch Link created via dashboard or programmatically through SDK:
let buo = BranchUniversalObject(canonicalIdentifier: "product/\(productId)")
buo.title = product.name
buo.contentMetadata.customMetadata["screen"] = "product_detail"
buo.contentMetadata.customMetadata["item_id"] = productId
let lp = BranchLinkProperties()
lp.channel = "email"
lp.campaign = "summer_sale"
lp.addControlParam("$fallback_url", withValue: "https://myapp.com/products/\(productId)")
buo.getShortUrl(with: lp) { url, error in
// url — Branch link for sharing
}
$fallback_url — where to send users without app installed and no Store access possibility (e.g., desktop browsers).
Attribution and analytics
Branch tracks entire path: click → install → first open → conversion event. Passing conversions:
let event = BranchEvent.standardEvent(.purchase)
event.transactionID = orderId
event.revenue = orderTotal
event.currency = BNCCurrency.RUB
event.logEvent()
Standard events (BranchEvent.standardEvent) automatically map to ad platforms (Meta, Google Ads) without additional setup.
Problems we encounter
Associated Domains not configured — Universal Links don't work, app doesn't intercept links. Need to add applinks:yourdomain.app.link to Entitlements and ensure Apple Developer Portal contains Associated Domains Capability.
Client SDK initializes after navigation — deeplink parameters lost because UI already displayed before initSession returned results. Solution: defer initial navigation until completion block.
Android Back Stack on deeplink — user opens app through deeplink, lands on product screen, presses Back and exits app instead of returning to home screen. Need to explicitly build Back Stack through TaskStackBuilder.
What's included in the work
- Branch SDK connection (iOS / Android / Flutter / React Native)
- Associated Domains and Universal Links setup on iOS
- App Links and intent-filter setup on Android
- Deferred deep linking configuration with navigation
- Creating Branch Link templates for marketing channels
- Conversion event setup
- Testing via Branch Dashboard → Live View
Timeline
Deeplink with attribution on one platform: 1–2 days. iOS + Android with full event set: 3–4 days. Cost calculated individually.







