InsertAffiliateSwift SDK for iOS¶
The official iOS SDK for Insert Affiliate - track affiliate-driven in-app purchases and reward your partners automatically.
What does this SDK do? It connects your iOS app to Insert Affiliate's platform, enabling you to track which affiliates drive subscriptions and automatically pay them commissions when users make in-app purchases.
📋 Table of Contents¶
- Quick Start (5 Minutes)
- Essential Setup
- 1. Initialize the SDK
- 2. Configure In-App Purchase Verification
- 3. Set Up Deep Linking
- Verify Your Integration
- Advanced Features
- Troubleshooting
- Support
🚀 Quick Start (5 Minutes)¶
Get up and running with minimal code to validate the SDK works before tackling IAP and deep linking setup.
Prerequisites¶
- iOS 13.0+ and Swift 5.0+
- Xcode 12.0+
- Company Code from your Insert Affiliate dashboard
Installation¶
Step 1: Open your Xcode project
Step 2: Go to File > Add Packages
Step 3: Enter the repository URL:
Step 4: Select the branch main and confirm
Alternative: Swift Package Manager
Add to your Package.swift:
Your First Integration¶
Add this minimal code to your AppDelegate.swift to test the SDK:
import InsertAffiliateSwift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Initialize SDK with verbose logging (recommended during setup)
InsertAffiliateSwift.initialize(
companyCode: "YOUR_COMPANY_CODE", // Get from https://app.insertaffiliate.com/settings
verboseLogging: true // Enable verbose logging for setup
)
return true
}
}
For SwiftUI apps:
import SwiftUI
import InsertAffiliateSwift
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
InsertAffiliateSwift.initialize(companyCode: "YOUR_COMPANY_CODE", verboseLogging: true)
return true
}
}
Expected Console Output:
When the SDK initializes successfully, you'll see logs confirming initialization:
[InsertAffiliateSwift] SDK initialized with company code: YOUR_COMPANY_CODE
[InsertAffiliateSwift] Verbose logging enabled
✅ If you see these logs, the SDK is working! Now proceed to Essential Setup below.
⚠️ Disable verbose logging in production by setting verboseLogging: false or omitting it.
⚙️ Essential Setup¶
Complete these three required steps to start tracking affiliate-driven purchases.
1. Initialize the SDK¶
The SDK must be initialized in your AppDelegate before using any features. You've already done the basic initialization above, but here are additional options:
Basic Initialization (Recommended for Getting Started)¶
// Minimal setup with verbose logging enabled (recommended during development)
InsertAffiliateSwift.initialize(companyCode: "YOUR_COMPANY_CODE", verboseLogging: true)
Advanced Initialization Options (click to expand)
// With Insert Links enabled (for Insert Affiliate's built-in deep linking)
InsertAffiliateSwift.initialize(
companyCode: "YOUR_COMPANY_CODE",
verboseLogging: true, // Enable verbose logging
insertLinksEnabled: true, // Enable Insert Links
insertLinksClipboardEnabled: true, // Enable clipboard access (triggers permission prompt)
affiliateAttributionActiveTime: 604800, // Optional: 7 days attribution timeout (default: no timeout)
preventAffiliateTransfer: true // Optional: Protect original affiliate from being overwritten
)
2. Configure In-App Purchase Verification¶
Insert Affiliate requires a receipt verification method to validate purchases. Choose ONE of the following:
| Method | Best For | Setup Time | Complexity |
|---|---|---|---|
| RevenueCat | Most developers, managed infrastructure | ~10 min | ⭐ Simple |
| Adapty | Paywall A/B testing, analytics | ~10 min | ⭐ Simple |
| Iaptic | Custom requirements, direct control | ~15 min | ⭐⭐ Medium |
| App Store Direct | No 3rd party fees (subscriptions only) | ~20 min | ⭐⭐ Medium |
| Apphud | Alternative managed infrastructure | ~10 min | ⭐ Simple |
Option 1: RevenueCat (Recommended)
**Step 1: Code Setup**
Complete the [RevenueCat SDK installation](https://www.revenuecat.com/docs/getting-started/installation/ios) first, then modify your `AppDelegate.swift`:
import SwiftUI
import RevenueCat
import InsertAffiliateSwift
final class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
Purchases.configure(withAPIKey: "YOUR_REVENUE_CAT_API_KEY")
// Set up callback to sync affiliate attributes to RevenueCat whenever they change
// Note: Use preventAffiliateTransfer in initialize() to block affiliate changes in the SDK
InsertAffiliateSwift.setInsertAffiliateIdentifierChangeCallback { identifier, offerCode in
guard let identifier = identifier else { return }
// Ensure subscriber exists before setting attributes
Purchases.shared.getCustomerInfo { customerInfo, error in
guard let customerInfo = customerInfo else { return }
// OPTIONAL: Prevent attribution for existing subscribers
// Uncomment to ensure affiliates only earn from users they actually brought:
// if !customerInfo.entitlements.active.isEmpty { return } // User already subscribed, don't attribute
// Set attributes for tracking and targeting
var attributes: [String: String] = [
"insert_affiliate": identifier,
"insert_timedout": "" // Clear timeout flag
]
if let offerCode = offerCode {
attributes["affiliateOfferCode"] = offerCode // For RevenueCat targeting
}
Purchases.shared.attribution.setAttributes(attributes)
// Sync to enable targeting based on affiliateOfferCode
Purchases.shared.syncAttributesAndOfferingsIfNeeded { offerings, error in
print("Offerings synced, current: \(offerings?.current?.identifier ?? "none")")
}
}
}
// Initialize Insert Affiliate SDK
InsertAffiliateSwift.initialize(companyCode: "YOUR_COMPANY_CODE", verboseLogging: true)
// Sync existing affiliate on app launch
if let existingAffiliate = InsertAffiliateSwift.returnInsertAffiliateIdentifier() {
Purchases.shared.attribution.setAttributes(["insert_affiliate": existingAffiliate])
}
return true
}
}
Option 2: Adapty
**Step 1: Code Setup**
Complete the [Adapty SDK installation](https://docs.adapty.io/docs/ios-installation) first, then modify your `AppDelegate.swift`:
import SwiftUI
import Adapty
import InsertAffiliateSwift
final class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
// Initialize Adapty
Adapty.activate("YOUR_ADAPTY_PUBLIC_SDK_KEY")
// Initialize Insert Affiliate
InsertAffiliateSwift.initialize(companyCode: "YOUR_COMPANY_CODE", verboseLogging: true)
// Set Insert Affiliate identifier as Adapty custom attribute
if let applicationUsername = InsertAffiliateSwift.returnInsertAffiliateIdentifier() {
Task {
do {
var builder = AdaptyProfileParameters.Builder()
builder = try builder.with(customAttribute: applicationUsername, forKey: "insert_affiliate")
try await Adapty.updateProfile(params: builder.build())
} catch {
print("Failed to set Adapty attribution: \(error.localizedDescription)")
}
}
}
return true
}
}
// Example with Branch.io
Branch.getInstance().initSession(launchOptions: launchOptions) { (params, error) in
if let referringLink = params?["~referring_link"] as? String {
InsertAffiliateSwift.setInsertAffiliateIdentifier(referringLink: referringLink) { result in
guard let shortCode = result else { return }
// Update Adapty with the new affiliate identifier
Task {
do {
var builder = AdaptyProfileParameters.Builder()
builder = try builder.with(customAttribute: shortCode, forKey: "insert_affiliate")
try await Adapty.updateProfile(params: builder.build())
print("[Adapty] Set insert_affiliate attribute: \(shortCode)")
} catch {
print("Failed to set Adapty attribution: \(error.localizedDescription)")
}
}
}
}
}
Option 3: Iaptic
**Step 1: Code Setup**
Complete the [Iaptic account setup](https://www.iaptic.com/documentation/setup/ios) and [SDK installation](https://github.com/iridescent-dev/iap-swift-lib). Then modify your `AppDelegate.swift`:
import SwiftUI
import InAppPurchaseLib
import InsertAffiliateSwift
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
InsertAffiliateSwift.initialize(companyCode: "YOUR_COMPANY_CODE")
// Define products
let iapProductsArray = [
IAPProduct(
productIdentifier: "YOUR_APPLE_IAP_SUBSCRIPTION_ID",
productType: .autoRenewableSubscription
)
]
// Reinitialise In-App Purchases
InAppPurchase.stop()
if let applicationUsername = InsertAffiliateSwift.returnInsertAffiliateIdentifier() {
InAppPurchase.initialize(
iapProducts: iapProductsArray,
validatorUrlString: "https://validator.iaptic.com/v3/validate?appName=YOUR_IAPTIC_APP_NAME&apiKey=YOUR_IAPTIC_PUBLIC_KEY",
applicationUsername: applicationUsername
)
} else {
InAppPurchase.initialize(
iapProducts: iapProductsArray,
validatorUrlString: "https://validator.iaptic.com/v3/validate?appName=YOUR_IAPTIC_APP_NAME&apiKey=YOUR_IAPTIC_PUBLIC_KEY"
)
}
return true
}
}
Option 4: App Store Direct (Beta)
**Step 1: Apple App Store Notification Setup**
Visit [our docs](https://docs.insertaffiliate.com/direct-store-purchase-integration#1-apple-app-store-server-notifications) and complete the required App Store Server to Server Notifications setup.
**Step 2: Implementing Purchases**
// Within the function where you are making the purchase...
func purchase(productIdentifier: String) async {
do {
// Replace your product.purchase() with the lines below
let token = await InsertAffiliateSwift.returnUserAccountTokenAndStoreExpectedTransaction()
// Optional override: Use your own UUID for the purchase token
// let token = await InsertAffiliateSwift.returnUserAccountTokenAndStoreExpectedTransaction(
// overrideUUIDString: "YOUR_OWN_UUID"
// )
let result = try await product.purchase(options: token.map { [.appAccountToken($0)] } ?? [])
}
}
Option 5: Apphud
**Step 1: Code Setup**
Complete the [Apphud Quickstart and Setup](https://docs.apphud.com/docs/quickstart). Then modify your `AppDelegate.swift`:
import SwiftUI
import ApphudSDK
import InsertAffiliateSwift
final class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
Apphud.start(apiKey: "YOUR_APPHUD_KEY")
if let applicationUsername = InsertAffiliateSwift.returnInsertAffiliateIdentifier() {
Apphud.setUserProperty(key: .init("insert_affiliate"), value: applicationUsername, setOnce: false)
}
return true
}
}
3. Set Up Deep Linking¶
Deep linking lets affiliates share unique links that track users to your app. Choose ONE deep linking provider:
| Provider | Best For | Complexity | Setup Guide |
|---|---|---|---|
| Insert Links | Simple setup, no 3rd party | ⭐ Simple | View |
| Branch.io | Robust attribution, deferred deep linking | ⭐⭐ Medium | View |
| AppsFlyer | Enterprise analytics, comprehensive attribution | ⭐⭐ Medium | View |
Option 1: Insert Links (Simplest)
Insert Links is Insert Affiliate's built-in deep linking solution—no third-party SDK required.
**Prerequisites:**
- Complete the [Insert Links setup](https://docs.insertaffiliate.com/insert-links) in the Insert Affiliate dashboard
**Code Implementation:**
import UIKit
import InsertAffiliateSwift
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
// Initialize SDK with Insert Links enabled
InsertAffiliateSwift.initialize(
companyCode: "YOUR_COMPANY_CODE",
verboseLogging: true, // Enable for debugging
insertLinksEnabled: true, // Enable Insert Links
insertLinksClipboardEnabled: false // Set to true if attribution accuracy is most important (triggers clipboard permission prompt)
)
// Set up callback for affiliate identifier changes (receives identifier and optional offer code)
InsertAffiliateSwift.setInsertAffiliateIdentifierChangeCallback { identifier, offerCode in
if let identifier = identifier {
print("Affiliate identifier: \(identifier)")
if let offerCode = offerCode {
print("Offer code: \(offerCode)")
}
// If using RevenueCat, update attributes here
// Purchases.shared.attribution.setAttributes(["insert_affiliate": identifier])
// Purchases.shared.syncAttributesAndOfferingsIfNeeded { offerings, error in }
// If using Adapty, update attributes here
// Task {
// var builder = AdaptyProfileParameters.Builder()
// builder = try builder.with(customAttribute: identifier, forKey: "insert_affiliate")
// try await Adapty.updateProfile(params: builder.build())
// }
// If using Apphud, update property here
// Apphud.setUserProperty(key: .init("insert_affiliate"), value: identifier, setOnce: false)
}
}
// Handle deep link from app launch
if let url = launchOptions?[.url] as? URL {
InsertAffiliateSwift.handleInsertLinks(url)
}
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
InsertAffiliateSwift.handleInsertLinks(url)
return true
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let url = userActivity.webpageURL {
InsertAffiliateSwift.handleInsertLinks(url)
}
return true
}
}
import InsertAffiliateSwift
import SwiftUI
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL(perform: { url in
// Handle InsertAffiliate deep links
if InsertAffiliateSwift.handleInsertLinks(url) {
if let affiliateIdentifier = InsertAffiliateSwift.returnInsertAffiliateIdentifier() {
// If using RevenueCat:
// Purchases.shared.attribution.setAttributes(["insert_affiliate": affiliateIdentifier])
// Purchases.shared.syncAttributesAndOfferingsIfNeeded { offerings, error in }
// If using Adapty:
// Task {
// var builder = AdaptyProfileParameters.Builder()
// builder = try builder.with(customAttribute: affiliateIdentifier, forKey: "insert_affiliate")
// try await Adapty.updateProfile(params: builder.build())
// }
// If using Apphud:
// Apphud.setUserProperty(key: .init("insert_affiliate"), value: affiliateIdentifier, setOnce: false)
}
}
})
}
}
}
# Test with your iOS URL scheme from Insert Affiliate dashboard
xcrun simctl openurl booted "YOUR_IOS_URL_SCHEME://TEST_SHORT_CODE"
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let url = userActivity.webpageURL {
InsertAffiliateSwift.handleInsertLinks(url)
}
return true
}
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
// Handles custom URL scheme (ia-companycode://)
InsertAffiliateSwift.handleInsertLinks(url)
}
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
// Handles Universal Links (https://insertaffiliate.link/...)
if let url = userActivity.webpageURL {
InsertAffiliateSwift.handleInsertLinks(url)
}
}
}
}
}
Option 2: Branch.io
Branch.io provides robust attribution and deferred deep linking capabilities.
**Key Integration Steps:**
1. Install and configure [Branch SDK for iOS](https://help.branch.io/developers-hub/docs/ios-basic-integration)
2. Extract `~referring_link` from Branch callback
3. Pass to Insert Affiliate SDK using `setInsertAffiliateIdentifier()`
📖 **[View complete Branch.io integration guide →](docs/deep-linking-branch.md)**
Includes full examples for:
- RevenueCat integration
- Adapty integration
- Apphud integration
- Iaptic integration
- App Store Direct integration
✅ **After completing Branch setup**, skip to [Verify Your Integration](#-verify-your-integration)
Option 3: AppsFlyer
AppsFlyer provides enterprise-grade analytics and comprehensive attribution.
**Key Integration Steps:**
1. Install and configure [AppsFlyer SDK for iOS](https://dev.appsflyer.com/hc/docs/ios-sdk-reference-getting-started)
2. Create AppsFlyer OneLink in dashboard
3. Extract deep link from `onAppOpenAttribution()` callback
4. Pass to Insert Affiliate SDK using `setInsertAffiliateIdentifier()`
📖 **[View complete AppsFlyer integration guide →](docs/deep-linking-appsflyer.md)**
Includes full examples for:
- RevenueCat integration
- Adapty integration
- Iaptic integration
- App Store Direct integration
- Deferred deep linking setup
✅ **After completing AppsFlyer setup**, proceed to [Verify Your Integration](#-verify-your-integration)
✅ Verify Your Integration¶
Before going live, verify everything works correctly:
Integration Checklist¶
- [ ] SDK Initializes: Check console for
SDK initialized with company codelog - [ ] Affiliate Identifier Stored: Click a test affiliate link and verify identifier is stored
- [ ] Purchase Tracked: Make a test purchase and verify transaction is sent to Insert Affiliate
Testing Commands¶
Test Deep Link (via Simulator):
# Replace with your actual deep link URL
xcrun simctl openurl booted "https://your-app.onelink.me/abc123"
Check Stored Affiliate Identifier:
if let affiliateId = InsertAffiliateSwift.returnInsertAffiliateIdentifier() {
print("Current affiliate ID: \(affiliateId)")
}
Expected Output: Current affiliate ID: AFFILIATE1-a1b2c3
Common Setup Issues¶
| Issue | Solution |
|---|---|
| "Company code is not set" | Ensure initialize() is called in AppDelegate before any other SDK methods |
| "No affiliate identifier found" | User must click an affiliate link before making a purchase |
| Deep link opens browser instead of app | Verify associated domains in Xcode project and deep linking provider dashboard |
| Purchase not tracked | Check webhook configuration in IAP verification platform |
🔧 Advanced Features¶
Event Tracking (Beta)
Track custom events beyond purchases (e.g., signups, referrals) to incentivize affiliates for specific actions.
**Use Cases:**
- Pay affiliates for signups instead of purchases
- Track trial starts, content unlocks, or other conversions
Short Codes
Short codes are unique, 3-25 character alphanumeric identifiers that affiliates can share (e.g., "SAVE20" in a TikTok video description).
**Validate and Store Short Code:**
**Get Affiliate Details Without Setting:**
Learn more: [Short Codes Documentation](https://docs.insertaffiliate.com/short-codes)
Dynamic Offer Codes / Discounts
Automatically apply discounts or trials when users come from specific affiliates.
**How It Works:**
1. Configure an offer code modifier in your [Insert Affiliate dashboard](https://app.insertaffiliate.com/affiliates) (e.g., `_oneWeekFree`)
2. SDK automatically fetches and stores the modifier when affiliate identifier is set
3. Use the modifier to construct dynamic product IDs
**Quick Example:**
📖 **[View complete Dynamic Offer Codes guide →](docs/dynamic-offer-codes.md)**
Includes full examples for:
- App Store Connect setup
- RevenueCat integration with dynamic product selection
- Native StoreKit 2 integration
- Testing and troubleshooting
Attribution Timeout Control
Control how long affiliate attribution remains active after a user clicks a link (e.g., 7-day attribution window).
**Set Timeout During Initialization:**
// 7-day attribution window (604800 seconds)
InsertAffiliateSwift.initialize(
companyCode: "YOUR_COMPANY_CODE",
affiliateAttributionActiveTime: 604800
)
let isValid = await InsertAffiliateSwift.isAffiliateAttributionValid()
if isValid {
// Attribution is still active
} else {
// Attribution expired
}
Prevent Affiliate Transfer¶
Protect the original affiliate's attribution from being overwritten when users click different affiliate links.
Enable During Initialization:
How It Works:
1. User clicks Affiliate A's link → Attribution stored
2. preventAffiliateTransfer: true is set
3. User clicks Affiliate B's link → SDK detects existing attribution
4. Transfer blocked → Affiliate B's link is silently ignored
5. User purchases → Affiliate A receives commission
Use Cases: - Prevent "affiliate stealing" scenarios - Ensure the first affiliate to acquire a user always receives credit - Protect long-term affiliate relationships
Learn more: Prevent Affiliate Transfer Documentation
🔍 Troubleshooting¶
Initialization Issues¶
Error: "Company code is not set"
- Cause: SDK not initialized or initialize() called after other SDK methods
- Solution: Call InsertAffiliateSwift.initialize() in AppDelegate.application(_:didFinishLaunchingWithOptions:) before any other SDK methods
Deep Linking Issues¶
Problem: Deep link opens browser instead of app - Cause: Missing or incorrect associated domains, or URL scheme not configured - Solution: - Verify associated domains in Xcode project match your deep linking provider's domain - Add URL scheme to Info.plist - For universal links, ensure apple-app-site-association file is properly configured
Problem: "No affiliate identifier found" - Cause: User hasn't clicked an affiliate link yet - Solution: Ensure users come from affiliate links before purchases. Test with simulator:
Purchase Tracking Issues¶
Problem: Purchases not appearing in Insert Affiliate dashboard
- Cause: Webhook not configured or affiliate identifier not passed to IAP platform
- Solution:
- Verify webhook URL and authorization headers are correct
- For RevenueCat: Confirm insert_affiliate attribute is set before purchase
- For Iaptic/App Store Direct: Check that affiliate identifier exists when purchase is made
- Enable verbose logging and check console for errors
Verbose Logging¶
Enable detailed logs during development to diagnose issues:
Important: Disable verbose logging in production builds.
Getting Help¶
📚 Support¶
- Documentation: docs.insertaffiliate.com
- Dashboard Support: app.insertaffiliate.com/help
- Issues: GitHub Issues
- Company Code: Get yours from Settings
Need help getting started? Check out our quickstart guide or contact support.