Attribution Providers
Configure direct deep links and attribution adapters for the GrowSurf iOS SDK.
On iOS, GrowSurf relies on your app or attribution provider to return the referral payload after install. Pass that payload into the SDK before calling addReferredParticipant().
Unlike Android (which reads the Play Install Referrer for native deferred attribution via handleDeferredDeepLink()), iOS has no native deferred deep link equivalent, so deferred attribution is delegated to your attribution provider (e.g., Branch, AppsFlyer).
Why iOS deferred is provider-specific
For a referral program, the deferred / cold-install path is the primary one — a referral targets people who don't yet have your app. When a friend taps a referral link, installs your app, then opens it for the first time (a deferred / cold install), iOS has no reliable native way to carry the referral across the install. iOS 14 (App Tracking Transparency removed the IDFA) and iOS 15 (Private Relay masks the Safari IP) broke the probabilistic device matching attribution providers previously relied on. Each provider now solves this differently, so deferred setup is not interchangeable between providers — follow the integration guide for yours.
NativeLink (encrypted clipboard token)
Yes, once NativeLink is enabled
Branch dashboard Enable NativeLink + a non-web-only link; call checkPasteboardOnInstall() before initSession() (iOS 16+: consider BranchPasteControl).
LinkMe (clipboard token)
No (optional)
ADJConfig.enableLinkMe() (v5) / setLinkMeEnabled(true) (v4) + link tag adj_linkme=1 or linkme=1; otherwise deferred is server-side/probabilistic.
Clipboard-Based DDL (clipboard token)
No (optional, enterprise)
SingularConfig.clipboardAttribution = true + Singular WebSDK on the landing page (ask your Singular CSM to enable); otherwise server-side/probabilistic.
Server-side Unified Deep Linking (no clipboard)
Yes
Implement the deepLinkDelegate / didResolveDeepLink(_:) callback; new installs receive deep_link_value + deep_link_sub1–deep_link_sub10 within a ~15-min click-to-install window.
In every case the GrowSurf SDK simply reads grsf out of whatever deep link your provider hands back. So GrowSurf deferred attribution survives a cold install only when (1) your provider's deferred path is enabled (above) and (2) the link your participants share carries grsf. The integration guides cover keeping grsf on the link; this table covers turning on the provider's deferred path.
Any clipboard-based path (Branch NativeLink, Adjust LinkMe, Singular Clipboard-Based DDL) triggers Apple's one-time "Pasted from …" prompt on first launch on iOS 16+. AppsFlyer's server-side UDL does not use the clipboard and shows no prompt. Provider SDK APIs are version-specific — confirm exact method names against your installed provider SDK.
iOS deferred is best-effort even when configured — the user can decline the paste prompt, overwrite the clipboard before first launch, or tap from an in-app/non-Safari browser (AppsFlyer also has a ~15-minute click-to-install window) — so always pair it with a fallback such as manual referral-code entry. Android's Play Install Referrer is deterministic and not subject to these.
Direct deep links
Use handleDeepLink(_:) when the installed app opens from a link that already contains grsf, which contains the referral code.
if let url {
let attribution = try await growsurf.handleDeepLink(url)
}Example accepted links:
your-app://open?grsf=referrer_idhttps://example.com/app?grsf=referrer_id
Already support deep links? If you use an attribution provider (Branch, AppsFlyer, Adjust, Singular) or otherwise open your app from links, this is already set up — just forward the opened URL to handleDeepLink(url).
Starting from scratch? Register a custom URL scheme (CFBundleURLSchemes in Info.plist) — the quickest path, no domain needed — and/or configure Universal Links (Associated Domains entitlement) for nicer https links, which require a domain you control. Then call handleDeepLink(url) from your app's URL-open handler (SwiftUI .onOpenURL or application(_:open:options:)).
Adapters
GrowSurf provides adapters for popular attribution providers. Choose your provider below, or use Other to pass a dictionary of attribution values from any other provider.
Adjust adapter
Add the Adjust adapter:
Add the GrowSurfAdjustAttribution product alongside GrowSurfSDK from the public binary package repository:
For a Package.swift target:
Download GrowSurfAdjustAttribution.xcframework.zip from the public release:
Unzip it, drag GrowSurfAdjustAttribution.xcframework into your Xcode project alongside GrowSurfSDK.xcframework, and set it to Embed & Sign in your app target.
Then pass the Adjust deferred deep link into GrowSurf:
The adapter accepts URL and String deep link values.
For deferred (no-app-installed) referrals on iOS, Adjust's clipboard path (LinkMe) is optional and off by default — enable it with ADJConfig.enableLinkMe() (v5) / setLinkMeEnabled(true) (v4) and tag your link adj_linkme=1/linkme=1; without it, deferred falls back to Adjust's server-side matching. See Adjust - iOS Deferred Deep Linking for detailed instructions.
AppsFlyer adapter
Add the AppsFlyer adapter:
Add the GrowSurfAppsFlyerAttribution product alongside GrowSurfSDK from the public binary package repository:
For a Package.swift target:
Download GrowSurfAppsFlyerAttribution.xcframework.zip from the public release:
Unzip it, drag GrowSurfAppsFlyerAttribution.xcframework into your Xcode project alongside GrowSurfSDK.xcframework, and set it to Embed & Sign in your app target.
Then pass AppsFlyer conversion data into GrowSurf:
The adapter accepts [String: String], [String: Any], and [AnyHashable: Any] payloads.
For deferred (no-app-installed) referrals on iOS, AppsFlyer has no clipboard path — the referral arrives via server-side Unified Deep Linking (deepLinkDelegate / didResolveDeepLink(_:)) within a ~15-minute lookback, carrying deep_link_value and deep_link_sub1–deep_link_sub10. See AppsFlyer - iOS Deferred Deep Linking for detailed instructions.
Branch adapter
Add the Branch adapter:
Add the GrowSurfBranchAttribution product alongside GrowSurfSDK from the public binary package repository:
For a Package.swift target:
Download GrowSurfBranchAttribution.xcframework.zip from the public release:
Unzip it, drag GrowSurfBranchAttribution.xcframework into your Xcode project alongside GrowSurfSDK.xcframework, and set it to Embed & Sign in your app target.
Then pass Branch callback data into GrowSurf:
The adapter accepts [String: String], [String: Any], and [AnyHashable: Any] payloads.
For deferred (no-app-installed) referrals on iOS, Branch requires NativeLink: enable it in the Branch dashboard (Configuration → Enable NativeLink) with a non-web-only link, and call Branch.getInstance().checkPasteboardOnInstall() before initSession() so the SDK reads the NativeLink clipboard token on first launch (iOS 14+ removed the fingerprint matching used previously; on iOS 16+ Branch also offers BranchPasteControl as a user-tappable alternative to the silent read). See Branch - iOS Deferred Deep Linking for detailed instructions.
Singular adapter
Add the Singular adapter:
Add the GrowSurfSingularAttribution product alongside GrowSurfSDK from the public binary package repository:
For a Package.swift target:
Download GrowSurfSingularAttribution.xcframework.zip from the public release:
Unzip it, drag GrowSurfSingularAttribution.xcframework into your Xcode project alongside GrowSurfSDK.xcframework, and set it to Embed & Sign in your app target.
Then pass Singular callback data into GrowSurf:
The adapter accepts [String: String], [String: Any], [AnyHashable: Any], URL, and String payloads. It parses GrowSurf referral keys from Singular deep link, deferred deep link, and passthrough fields such as _dl, _ddl, and _p.
For deferred (no-app-installed) referrals on iOS, Singular Clipboard-Based DDL is an optional, enterprise feature requiring SingularConfig.clipboardAttribution = true and the Singular WebSDK on your landing page (enabled via your Singular CSM); otherwise deferred is server-side/probabilistic. See Singular - iOS Deferred Deep Linking for detailed instructions.
Accepted attribution keys
grsf
Preferred GrowSurf referrer ID.
ref
Alternate referrer ID.
referredBy
Alternate referrer ID.
provider
Attribution provider name. Ignored when the SDK method receives an explicit provider argument.
clickId
Provider click ID metadata.
click_id
Provider click ID metadata.
unique
Optional boolean string: true or false.
The SDK also parses values nested inside URL-like payload fields. For example, a provider value of https://example.com/?grsf=referrer_id&click_id=click_123 can still produce GrowSurf attribution. If a provider returns a GrowSurf-hosted share URL such as https://grow.surf/share/:campaignId/:referrerId, the SDK uses the participant value from the path.
Last updated
Was this helpful?