iOS SDK Platform Research (2025/2026)
Research for the native OptoLink Swift iOS SDK (deep linking + deferred deep linking + attribution). Compiled from web sources, current as of 2026. Source URLs cited inline per finding.
1. Universal Links — current setup
AASA file + Associated Domains (unchanged core, stricter serving)
- Universal Links still rest on two pillars: an
apple-app-site-association(AASA) JSON file on the link domain and thecom.apple.developer.associated-domainsentitlement (applinks:domainentries, no scheme, no trailing slash; subdomains need separate entries;*.subdomainwildcards supported but discouraged for security). Sources: https://docs.expo.dev/linking/ios-universal-links/ , https://tolinku.com/blog/xcode-universal-links-configuration/ - Serving requirements: HTTPS only,
Content-Type: application/json, no redirects, file < 128 KB, served from/.well-known/apple-app-site-association(root path as legacy fallback). Rules are stricter on iOS 15/17+ — a redirect or wrong content type fails validation silently (link just opens Safari). Source: https://proandroiddev.com/are-your-android-ios-deep-links-ready-for-2025-e822c1b650c8 , https://tolinku.com/blog/aasa-file-setup/ - Modern AASA format (iOS 13+):
applinks.details[]withappIDs(array),paths, optionalexcludefragments, and per-component matching with thecomponentskey (query/fragment rules). Sources: https://docs.expo.dev/linking/ios-universal-links/ , https://blog.avinashkattamanchi.in/posts/ios-universal-links/ - Apple CDN caching: since iOS 14, AASA fetches go through Apple's CDN, not directly from devices. Changes can lag hours (commonly cited 24–48h). For dev builds use
applinks:domain?mode=developer(bypasses CDN; Xcode/TestFlight installs on team-registered devices only). Source: https://tolinku.com/blog/aasa-file-setup/ - Common silent-failure causes: entitlement not in the provisioning profile (must regenerate profile after enabling capability), domain mismatch between entitlement and AASA,
https://accidentally included in the entitlement, app installed before capability was enabled (uninstall/reinstall forces re-fetch). Sources: https://tolinku.com/blog/xcode-universal-links-configuration/ , https://tolinku.com/blog/aasa-file-setup/ - Testing gotchas: typed URLs in Safari's address bar do NOT trigger Universal Links — test via iMessage/email/Notes taps. Physical devices required (simulator support is unreliable); Settings → Developer → Associated Domains Development helps on device. Sources: https://tolinku.com/blog/xcode-universal-links-configuration/ , https://proandroiddev.com/are-your-android-ios-deep-links-ready-for-2025-e822c1b650c8
Custom URL schemes — residual role only
- Custom schemes (
myapp://) are trivially claimable by any app (no ownership verification), so Apple positions Universal Links as the primary mechanism; Universal Links "cannot be claimed by other apps." Source: https://blog.avinashkattamanchi.in/posts/ios-universal-links/ - Branch (2026) still lists custom schemes as one of three link types but notes the failure mode: if the app isn't installed the user "sees an error or nothing happens." Their setup flow leads with Universal Links/AASA. Source: https://www.branch.io/resources/blog/how-to-set-up-deferred-deep-linking-on-ios/
- Residual legit uses: opening your own app from your own app/webviews where a scheme is convenient, and legacy SDK callbacks. Any serious link platform treats schemes as a fallback, never the primary router.
How modern apps intercept link opens (SwiftUI vs UIKit)
- SwiftUI
.onOpenURLis the primary entry point; attach at the root (WindowGroupcontent). It covers cold start, background, and foreground delivery. Source: https://tolinku.com/blog/universal-links-with-swiftui/ - Gotcha (2025 field reports): QR-code-sourced Universal Links on cold start in Release builds may arrive via the
NSUserActivitypath instead of.onOpenURL— production apps add.onContinueUserActivity(NSUserActivityTypeBrowsingWeb)alongside.onOpenURLand route both into one handler. SDK docs should tell integrators to do the same. Source: https://www.linkedin.com/posts/mayank-bimbra-99329b174_ios-swiftui-deeplinking-activity-7400554804273401856-YRuM - UIKit path (still what most hybrid/older apps and all App Clips use):
UISceneDelegate.scene(_:continue:)receivingNSUserActivityof typeNSUserActivityTypeBrowsingWebwithwebpageURL(pre-iOS-13 AppDelegateapplication(_:continue:restorationHandler:)is legacy). Sources: https://tolinku.com/blog/universal-links-with-swiftui/ , https://nerdy.pro/blog/deferred-deep-linking-app-clips-install-referrer
2. Deferred deep linking on iOS — the hard problem
No Play Install Referrer equivalent exists on iOS. Between tap → App Store → install → first launch, no official channel carries link context. Firebase Dynamic Links (the old free default) shut down Aug 25, 2025, so everything below is the current field. Source: https://nerdy.pro/blog/deferred-deep-linking-app-clips-install-referrer , https://firebase.google.com/support/dynamic-links-faq
2a. Clipboard token handoff (the workhorse)
- Flow: web click page writes a short opaque token to
UIPasteboard→ user installs → SDK reads pasteboard on first launch and exchanges the token server-side. - Paste notification/prompt history: iOS ≤13 silent; iOS 14/15 show a "[App] pasted from [Source]" banner (informational, non-blocking); iOS 16+ a modal "Allow Paste?" prompt that blocks reading until consent. Acceptance rates: ~30–50% raw, ~50–70% with a well-designed pre-prompt explanation screen. Source: https://tolinku.com/blog/ios-paste-permission-deferred-links/
- Avoiding the prompt/banner:
UIPasteboard.detectPatterns/detectedPatterns(for:)(iOS 16+) ask the data-detection system whether the pasteboard matches aDetectionPattern— e.g..probableWebURL,.probableWebSearch,.link,.number— "without notifying the user." An SDK can (1) check.probableWebURLsilently, (2) only if it matches, trigger the actual read/prompt. This is the standard way to avoid nagging organic installs. Sources: https://developer.apple.com/documentation/uikit/uipasteboard/detectionpattern , https://developer.apple.com/documentation/uikit/uipasteboard/detectpatterns(for:completionhandler:)-5zlnd UIPasteControl(iOS 16+): a system paste button whose tap IS consent — no prompt at all. Branch shipsBranchPasteControlas a wrapper (passPaste(itemProviders:)feeds the SDK). Limitation: user must tap a visible button; can't fire programmatically. Sources: https://www.branch.io/resources/blog/how-to-set-up-deferred-deep-linking-on-ios/ , https://tolinku.com/blog/ios-paste-permission-deferred-links/- Fragility: any intermediate copy destroys the token; users can wipe it; paste permission resets per install. Mitigations: gate the check to first launch, use
hasStringsas a cheap pre-filter, server-side "recent click" hints to decide whether to ask at all, and a graceful fallback when denied. Source: https://tolinku.com/blog/ios-paste-permission-deferred-links/
2b. Safari/browser-based matching (cookie + IP)
- Pre-install, the link domain can set a first-party cookie + record click server-side; on first open the SDK's webview/server compares. Historically "Safari matching."
- Largely degraded on iOS 14+: Safari ITP blocks third-party cookies, iCloud Private Relay hides IPs for iCloud+ users (Branch explicitly cites Private Relay as what breaks their IP-based matching, motivating NativeLink). iOS 26 Safari adds Link Tracking Protection stripping
gclid/fbclid/msclkidfrom URLs and Advanced Fingerprinting Protection on by default. Sources: https://www.branch.io/resources/blog/how-to-set-up-deferred-deep-linking-on-ios/ , https://respectlytics.com/blog/app-tracking-transparency-2026/
2c. Probabilistic / fingerprint matching — Apple's policy stance
- Technique: match device/browser attributes (IP, OS, screen, locale, language) between click and first open within a short window. Widely used 2021–2023 as IDFA died.
- Apple's position is prohibitive, and enforcement is real: Apple has "made it clear that probabilistic or fingerprint attribution is not allowed — any method that lets an advertiser link users between apps is forbidden." The privacy-manifest regime "serves Apple's end goal of restricting probabilistic attribution and ending fingerprinting." Marketers were told to move off fingerprinting before the spring 2024 privacy-manifest deadline (53% were still using it alongside SKAN). Sources: https://www.adexchanger.com/data-driven-thinking/the-future-of-probabilistic-attribution-what-will-apple-do-next/ , https://verve.com/blog/mobile-performance-after-ios-privacy-manifest-enforcement-advertisers/ , https://advertising.inmobi.com/blog/skan-and-fingerprinting-in-2024-everything-you-need-to-know , https://mwm.ai/glossary/fingerprinting
- iOS 26 closed the last workarounds: Advanced Fingerprinting Protection (blocking screen/GPU/font/device-signal probes) on by default in all Safari sessions; France fined Apple €150M over ATT in Mar 2025, Germany found similar — the regulatory direction is more privacy, not less. Source: https://respectlytics.com/blog/app-tracking-transparency-2026/
- Even third-party vendors acknowledge DIY fingerprinting is "unreliable, privacy-fragile, and discouraged by Apple" (low-medium accuracy: shared/carrier IPs, short match windows). Source: https://nerdy.pro/blog/deferred-deep-linking-app-clips-install-referrer
- Note: some vendors still ship "fingerprint-based" deferred linking (e.g. Dynalinks markets it as zero-interaction); an SDK that must pass App Store review with enterprise customers should treat fingerprinting as a compliance liability, not a feature. Source: https://docs.dynalinks.app/deferred/deferred-ios.html
2d. App Clips as install bridge (deterministic, first-party)
- An App Clip (≤ 15 MB, instant-launch from Universal Link / App Clip Code / QR) runs before the full app exists, receives the invocation URL via
NSUserActivity, and can persist it to a shared App Group container (UserDefaults(suiteName:)). After the user installs the full app via the App Clip's store overlay, the full app reads the pending link on first launch. Deterministic handoff — no clipboard prompt, no matching. Source: https://nerdy.pro/blog/deferred-deep-linking-app-clips-install-referrer - Trade-offs: separate clip target to build/maintain, size budget, AASA must cover clip domains, and clip-session analytics resist standard install measurement ("the downstream full-app install can be attributed through deferred deep linking, but the clip session itself resists standard precision measurement"). Sources: https://nerdy.pro/blog/deferred-deep-linking-app-clips-install-referrer , https://www.airbridge.io/en/blog/app-clips-vs-full-app-install
- Branch positions App Clips the same way — as one of the two modern answers (their NativeLink clipboard + App Clips) to Private Relay. Source: https://www.branch.io/resources/blog/nativelink-and-app-clips-solving-the-deferred-deep-linking-challenges-of-private-relay/
2e. AdServices / AdAttributionKit — paid UA vs organic
- AdServices (iOS 14.3+): Apple Search Ads attribution via
attributionToken; complements AdAttributionKit; Apple states it will "continue to maintain the AdServices API" alongside AAK. Source: https://ads.apple.com/app-store/help/attribution/0094-ad-attribution-overview - AdAttributionKit (iOS 17.4+, successor to SKAdNetwork — there will be no SKAN 5.0): privacy-preserving install/re-engagement attribution for ad networks; App Store + alternative marketplaces. iOS 18.4 additions: overlapping conversion windows, configurable attribution windows/cooldowns, country-code postbacks, and Settings → Developer → Ad Attribution Testing dev postbacks. Sources: https://developer.apple.com/documentation/AdAttributionKit , https://dev.to/arshtechpro/wwdc-2025-adattributionkit-ios-184-essential-features-for-modern-app-attribution-2h5c , https://respectlytics.com/blog/app-tracking-transparency-2026/
- Relevance split: these cover paid ad-network attribution only (aggregated, delayed postbacks, crowd-anonymity thresholds). They tell you nothing about organic/shared-link journeys — a deep-linking platform still needs its own mechanism (Universal Link + clipboard/App-Group handoff) for organic deferred context. AAK handles "where installs came from," not "what the user tapped." Source: https://respectlytics.com/blog/app-tracking-transparency-2026/
3. Privacy compliance for SDKs
ATT — when an attribution SDK must prompt
- Apple's definition: "tracking" = linking user/device data from your app with data from other companies' apps/websites for targeted advertising or ad measurement, or sharing with data brokers. Accessing IDFA for any purpose requires the prompt; first-party analytics without cross-app linking, ephemeral session IDs, or country-level geo from transient IPs do not. Sources: https://respectlytics.com/blog/app-tracking-transparency-2026/ , https://developer.apple.com/documentation/apptrackingtransparency
- For an attribution SDK: if the SDK reads IDFA or links device data across companies' apps/sites, the host app must show ATT (
ATTrackingManager.requestTrackingAuthorization) — embedding it is the app's job, the SDK documents the requirement and reads the status. Adjust's SDK documents exactly this pattern (store authorization status, send with each request). Source: https://dev.adjust.com/en/sdk/ios/features/att/ - Skipping ATT is legitimate if the SDK never touches IDFA and never cross-links — the architecture choice, not a workaround: "When Apple asks 'Does your app track users?' you truthfully answer No." Guideline 5.1.2(i) "tracking without permission" is one of the most common privacy rejections when the prompt is missing/mis-wired. Sources: https://respectlytics.com/blog/app-tracking-transparency-2026/ , https://appcompliance.io/blog/app-tracking-transparency-att-compliance/
- EU ordering note: GDPR consent flow before the ATT prompt (GDPR-first sequencing), and respect both answers independently. Source: https://respectlytics.com/blog/app-tracking-transparency-2026/
- ATT opt-in reality: industry average 15–30%; plan attribution for the majority who decline. Source: https://respectlytics.com/blog/app-tracking-transparency-2026/
Privacy manifests (PrivacyInfo.xcprivacy) + required-reason APIs
- Since May 1, 2024, any app submission that adds a "commonly used" third-party SDK must include that SDK's privacy manifest; binary-distributed SDKs must also be signed. An attribution/deep-linking SDK should ship both regardless of whether it's on Apple's current list — integrators' app submissions depend on it. Sources: https://developer.apple.com/support/third-party-SDK-requirements/ , https://developer.apple.com/news/?id=pvszzano
- Manifest keys: NSPrivacyTracking (does it track), NSPrivacyTrackingDomains, NSPrivacyCollectedDataTypes, NSPrivacyAccessedAPITypes. Source: https://developer.apple.com/documentation/bundleresources/privacy-manifest-files
- Required-reason APIs: declare categories + approved reason codes. The classic SDK miss is UserDefaults → reason
CA92.1("access user info accessible only to the app itself"). Apple "continually reviews" the list; file-timestamp, disk-space, system-boot-time, and keyboard APIs are the other categories. Missing manifests/code produce ITMS-91053-style submission errors. Sources: https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api , https://techconcepts.org/blog/privacyinfo-xcprivacy-guide-ios-developers , https://iossubmissionguide.com/privacy-manifest-required-reason-api , https://emrldlabs.com/blog/privacy-manifest-required-reason-apis-privacyinfo-xcprivacy/ - Keychain items are NOT in the required-reason list, but collected-data types (device ID, coarse location, product interaction) must be declared accurately — an attribution SDK declaring
NSPrivacyTracking: truemust also list tracking domains.
SDK signing requirements (2024+)
- Xcode validates that adopted third-party SDK binaries are "signed by the same developer," improving supply-chain integrity. Distribution must produce a signed XCFramework (typically signed with the vendor's Developer ID Application cert at archive time). Sources: https://developer.apple.com/support/third-party-SDK-requirements/ , https://developer.apple.com/news/?id=pvszzano
4. Distribution & modern Swift practice
SPM is primary; CocoaPods declining
- SPM is "Apple's official tool," deeply integrated into Xcode, and supports binary distribution; industry commentary is openly "Goodbye CocoaPods, Hello SPM." CocoaPods' 60k+ pod ecosystem keeps it relevant for legacy, but new SDKs default to SPM (Branch supports CocoaPods/SPM/Carthage; newer SDKs like DeepLinkNow lead with SPM). Sources: https://medium.com/@rishabhkochar27/understanding-the-shift-in-ios-dependency-management-goodbye-cocoapods-hello-spm-6e8b76f65ffe , https://www.pistack.xyz/posts/2026-07-31-swift-package-managers-spm-cocoapods-carthage/ , https://www.branch.io/resources/blog/how-to-set-up-deferred-deep-linking-on-ios/ , https://deeplinknow.com/docs/ios
- Binary target/XCframework:
.binaryTarget(url:, checksum:)(or a path-based local target); Xcode validates SDK signatures; checksum pins the zip (supply-chain security). Compute withswift package compute-checksum. Sources: https://developer.apple.com/documentation/xcode/distributing-binary-frameworks-as-swift-packages , https://www.avanderlee.com/swift/binary-targets-swift-package-manager/ , https://wwdcnotes.com/documentation/wwdc20-10147-distribute-binary-frameworks-as-swift-packages/ - Pragmatic pattern for an SDK with no closed-source parts: source-distributed SPM package as primary, optional prebuilt XCframework release artifact for teams that want faster builds. Source-only avoids signature/checksum churn entirely.
Swift concurrency
- Modern SDKs are expected to offer
async/awaitAPIs; use actors for SDK-internal state (install state, pending-link queue),@MainActorfor UI-adjacent callbacks,Sendablevalue types for link payloads/params so results can cross isolation boundaries safely. Swift 6 strict concurrency makesSendableconformance a compile-time requirement, not a nicety. Sources: https://swiftuiportal.com/swift-concurrency-guide/ , https://slekens.dev/en/blog/modern-concurrency-in-swift/ , https://abdorizak.dev/blog/swift-concurrency-async-await-actors
Minimum iOS version in 2025/2026
- Apple's floor is low (App Store Connect requires only iOS 13+ as of Sept 2026), but the practical coverage math: iOS 15 covers ~96% of devices (mid-2026); iOS 16 covers clipboard
detectPatterns(2022+, ~all non-ancient devices); iOS 17.4+ for AdAttributionKit. Sources: https://developer.apple.com/news/upcoming-requirements/ , https://capgo.app/ios-distribution-chart/ , https://blog.ecoatm.com/what-minimum-ios-version-do-most-apps-need/ - Sensible SDK floor: iOS 15 with
#available(iOS 16, *)gating for paste-pattern APIs andUIPasteControl. iOS 16+ as floor is defensible if you accept ~a few % coverage loss. (Apple's own year-based naming: current OS is "iOS 26".)
SDK size expectations
- App Clips must stay ≤ 15 MB; app-extension-free SDKs should stay in the low single-digit MBs compressed — heavy-footprint SDKs (Firebase historically ~tens of MB) drive integrator pushback and App Size review complaints. lightweight is an explicit selling point in the category (DeepLinkNow markets "lightweight"; OptoLink's own node SDK is zero-dependency for the same reason). Sources: https://nerdy.pro/blog/deferred-deep-linking-app-clips-install-referrer , https://deeplinknow.com/docs/ios
- Zero third-party dependencies in the SDK (avoid pulling in analytics/attribution transitive deps) — it protects integrators from privacy-manifest and signing conflicts of bundled third-party SDKs.
5. First-launch detection and device ID under ATT
Identifier options
| Identifier | Persistence | ATT needed | Notes |
|---|---|---|---|
| IDFA | Persistent-ish, user-resettable | Yes (any access) | 15–30% opt-in; mostly unavailable |
IDFV (UIDevice.identifierForVendor) | Same-vendor apps; changes to a new UUID when the last app of the vendor is uninstalled | No | Stable across reinstall only if another app from same vendor stays installed |
| Generated UUID in UserDefaults | Cleared on uninstall | No | Same-lifetime as app data — the honest "install ID" |
| Generated UUID in Keychain | Survives uninstall (iOS keeps the app's keychain items until device wipe); no API to delete on uninstall | No | The de-facto persistent device/install ID technique, widely documented |
| DeviceCheck / App Attest | Apple-backed per-device bits (2 bits!) / attestation | No | Fraud signals, not link identity |
Sources: https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor , https://stackoverflow.com/questions/21878560/how-to-preserve-identifierforvendor-in-ios-after-uninstalling-ios-app-on-device , https://stackoverflow.com/questions/3671499/iphone-keychain-items-persist-after-application-uninstall , https://anjay.sh/posts/ios-keychain/ , https://dev.classmethod.jp/en/articles/ios-device-identifiers-vs-android-ssaid/ , https://stackoverflow.com/questions/80005125/how-to-uniquely-identify-an-ios-device-and-persist-the-identifier-after-app-rein
First-launch detection
- First launch = absence of your own persisted install record. Store an install UUID on first
initialize()(UserDefaults for the install-scoped ID; Keychain for the vendor-scoped persistent ID). No OS callback exists;isFirstLaunchis purely SDK-state. - Reinstall semantics drive attribution policy: UserDefaults ID dies with uninstall (fresh install → new user), Keychain ID survives (device returner). Use the Keychain ID to detect reinstalls for re-attribution/refraud, but declare its collection honestly in the privacy manifest and keep it first-party (never cross-app linked → no ATT).
- IDFA handling pattern (Adjust-style): SDK reads
ATTrackingManager.trackingAuthorizationStatus, includes IDFA only when.authorized, never requests the prompt itself unless the integrator opts in via config. Source: https://dev.adjust.com/en/sdk/ios/features/att/ - Keychain caveat: items persisting past uninstall is expected Apple behavior (documented by Apple engineers) but some managed environments differ; treat Keychain-UUID as "highly persistent, not guaranteed eternal," and mirror the ID in DeviceCheck's 2 bits for hard fraud checks if needed. Sources: https://stackoverflow.com/questions/3671499/iphone-keychain-items-persist-after-application-uninstall , https://dev.classmethod.jp/en/articles/ios-device-identifiers-vs-android-ssaid/
Implications for an OptoLink iOS SDK
- Universal Links are the only primary link mechanism (
applinks:entitlement + AASA on the OptoLink short-link domain(s)); custom schemes are a documented fallback for webview-to-app hops only. The SDK ships docs for both AASA hosting (strict: HTTPS,application/json, no redirect, <128 KB) and entitlement setup. - Document the Apple CDN lag: AASA changes propagate in hours via Apple's CDN; ship a
?mode=developerguidance section and an AASA validator/checklist in onboarding so customer integrations don't fail silently. - Instruct integrators to handle BOTH delivery paths:
.onOpenURL+.onContinueUserActivity(NSUserActivityTypeBrowsingWeb)feeding oneOptoLink.handle(url:)entry point (andscene(_:continue:)for UIKit apps) — QR/cold-start Release builds demonstrably bypass.onOpenURL. - Deferred deep linking: clipboard handoff is the core mechanism — short opaque token written by the click page, resolved server-side on first open. It survives Private Relay and matches Branch's current NativeLink direction.
- Use
UIPasteboard.detectPatterns([.probableWebURL])(iOS 16+) as the silent gate before any real pasteboard read — never read clipboard content on organic installs, never trigger the paste prompt without a probable match. On iOS 16+, offer an optionalUIPasteControl-based "restore link" button (tap = consent, no prompt). - Treat IP/cookie "Safari matching" as best-effort only and never implement fingerprint matching — Apple's privacy-manifest regime and iOS 26's Advanced Fingerprinting Protection make it a compliance liability; document a graceful degrade path (campaign-level attribution) when no match mechanism fires.
- Ship a PrivacyInfo.xcprivacy with the SDK from day one:
NSPrivacyCollectedDataTypes(device ID, product interaction), UserDefaults reasonCA92.1, and an explicitNSPrivacyTracking: falseif we stay first-party-only (no IDFA, no cross-app linking) — that keeps customer apps un-prompted by ATT and review-clean. - Offer optional IDFA support, opt-in by config: SDK reads ATT status, includes IDFA only when
.authorized, never prompts on its own; document Guideline 5.1.2(i) risk for integrators who enable it. - First-party session/install identifiers, not fingerprints: install UUID in UserDefaults (install-scoped) + vendor UUID in Keychain (device-scoped, survives reinstall) for re-attribution and fraud checks; both declared in the privacy manifest; no cross-app linking → no ATT requirement.
- Keep the SDK dependency-free and small (< a few MB; ideally source-distributed) — mirrors the zero-dependency Node SDK posture and avoids privacy-manifest/signing conflicts inside customer apps.
- Distribute via Swift Package Manager (source package as primary, signed XCframework binary target as optional artifact with checksum); skip CocoaPods or provide a stub podspec only if customers demand it.
- Modern Swift API surface:
async/awaitinitialize()/resolve()methods, an actor for SDK state and the pending-link queue,Sendablelink-payload structs; maintain a lightweight completion-handler facade for pre-concurrency codebases if the min target requires it. - Target iOS 15 as the deployment floor,
#available(iOS 16, *)for paste-pattern/UIPasteControlfeatures — covers ~96% of devices in 2026. - Queue deferred links behind app readiness: persist the resolved payload and let the app decide when to route (post-onboarding/login) — the pending-link queue pattern; SDK exposes
onDeferredLinkonce, apps gate navigation. - Position AdServices/AdAttributionKit as paid-UA plumbing, not the product: organic/shared-link deferred context (our differentiator vs ad networks) comes from Universal Links + clipboard/App-Group handoff; if we later serve paid campaigns, integrate AAK postbacks server-side, not in the client SDK.
- Consider an optional App Clip companion target (customer-hosted, SDK-provided helper) as the deterministic premium path: clip writes the invocation URL to a shared App Group, full app consumes it on first launch — zero prompts, zero matching; document the ≤15 MB and separate-target trade-offs.