iOS Quickstart
Get Running with the Convert iOS SDK in 5 Minutes
THIS ARTICLE WILL HELP YOU:
- Get an Overview
- Add Dependency
- Understand Platform Requirements
- Initialize Once at App Startup
- Wait for SDK readiness
- Create a Visitor Context
- Run an Experience
- Complete Handler Style
- Track Conversion and Revenue
- Know UI Facing Implementation Consideration
- Know Offline Behavior
- Understand Privacy and Data Collection
- Avoid Duplicate Bucketing
- Get QA Checklist
- Troubleshoot
- Conclusion
Overview
The Convert iOS SDK lets you run Convert Full Stack experiments and feature flags directly inside native iOS, macOS, and tvOS applications.
The SDK is designed for app-side experimentation where the application decides which screen, feature, onboarding flow, layout, pricing treatment, or user experience should be shown to a visitor.
You need an SDK Key from your Convert dashboard and an Xcode project targeting:
- iOS 15+
- macOS 12+
- tvOS 15+
Unlike server-side SDKs such as PHP or Ruby, the iOS SDK fetches its bucketing configuration asynchronously. You should wait for sdk.ready() before making experiment decisions. Calling runExperience() before the SDK is ready returns nil.
Convert Full Stack projects allow experimentation across frontend and backend systems, enabling optimization of complete user experiences rather than only browser-based interfaces.
Source: Full Stack Experiments on Convert
1. Add the Dependency
Swift Package Manager (Recommended)
In Xcode:
File → Add Package Dependencies
Add:
https://github.com/convertcom/ios-sdk.git
Or add the package directly to Package.swift:
dependencies: [
.package(
url: "https://github.com/convertcom/ios-sdk.git",
from: "1.0.0"
)
],
targets: [
.target(
name: "MyApp",
dependencies: [
.product(
name: "ConvertSwiftSDK",
package: "ios-sdk"
)
]
)
]
CocoaPods
Add the following to your Podfile:
pod 'ConvertSwiftSDK', '~> 1.0'
Then run:
pod install
and open the generated .xcworkspace.
ConvertSwiftSDK automatically installs ConvertSwiftSDKCore, so you only need to reference ConvertSwiftSDK.
Platform Requirements
|
Platform |
Minimum Version |
|
iOS |
15+ |
|
macOS |
12+ |
|
tvOS |
15+ |
2. Initialize Once at App Startup
Create exactly one SDK instance per application process.
The SDK owns:
- a background URLSession
- an offline event queue
- a configuration refresh scheduler
Creating multiple instances may result in duplicated work and unnecessary resource consumption.
SwiftUI Example
import SwiftUI
import ConvertSwiftSDK
@main
struct MyApp: App {
let sdk = ConvertSwiftSDK(
configuration: ConvertConfiguration(
sdkKey: "YOUR_SDK_KEY"
)
)
var body: some Scene {
WindowGroup {
ContentView()
.task {
try? await sdk.ready()
}
.environmentObject(sdk)
}
}
}
UIKit Example
import UIKit
import ConvertSwiftSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var sdk: ConvertSwiftSDK!
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
sdk = ConvertSwiftSDK(
configuration: ConvertConfiguration(
sdkKey: "YOUR_SDK_KEY",
logLevel: .info
)
)
return true
}
}
Use .debug logging during integration and QA.
Wait for SDK Readiness
The SDK downloads its bucketing configuration asynchronously.
You must wait for:
try await sdk.ready()
before running experiments.
Calling:
await ctx.runExperience("homepage-redesign")
before readiness is reached returns nil.
This is not an error. It simply means decisions are not yet available.
3. Create a Visitor Context
Create a visitor context after the SDK becomes ready.
let ctx = sdk.createContext()
This automatically creates and persists a UUID-based visitor identifier.
The persisted identifier allows the SDK to recognize the same visitor across application launches and sessions.
For authenticated users, you may choose to use your own stable internal user identifier where appropriate so experiment assignments remain consistent for that user.
4. Running an Experience
Once the SDK is ready, create a context and run an experience.
try await sdk.ready()
let ctx = sdk.createContext()
if let variation = await ctx.runExperience("homepage-redesign") {
switch variation.key {
case "control":
renderControl()
case "treatment":
renderTreatment()
default:
renderControl()
}
} else {
renderControl()
}
A returned variation contains the assigned variation key for the visitor.
A nil result means:
- SDK not ready
- visitor not bucketed
- no matching experience assignment
It is not considered an error condition.
Completion Handler Style
For UIKit or callback-based code:
sdk.ready { result in
guard case .success = result else {
return
}
let ctx = self.sdk.createContext()
Task { @MainActor in
if let variation = await ctx.runExperience("homepage-redesign") {
self.applyVariation(variation.key)
}
}
}
The callback is delivered on MainActor, making it safe to update user interface components.
5. Tracking Conversions and Revenue
Basic Conversion
await ctx.trackConversion(
"signup-completed"
)
Conversion with Revenue
await ctx.trackConversion(
"purchase-completed",
goalData: [
.amount: .double(49.99),
.transactionId: .string("tx-42")
]
)
Repeat Purchases
If a customer makes another purchase:
await ctx.trackConversion(
"purchase-completed",
goalData: [
.amount: .double(29.99)
],
forceMultipleTransactions: true
)
The conversion event remains deduplicated while the additional revenue transaction is recorded.
6. iOS UI-Facing Implementation Considerations
The SDK determines experiment assignments inside the application. Your UI implementation should use those decisions consistently.
Pattern A: Wait for Assignment Before Rendering
try await sdk.ready()
let ctx = sdk.createContext()
if let variation = await ctx.runExperience("checkout-test") {
switch variation.key {
case "simplified":
showSimplifiedCheckout()
default:
showStandardCheckout()
}
}
This approach avoids visual changes after a screen is displayed.
Pattern B: Render Default UI Then Upgrade
showStandardCheckout()
Task {
try await sdk.ready()
let ctx = sdk.createContext()
if let variation = await ctx.runExperience("checkout-test"),
variation.key == "simplified" {
await MainActor.run {
showSimplifiedCheckout()
}
}
}
This pattern can produce visible UI changes after the initial screen appears.
Use it carefully for onboarding, pricing, and checkout experiences.
Pattern C: Backend + App Consistency
When backend systems and iOS applications both depend on experiment assignments:
- use the same stable visitor identifier
- keep one source of truth for assignment
- avoid independently bucketing the same visitor in multiple systems
- pass assignment data between backend and app when needed
This helps ensure a consistent user experience across all touchpoints.
Source: Full Stack Experiments on Convert
7. Offline Behavior
The iOS SDK automatically handles offline devices.
Events are:
- batched
- persisted to disk
- retried automatically
- flushed in the background
This means:
- events survive app restarts
- events survive temporary network outages
- visitors can continue using the application while offline
You do not need to manually manage:
- retry queues
- local persistence
- background delivery
The SDK handles these responsibilities automatically.
8. Privacy and Data Collection
The iOS SDK includes Apple's required privacy manifest support.
When implementing experimentation on iOS, ensure that your use of analytics, experimentation, and tracking technologies complies with your organization's privacy requirements and any applicable platform policies.
Avoid Duplicate Bucketing
Avoid evaluating the same experiment multiple times using different identifiers.
Common causes include:
- anonymous IDs before login and user IDs after login
- backend assignment plus separate app assignment
- multiple SDK instances
To prevent inconsistencies:
- initialize one SDK instance
- use stable visitor identifiers
- keep one source of truth for assignments
- validate assignments during QA
Source: Full Stack Experiments on Convert
9. QA Checklist
Before launching your implementation, verify:
- SDK dependency installed correctly
- SDK initialized once
- Correct SDK Key configured
- sdk.ready() completes successfully
- Visitor contexts are created correctly
- Experience keys match Convert configuration
- Variations render correctly
- Goal keys match Convert configuration
- Revenue tracking sends expected values
- Offline events are delivered after reconnecting
- Anonymous and authenticated users behave as expected
- Debug logs show successful initialization
10. Troubleshooting
runExperience() Returns nil
Check that:
try await sdk.ready()
completed before running the experience.
A nil value is expected when the SDK is not ready or the visitor is not bucketed.
Conversions Not Appearing
Verify:
- goal key exists in Convert
- visitor context was created successfully
- device has network connectivity
- SDK initialized correctly
Unknown goal keys generate a warning log and are silently dropped.
Multiple Variations for the Same User
Confirm:
- only one SDK instance exists
- visitor identifiers remain stable
- backend and app use consistent assignment logic
Source: Full Stack Experiments on Convert
Conclusion
The Convert iOS SDK enables Full Stack experimentation and feature delivery inside native Apple applications. Install the SDK using Swift Package Manager or CocoaPods, initialize a single SDK instance, wait for readiness, create a visitor context, run experiences, and track conversions.
For user-facing experiences, carefully decide whether to wait for assignment before rendering screens or render a default experience first. Keeping assignment logic consistent across backend and frontend systems helps ensure accurate reporting and a better visitor experience.
Sources: