iOS SDK
The GrowthRail iOS SDK is the native Swift counterpart to the React Native SDK. It provides attribution and referral APIs, automatic referral UI (trigger, banner, and dashboard), and deep-link handling for SwiftUI and UIKit apps.
Installation
The SDK is distributed as a binary Swift package from GrowthRail/growthrail-ios-sdk. There is no CocoaPods artifact.
Install with Xcode
- Choose File → Add Package Dependencies.
- Enter
https://github.com/GrowthRail/growthrail-ios-sdk.git. - Select a released version (prefer an exact version for production).
- Add the
GrowthRailproduct for full UI, orGrowthRailCorefor a headless integration.
Install from Package.swift
dependencies: [
.package(
name: "GrowthRail",
url: "https://github.com/GrowthRail/growthrail-ios-sdk.git",
from: "0.1.8"
),
],
targets: [
.target(
name: "YourTarget",
dependencies: [
.product(name: "GrowthRail", package: "GrowthRail"),
// Or: .product(name: "GrowthRailCore", package: "GrowthRail"),
]
),
]0.1.8. SwiftPM verifies XCFramework checksums automatically.| Product | Use when |
|---|---|
GrowthRail | Full SDK including SwiftUI/UIKit host UI. Re-exports Core APIs via import GrowthRail. |
GrowthRailCore | Attribution and referral APIs only — you render your own UI and observe GrowthRail.shared.state. |
Configuration
Call GrowthRail.configure once at app startup (for example in App.init() or application(_:didFinishLaunchingWithOptions:)). Use a publishable mobile key; never ship a server secret in the app binary.
import GrowthRail
import SwiftUI
@main
struct ExampleApp: App {
init() {
GrowthRail.configure(
GrowthRailConfiguration(
projectSecretKey: "sk_your_publishable_mobile_key",
appearance: .dark,
theme: GrowthRailTheme(primaryColor: "#2563eb"),
debug: true
)
)
}
var body: some Scene {
WindowGroup {
ContentView()
.growthRailHost()
.onOpenURL { _ = GrowthRail.shared.handle(url: $0) }
}
}
}Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
projectSecretKey | string | — | Required Publishable mobile key (sk_...). |
apiURL | URL | production API | Override for staging or local API testing. |
appearance | .light | .dark? | system | Preferred appearance for automatic UI. |
theme.primaryColor | string? | campaign / #2563eb | Hex primary color for trigger and dashboard chrome. |
disableTriggerButton | bool | false | Never show the automatic floating/edge trigger. |
userId | string? | nil | If set, identifies the user automatically after bootstrap. |
debug | bool | false | Verbose logging. Disable in production. |
cookieDomain and autoPageTrack exist for React Native source compatibility and have no effect on iOS.Automatic UI
With the GrowthRail product, attach the host once at the root. The host renders the server-configured trigger, new-user banner, and referral dashboard.
SwiftUI
ContentView()
.growthRailHost()
// Or: .growthRailHost(sdk: GrowthRail.shared)UIKit
final class HomeViewController: UIViewController {
private let growthRailHost = GrowthRailUIKitHost()
override func viewDidLoad() {
super.viewDidLoad()
growthRailHost.attach(to: self)
}
deinit {
growthRailHost.detach()
}
}Backend campaign settings drive layout at runtime:
| Field | Values | Behavior |
|---|---|---|
trigger.displayMode | floating | edge | none | Circle inset trigger, flush edge tab, or hidden. Also respect disableTriggerButton. |
trigger.position | bottom-right, bottom-left, top-right, top-left | Corner placement for the trigger. |
modal.componentType | modal | drawer | Centered card over a dimmed backdrop, or system bottom sheet with detents. |
banner.position | center-top, center-bottom, left-*, right-* | New-user promotional banner placement after attributed install/open. |
User Management
Call initAppUser after authentication with a stable app user ID (for example a RevenueCat app user ID or your database ID — never an email). Any attribution captured from an incoming link is bound automatically.
Task {
do {
let user = try await GrowthRail.shared.initAppUser(userID)
let referralLink = await GrowthRail.shared.getReferralLink()
let attributionToken = await GrowthRail.shared.getAttributionToken()
} catch {
// Present or log the integration error
}
}GrowthRail.shared.state is an ObservableObject with isInitialized, isUserReady, currentUser, isLoading, error, referral fields, trigger visibility, banner state, and dashboard state.
Common APIs
| Need | API |
|---|---|
| Identify user | try await GrowthRail.shared.initAppUser(userID) or identify(userID) |
| Open / close dashboard | showReferralDashboard(options:), hideReferralDashboard() |
| Incoming attribution | getReferralTrackingId(), getAttributionToken(), getCapturedReferralCode() |
| Current referral data | getReferralLink(), getReferralCode() |
| Track a non-standard source | try await trackReferral(code, rewardEventName:) |
| Dismiss banner | dismissBanner() |
| Custom UI | Observe GrowthRail.shared.state; optionally embed ReferralDashboard / TriggerButton |
Dashboard options override
Pass ReferrerModalOptions to override title, description, presentation, appearance, or primary color for a single open:
GrowthRail.shared.showReferralDashboard(
options: ReferrerModalOptions(
title: "Invite Friends",
description: "Share your link and earn rewards.",
componentType: .drawer,
appearance: .dark,
theme: GrowthRailTheme(primaryColor: "#2563eb")
)
)Deep Linking
Register a custom URL scheme or Universal Link, then forward URLs to GrowthRail. The handler returns true only when the URL contains a non-empty referralCode query parameter.
SwiftUI
.onOpenURL { url in
_ = GrowthRail.shared.handle(url: url)
}UIKit / AppDelegate
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
GrowthRail.shared.handle(url: url)
}
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
guard let url = userActivity.webpageURL else { return false }
return GrowthRail.shared.handle(url: url)
}Deferred attribution uses privacy-preserving fingerprint matching on first launch and does not collect IDFA. The SDK persists the referrer code and tracking ID, then forwards the tracking ID when the user is initialized.
xcrun simctl openurl booted 'your-app://open?referralCode=TEST123'Complete Example
import GrowthRail
import SwiftUI
@main
struct ExampleApp: App {
init() {
GrowthRail.configure(
GrowthRailConfiguration(
projectSecretKey: "sk_your_publishable_mobile_key",
debug: true
)
)
}
var body: some Scene {
WindowGroup {
ContentView()
.growthRailHost()
.onOpenURL { _ = GrowthRail.shared.handle(url: $0) }
.task {
_ = try? await GrowthRail.shared.initAppUser("user_123")
}
}
}
}
struct ContentView: View {
var body: some View {
Button("Invite Friends") {
GrowthRail.shared.showReferralDashboard()
}
}
}Differences from React Native
| Feature | React Native | iOS (Swift) |
|---|---|---|
| Distribution | npm (@growth-rail/react-native) | SwiftPM binary XCFrameworks |
| Entry point | GrowthRailProvider + hooks | GrowthRail.configure + .growthRailHost() |
| Storage | AsyncStorage | App Group / UserDefaults-backed storage |
| UI | React Native components | SwiftUI overlay / UIKit host |
| Modal vs drawer | Custom animated views | Centered card vs system bottom sheet |