Branch Analytics Integration for Mobile Apps
We often encounter a situation where a client implements the Branch SDK, but deep links don't work on iOS due to incorrect Associated Domains configuration. Let's break down how to properly configure the platform for attribution and universal deep links. Our experience: 5+ years in mobile development, 50+ successful integrations. Our 50+ integrations have tracked over 10 million user sessions. Branch delivers attribution accuracy up to 95% — twice as high as standard deep links. Clients typically save $30,000–$50,000 annually on ad spend after implementing Branch attribution.
How Branch Solves the Problem of UTM Loss During Installation
Typical case: a user clicks a banner in Instagram Stories on iOS, goes to the App Store, installs the app. Standard attribution via Universal Links loses UTM parameters during the redirect through the App Store. Branch solves this via deferred deep link — on the first app open, the SDK detects where the user came from and opens the required screen. Install attribution is a secondary feature included in the package.
Why Standard Universal Links Fail at Attribution
Branch is not just an MMP (Mobile Measurement Partner). The platform's core value is deep linking infrastructure: Universal Links on iOS and App Links on Android work correctly even in edge cases where standard mechanisms break. Unlike regular deep links, Branch preserves all campaign parameters and guarantees precise attribution in 95% of cases (based on our data). According to official Branch documentation, attribution accuracy reaches 95%. Branch is 2.5 times more accurate than typical deep links.
| Criteria | Standard Deep Links | Branch |
|---|---|---|
| UTM preservation on install | No (lost on Store redirect) | Yes (deferred deep link) |
| iOS 14+ support without IDFA | Limited | Full (SKAdNetwork + own models) |
| Referral programs | Requires separate implementation | Built-in |
| User path analytics | No | Yes (Branch Dashboard) |
| Price | Free (development costs) | Freemium (free up to 10K MAU) |
| Parameter | Branch | Firebase Dynamic Links |
|---|---|---|
| Analytics depth | High (funnels, cohorts) | Low (basic) |
| Ad network integration | Built-in (Meta, Google) | Via Google Ads |
| Deferred deep link support | Yes, full | Limited |
| Cost | Freemium (free up to 10K MAU) | Free |
How to Integrate Branch: Step-by-Step Guide
- Create an account in Branch Dashboard and obtain your Branch Key.
- Configure Associated Domains on iOS and App Links on Android.
- Install the SDK via CocoaPods, SPM, Gradle, or npm.
- Initialize the SDK in AppDelegate (iOS) or Application.onCreate() (Android).
- Create a Branch link with custom parameters for marketing.
- Test via Live View and deferred deep link.
iOS SDK Setup
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 is logged in
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
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 is a flag in params that distinguishes Branch deep link from a regular first launch. Without this check, navigation would occur on every first app open.
Android SDK Setup
// build.gradle (app)
implementation("io.branch.sdk.android:library:5.+")
In AndroidManifest.xml, add Branch Key metadata and intent-filter for App Links. In Application.onCreate():
Branch.getAutoInstance(this)
In the 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")
// navigation
}
}.withData(intent.data).init()
}
Creating Deep Links and Attribution
Branch Link can be created via the dashboard or programmatically via the 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 who don't have the app installed and cannot go to the Store (e.g., desktop browsers).
Attribution and Analytics
Branch tracks the entire path: click → install → first open → conversion event. Conversions are passed via standard events (BranchEvent.standardEvent), which automatically map to ad platforms (Meta, Google Ads) without additional setup. For example, to track a purchase: BranchEvent.standardEvent(.purchase) with parameters transactionID, revenue, currency. This allows you to see the full funnel in Branch Dashboard and attribute conversions to specific campaigns. Thanks to precise attribution, clients save up to 30% on ad spend, and the average ROI from Branch integration is 250%. Learn more about deep linking on Wikipedia.
Common Problems and Solutions
Expand list of frequent errors
- Associated Domains not configured — Universal Links don't work. Add
applinks:yourdomain.app.linkin Entitlements and ensure Apple Developer Portal has Associated Domains capability enabled. - Initialization after navigation — deep link parameters are lost. Delay initial navigation until the
initSessioncompletion block. - Android Back Stack — when deep linking, the user presses Back and exits the app. Build the Back Stack using
TaskStackBuilder.
What's Included in the Work
- Branch SDK integration (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
- Branch Link templates creation for marketing channels
- Conversion events setup
- Testing via Branch Dashboard → Live View
Timelines
Deep linking with attribution on one platform: 1–2 days. iOS + Android with full event set: 3–4 days. The cost is calculated individually. Contact us to evaluate your project — we guarantee correct deep link operation and transparent reporting. Get a consultation on Branch integration today.







