BaxLinks/Swift SDK

Swift SDK

Create and manage deep links natively in your iOS app

Installation

In Xcode: File → Add Package Dependencies and enter:

https://github.com/baxcloud/swift-links-sdk.git

Or add to Package.swift:

dependencies: [
    .package(url: "https://github.com/baxcloud/swift-links-sdk.git", from: "1.0.0")
]

Device info (IDFV, device model, OS version) is collected automatically. No extra dependencies needed — uses only Foundation and UIKit.

Quick Start

1. Initialize the SDK

1import BaxCloudLinks
2
3let links = BaxCloudLinksClient(
4    config: BaxCloudLinksConfig(
5        projectId: "your-project-id",
6        apiKey: "your-api-key",
7        debug: true // Enable SDK debug logs (disable in production)
8    )
9)

2. Create a Deep Link

iOS/Android store URLs are configured once in Dashboard → BaxLinks → Setup. You only pass link-specific data:

1let link = try await links.createLink(CreateLinkOptions(
2    fallbackUrl: "https://yourapp.com/invite?code=ABC123",
3    deepLinkPath: "/invite/ABC123",
4    deepLinkParams: ["inviteCode": .string("ABC123"), "referrer": .string("john")],
5    title: "Join us on MyApp!"
6))
7
8// Short URL from project subdomain (e.g. https://xxxxx.baxcloud.link/abc123)
9print(link.shortUrl ?? link.slug)

3. Track Install (device info auto-collected via IDFV)

1// Device ID, model, OS, OS version collected automatically via UIDevice
2try await links.trackInstall(appVersion: "1.0.0")

4. Get Deferred Deep Link

1// On first launch — device fingerprint matched automatically
2let result = try await links.getDeferredLink()
3
4if result.found, let path = result.deepLinkPath {
5    // Navigate user to the right screen
6    navigate(to: path, params: result.deepLinkParams)
7}

Debug Logging

Trace SDK activity during development

Set debug: true in the config to see detailed SDK activity in the Xcode console. All messages are prefixed with [BaxCloudLinks]. Disable in production.

[BaxCloudLinks] BaxCloudLinks SDK initialized (project: abc123)
[BaxCloudLinks] handleDeepLink: https://xxx.baxcloud.link/mTX4Jw (scheme=https)
[BaxCloudLinks] resolveLink: mTX4Jw
[BaxCloudLinks] GET .../v1/sdk/links/resolve/mTX4Jw → 200
[BaxCloudLinks] handleDeepLink: resolved params=[type: post, objectId: abc]

Builder API

Fluent interface for constructing link options

1let options = BaxLinkBuilder("https://yourapp.com/landing")
2    .setAlias("summer-promo")
3    .setTitle("Summer Sale — 50% Off!")
4    .setDeepLinkPath("/promo/summer2024")
5    .addDeepLinkParam("discount", .string("50"))
6    .setMaxClicks(1000)
7    .setExpiresAt(Date().addingTimeInterval(86400 * 30))
8    .build()
9
10let link = try await links.createLink(options)

Convenience Methods

Purpose-built methods for common use cases

1// Invitation link
2let inviteLink = try await links.createInvitationLink(
3    inviteCode:  "ABC123",
4    fallbackUrl: "https://yourapp.com/invite?code=ABC123",
5    inviterName: "John"
6)
7
8// Referral link
9let refLink = try await links.createReferralLink(
10    referralCode: "REF_JOHN_2024",
11    fallbackUrl:  "https://yourapp.com/signup?ref=REF_JOHN_2024",
12    referrerName: "John Doe"
13)
14
15// App install campaign link
16let installLink = try await links.createAppInstallLink(
17    fallbackUrl: "https://yourapp.com",
18    campaign:    "summer_2024",
19    source:      "instagram"
20)
21
22// Content sharing link
23let contentLink = try await links.createContentLink(
24    contentType: "post",
25    contentId:   "post-789",
26    fallbackUrl: "https://yourapp.com/post/post-789",
27    title:       "Check out this post!"
28)

Handling Incoming Links

Resolve short links and URI scheme links automatically

The SDK provides handleDeepLink(_ url: URL) which automatically detects HTTPS short links (Universal Links) and resolves them via the API, or extracts query parameters directly from URI scheme links. Returns [String: Any]? or nil.

SwiftUI

1@main
2struct MyApp: App {
3    let links = BaxCloudLinksClient(
4        config: BaxCloudLinksConfig(
5            projectId: "...", apiKey: "...", debug: true
6        )
7    )
8
9    var body: some Scene {
10        WindowGroup {
11            ContentView()
12                .onOpenURL { url in
13                    Task {
14                        if let params = await links.handleDeepLink(url) {
15                            let type = params["type"] as? String
16                            let objectId = params["objectId"] as? String
17                            // navigate based on type and objectId
18                        }
19                    }
20                }
21        }
22    }
23}

UIKit (SceneDelegate)

1func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
2    guard let url = userActivity.webpageURL else { return }
3    Task {
4        if let params = await linksClient.handleDeepLink(url) {
5            navigate(to: params["type"] as? String,
6                     objectId: params["objectId"] as? String)
7        }
8    }
9}
10
11func scene(_ scene: UIScene,
12           openURLContexts URLContexts: Set<UIOpenURLContext>) {
13    guard let url = URLContexts.first?.url else { return }
14    Task {
15        if let params = await linksClient.handleDeepLink(url) {
16            navigate(to: params["type"] as? String,
17                     objectId: params["objectId"] as? String)
18        }
19    }
20}

You can also use the lower-level handleIncomingURL(_:) if you only need to parse the URL without API resolution.

Resolve a Short Link Manually

1let result = try await links.resolveLink(slug: "mTX4Jw")
2// ["found": true, "deepLinkPath": "/post/abc",
3//  "deepLinkParams": ["type": "post", "objectId": "abc"]]

Extract Slug from URL

1let slug = links.extractSlug(from: url)
2// "mTX4Jw"

Event Tracking

Device info (IDFV, model, OS, version) is collected automatically — no manual deviceId needed

1// First launch — attributes install to a link click
2try await links.trackInstall(appVersion: "1.0.0")
3
4// Every app open
5try await links.trackOpen(appVersion: "1.0.0")
6
7// After signup
8try await links.trackSignup()
9
10// After a purchase
11try await links.trackPurchase(value: 29.99, eventData: ["planId": .string("pro")])
12
13// Custom event
14try await links.trackCustomEvent(eventName: "level_complete", eventValue: 5)

Event Types: installopenreinstallsignuppurchasecustom

Deferred Deep Linking

Navigate users to the right screen after install

Call getDeferredLink() on first launch. BaxCloud fingerprints the device IP and matches it to a recent link click (48-hour window).

1func checkDeferredLink() async {
2    // Ensure we only check once after install
3    let key = "bax_deferred_checked"
4    guard !UserDefaults.standard.bool(forKey: key) else { return }
5    UserDefaults.standard.set(true, forKey: key)
6
7    // Track install (device info auto-collected)
8    try? await links.trackInstall(appVersion: "1.0.0")
9
10    // Check for deferred deep link
11    guard let result = try? await links.getDeferredLink(),
12          result.found,
13          let path = result.deepLinkPath else { return }
14
15    await MainActor.run {
16        router.navigate(to: path, params: result.deepLinkParams?.compactMapValues { $0.stringValue })
17    }
18}

How it works: Device IP is matched to a recent click within 48 hours. Returns deepLinkPath + deepLinkParams.

Attribution & Install Tracking

Query attributed installs for referral rewards

1let result = try await links.getAttributedInstalls()
2print("Total: \(result.total)")
3
4for install in result.data {
5    print("\(install.linkSlug ?? "-") · \(install.os ?? "-") · \(install.country ?? "-")")
6}
7
8// Filter by link
9let linkInstalls = try await links.getAttributedInstalls(
10    linkId: "your-link-id",
11    page: 1,
12    limit: 20
13)

Platform Setup

Required Xcode configuration. Get your subdomain from Dashboard → BaxLinks → Setup.

1. Enable Associated Domains

In Xcode: Signing & Capabilities → + Capability → Associated Domains

applinks:xxxxx.baxcloud.link
applinks:yourdomain.com

2. Add URI Scheme to Info.plist

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myapp</string>
        </array>
    </dict>
</array>

3. Entitlements file

<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:xxxxx.baxcloud.link</string>
</array>

API Reference

Link Management

createLink(_:)Create a new deep link
getLink(_:)Get a link by ID
listLinks(status:search:page:limit:)List project links
updateLink(_:options:)Update a link
deleteLink(_:)Delete a link
pauseLink(_:) / resumeLink(_:) / archiveLink(_:)Change link status

Event Tracking

trackInstall(appVersion:linkSlug:)Track first install — auto device info
trackOpen(appVersion:linkSlug:)Track app open — auto device info
trackSignup(linkSlug:eventData:)Track signup
trackPurchase(value:linkSlug:eventData:)Track purchase
trackCustomEvent(eventName:eventValue:linkSlug:eventData:)Track custom event

Deep Linking & Attribution

handleDeepLink(_:) → [String: Any]?Resolve any incoming URL — HTTPS short links via API, URI scheme directly
resolveLink(slug:) → [String: Any]Resolve a short link slug to deep link data via the API
extractSlug(from:) → String?Extract the slug from a short link URL
handleIncomingURL(_:) → BaxDeepLinkDataParse an incoming URL (no API call)
getDeferredLink()Retrieve deferred deep link (auto device ID)
getAttributedInstalls(linkId:page:limit:)Query attributed installs
getAppConfig()Get project config + shortLinkBase
getProjectStats()Project-wide link stats
getLinkAnalytics(_:)Per-link click analytics