LinkSense
FeaturesPricingDocs
Sign InGet Started
LinkSense

Smart dynamic mobile links for the modern web

Product

  • Features
  • Pricing
  • Documentation

Company

  • About
  • Contact
  • Privacy
  • Terms
  • Refund Policy

Support

  • Help Center

© 2026 Informacijske storitve BACK2PIXELS, Jan Kokalj s.p. All rights reserved.

Getting Started

Introduction

Core Features

ProjectsDynamic LinksURL ShorteningSocial PreviewsAnalytics

Deep Linking

iOS Deep LinkingAndroid Deep Linking

Mobile SDKs

iOS SDKBetaAndroid SDKBetaFlutter SDKBetaFlutterFlow SDKSoonReact Native SDKPreview

Account & Billing

Plans & Billing

Migration

Firebase Migration

API Reference

API OverviewAPI Endpoints
DocsMobile SDKsiOS SDK
Mobile SDKs

iOS SDK

Integrate the LinkSense iOS SDK to enable deferred deep linking and dynamic link management in your iOS app.
Beta
Beta release

The iOS SDK is currently in beta. The public API surface in Sources/LinkSense/*.swift may change between 0.x releases. Pin to an exact version in production using .exact("0.1.0") in your Package.swift and review the changelog before upgrading. We commit to API stability at 1.0.

Overview

The LinkSense iOS SDK delivers four capabilities:

  • Install-time attribution — match a user's post-install session to the link they tapped before downloading your app.
  • Deferred deep linking — surface the original link URL via a callback after install.
  • Universal Link forwarding — translate Universal Link taps into structured navigation events.
  • Link CRUD — create, read, update, and delete dynamic links directly from the device.

The SDK ships as a Swift Package with zero third-party dependencies. It does not collect IDFA and never reads the clipboard without explicit opt-in.

Prerequisites

  • iOS 14.0 or later deployment target
  • Xcode 15 or later, Swift 5.9+
  • An SDK key from your LinkSense project (Project Settings → SDK Keys)
  • Universal Links configured for your project subdomain (see iOS Deep Linking)

Installation

Add the SDK via Swift Package Manager. In Xcode, choose File → Add Package Dependencies… and paste the repository URL:

Repository URL
bash
https://github.com/LinkSense-net/linksense-ios-sdk.git

Or add the dependency directly in your Package.swift:

.package(url: "https://github.com/LinkSense-net/linksense-ios-sdk.git", from: "0.1.0")
No CocoaPods

The iOS SDK ships only via Swift Package Manager. There is no podspec. If your project still uses CocoaPods, add the package via Xcode's Add Package Dependencies dialog alongside your existing Podfile.

Configuration

Call configure once at app launch, then start to begin install-time attribution:

App.swift / AppDelegate.swift
swift
import LinkSense
 
LinkSense.shared.configure(
LinkSenseConfiguration(
sdkKey: "ls_sdk_<project>_<random>",
enableClipboard: false,
logLevel: .off
)
)
LinkSense.shared.start()

Configuration fields:

FieldTypeRequiredDescription
sdkKeyStringYesYour project SDK key (format: ls_sdk_<project>_<random>). Generate one in Project Settings → SDK Keys.
enableClipboardBoolNoRead the pasteboard on first launch for clipboard-based deferred attribution. iOS 14+ shows a paste notification to the user. Default false.
logLevelLinkSenseLogLevelNoDiagnostic logging level (.off, .error, .warning, .info, .debug). Default .off — recommended for production.
Call configure exactly once

Subsequent calls to configure after the first are no-ops by design. The SDK reuses the same install idempotency key across cold starts to prevent double-attribution.

Handling Deferred Deep Links

Register a handler to receive the original dynamic link URL once attribution resolves. The callback fires on the main queue.

App.swift
swift
LinkSense.shared.onDeferredDeepLink { url in
if let url = url {
router.handle(url)
}
}
When does this fire?

The handler fires the first time start() resolves an install with a matching click, then never again for that install. If no click matched, the URL is nil.

Forwarding Universal Links

When iOS opens your app via a Universal Link (warm path), forward the NSUserActivity to the SDK so it can resolve the link target:

AppDelegate / SceneDelegate
swift
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
return LinkSense.shared.continueUserActivity(userActivity) { url in
if let url = url {
router.handle(url)
}
}
}

For AASA hosting and the Associated Domains entitlement, see iOS Deep Linking.

Link CRUD

The SDK exposes createLink, link(withId:), updateLink, and deleteLink. All completions dispatch on the main queue.

Creating a link
swift
LinkSense.shared.createLink(
options: CreateLinkOptions(
name: "Summer sale",
desktopUrl: URL(string: "https://example.com/sale"),
iosFallbackUrl: URL(string: "https://apps.apple.com/app/id123456789")
)
) { result in
switch result {
case .success(let link):
print("Created: \(link.url)")
case .failure(let error):
print("Failed: \(error)")
}
}
Three-state PATCH semantics

UpdateLinkOptions uses double-optionals (URL??) to distinguish three states: omit the field (.none), explicitly clear it (.some(.none)), or set a new value (.some(.some(value))).

Error Handling

All CRUD methods return Result<T, LinkSenseError>. The LinkSenseError enum maps server error codes to typed cases:

Switching on LinkSenseError
swift
LinkSense.shared.link(withId: "ln_abc123") { result in
switch result {
case .success(let link):
// use link
break
case .failure(let error):
switch error {
case .notConfigured:
print("Call configure() first")
case .network(let underlying):
print("Network failure: \(underlying)")
case .rateLimited(let retryAfter):
print("Retry after \(retryAfter)s")
case .server(let code, let message, _):
print("Server \(code): \(message)")
default:
print("Other error: \(error)")
}
}
}

Common cases: .notConfigured, .network, .unauthorized, .forbiddenCrossScope, .forbiddenField, .invalidInput(fieldErrors:), .notFound, .customPathExists, .rateLimited(retryAfter:), .server(code:message:status:).

Example & Resources

The iOS SDK repository ships with a SwiftUI sample app demonstrating configuration, deferred deep link handling, Universal Link forwarding, and link CRUD.

iOS Deep LinkingConfigure AASA and Associated Domains.Android SDKIntegration guide for Android.Flutter SDKCross-platform integration with Flutter.
PreviousAndroid Deep LinkingNextAndroid SDK

On this page

OverviewPrerequisitesInstallationConfigurationHandling Deferred Deep LinksForwarding Universal LinksLink CRUDError HandlingExample & Resources
API ReferenceHTTP endpoints behind the SDK.