iOS SDK (Swift)
Full reference for the OnRamp Swift SDK. Works with UIKit and SwiftUI on iOS 14+.
Installation
Swift Package Manager
In Xcode: File → Add Package Dependencies, paste the repository URL, and add the OnRamp library to your target.
https://github.com/getonramp/onramp-swift
Then import the module wherever you need it:
import OnRamp
Setup
Call OnRamp.initialize() once at app launch before any OnRamp.step() calls.
UIKit - AppDelegate
import UIKit
import OnRamp
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
OnRamp.initialize(
apiKey: "onr_YOUR_API_KEY",
appVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
)
return true
}
}
SwiftUI - @main App struct
import SwiftUI
import OnRamp
@main
struct MyApp: App {
init() {
OnRamp.initialize(
apiKey: "onr_YOUR_API_KEY",
appVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Your API key is on the Settings page of each app in the dashboard.
OnRamp.initialize() options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | String | Yes | - | Your API key from Settings |
host | String | No | https://ingest.getonramp.dev | Override the ingestion endpoint for self-hosting |
appVersion | String? | No | nil | App version string, e.g. "2.4.1" - shows in version breakdown |
captureInstallReferrer | Bool | No | false | Capture install attribution (deep links via handleDeepLink(), Apple Search Ads) automatically - opt-in, see Attribution below |
Tracking steps
OnRamp.step(_:properties:)
Records a funnel milestone. Safe to call from any thread or SwiftUI view. The SDK fires events asynchronously via URLSession.
import OnRamp
// Basic
OnRamp.step("account_created")
// With custom properties
OnRamp.step("subscription_started", properties: [
"plan": "pro",
"billing_period": "annual",
"price_usd": 79.99,
])
Options
| Option | Type | Description |
|---|---|---|
properties | [String: Any]? | Custom key-value data attached to the event |
Property values must be primitives - strings, numbers, or booleans. Nested dictionaries are not supported. Numeric values become queryable as custom metrics in the funnel chart.
Identifying users
OnRamp.identify(_:)
Associates the current anonymous user with known identity traits. Call once after sign-in so integrations (Stripe, RevenueCat) can match the user to external records.
// After the user signs in
OnRamp.identify([
"email": user.email,
"userId": user.id,
])
identify() is entirely optional. All funnel and retention features work without it. Only call it if you have an integration connected and want to correlate OnRamp sessions with external revenue data.
Attribution
The SDK can capture which channel or campaign drove an install - deep links via handleDeepLink(), and Apple Search Ads automatically once enabled. Neither requires the device advertising identifier (IDFA) or an App Tracking Transparency prompt. This is off by default - pass captureInstallReferrer: true to turn it on:
OnRamp.initialize(apiKey: "onr_YOUR_API_KEY", captureInstallReferrer: true)
It defaults to false rather than true for two reasons: turning it on starts collecting a new category of data (campaign/keyword info) that you should consciously opt into rather than get for free on an SDK upgrade, and it can touch the same Apple Search Ads attribution surface an existing MMP (Adjust, AppsFlyer, Branch) might already read. OnRamp.setAttribution() (below) works regardless of this flag, so it's always safe to call if you get attribution data from elsewhere.
Deep links
Forward the URL your app receives to OnRamp.handleDeepLink(_:) - from application(_:continue:restorationHandler:) (UIKit) or .onContinueUserActivity/.onOpenURL (SwiftUI). This is a separate step from configuring the Universal Link itself (the associatedDomains entitlement and apple-app-site-association file), which your app still needs regardless.
// UIKit - AppDelegate
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
if let url = userActivity.webpageURL {
OnRamp.handleDeepLink(url)
}
return true
}
// SwiftUI
WindowGroup {
ContentView()
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in
if let url = activity.webpageURL {
OnRamp.handleDeepLink(url)
}
}
.onOpenURL { url in
OnRamp.handleDeepLink(url)
}
}
utm_source/utm_medium/utm_campaign/utm_term/utm_content (falling back to known ad click IDs like gclid/fbclid) are attached once, to this install's first tracked event, and never re-attached on later app opens.
Apple Search Ads
With captureInstallReferrer: true and AdServices linked (available automatically on iOS 14.3+), the SDK captures the attribution token on initialize() and sends it to OnRamp, which resolves it server-side into a campaign/keyword - the token itself is opaque and can't be resolved on-device.
Resolution is asynchronous
Unlike deep links, this data can take minutes to hours to appear in the dashboard - it depends on a server-to-server round trip to Apple's attribution API, not something available at track time. It also only reveals the paid keyword/campaign behind a Search Ads impression; there's no API (Apple or Google) for organic App Store search-term data.
OnRamp.setAttribution()
If you already use an MMP (Adjust, AppsFlyer, Branch, etc.), leave captureInstallReferrer at its default false and call this from its attribution-resolved callback instead:
OnRamp.initialize(apiKey: "onr_YOUR_API_KEY") // captureInstallReferrer left at its default (false)
// Inside your MMP's attribution callback:
OnRamp.setAttribution(source: "facebook", medium: "paid_social", campaign: "summer_promo")
This works independently of captureInstallReferrer - it's always safe to call, whether or not you've turned on OnRamp's own capture. No-ops if attribution has already been attached to this install's first tracked event.
Not covered: ad-network postback attribution
SKAdNetwork (Facebook/TikTok/etc install attribution) and deferred deep linking (matching a pre-install ad click to an install after a detour through the App Store) aren't built into OnRamp - that's full MMP territory (Adjust/AppsFlyer/Branch). If you already have one of those for this, OnRamp.setAttribution() above is the way to bring its resolved data into your OnRamp funnels.
Session management
OnRamp.newSession()
Force-starts a new session. Call after sign-out so the next user gets a clean session.
func handleLogout() {
signOut()
OnRamp.newSession()
}
Privacy
The SDK uses UserDefaults (not HTTP cookies) to persist the anonymous ID across app launches. No personal data is collected unless you explicitly call identify(). All events are sent to EU servers.
If your app targets the EU market, analytics storage (including UserDefaults) may require user consent under EU ePrivacy rules. OnRamp does not replace a consent banner.
Requirements
| Minimum | |
|---|---|
| iOS | 14.0 |
| Swift | 5.7 |
| Xcode | 14 |
