Developer Guide

iOS SDK Reference

CohortSDK is a Swift Package Manager (SPM) library designed to easily integrate your iOS applications with the Cohort.ai backend. It provides a native, type-safe interface to fetch dynamically generated, AI-targeted paywall campaigns and track user sessions for cohort routing.

Requirements

  • iOS 15.0+
  • macOS 12.0+
  • tvOS 15.0+
  • watchOS 8.0+
  • Swift 5.9+

Installation

1. Install as a Local Package (Monorepo)

If you are working directly within this repository, you can add it as a local package:

  1. Open your Xcode Project: Open your main iOS app in Xcode.
  2. Drag and Drop: In Finder, locate the CohortSDK folder inside this repository. Drag it into your Xcode project navigator.
  3. Link the Framework: Add CohortSDK under your target's General > Frameworks, Libraries, and Embedded Content.

2. Install from GitHub (Coming Soon)

For public or cross-repo distribution, use the Swift Package Manager URL.

Initialize the SDK

Before making any requests, you must initialize the SDK. The easiest way is to download the cohort-config.json file from your Cohort Dashboard and drag it into your Xcode project (ensure "Copy items if needed" is checked).

Then, initialize the SDK once, typically in your AppDelegate or at the very beginning of your app's lifecycle:

import CohortSDK

// E.g., inside application(_:didFinishLaunchingWithOptions:)
CohortSDK.shared.initialize(
    userId: "user_12345" // Optional: Identify the user immediately
)

Track User Activity

To ensure users are placed in the correct cohort (e.g., new_user, high_intent), you should track user sessions and paywall views.

// Track a general session start
Task {
    try await CohortSDK.shared.trackActivity(
        eventType: "session_start"
    )
}

// Track when a user views a paywall
Task {
    try await CohortSDK.shared.trackActivity(
        eventType: "paywall_view"
    )
}

Track your "North Star" Metric (Success Goal)

Cohort.ai optimizes your marketing copy based on a Success Goal. By default, this is purchase_success, but you can customize this in the Dashboard Settings (e.g., to _core_event, lesson_completed, etc.).

To drive AI optimization, track your custom success event whenever the user achieves it:

Task {
    try await CohortSDK.shared.trackActivity(
        eventType: "_core_event" // Matches the Success Event ID in your Dashboard
    )
}

Advanced Tracking (FCM & Receipts)

To link app purchases and subscriptions with backend webhooks, you must track the successful purchase. You can do this easily by passing the StoreKit 2 Transaction object directly to trackPurchase:

// Example: Tracking a StoreKit 2 purchase success using the native helper wrapper
Task {
    try await CohortSDK.shared.trackPurchase(
        transaction: transaction,            // Passes the StoreKit 2 Transaction directly
        fcmToken: "e123abc-xyz-token"         // Store their push token (optional)
    )
}

Behind the scenes, this automatically extracts String(transaction.originalID) and forwards it as the originalTransactionId to map backend webhooks to the correct client user.

Fetch a Campaign

Call the getCampaignConfig method using Swift Concurrency (async/await) to retrieve the localized marketing copy and discount eligibility for a user.

import CohortSDK
import SwiftUI

struct PaywallView: View {
    // ... use CohortSDK.shared.getCampaignConfig()
}

SDK Debugger (Production Safe)

CohortSDK includes a built-in debug menu to inspect the current SDK state on real devices.

Usage

In your View or ViewController (Debug builds only):

CohortSDK.shared.showDebugUI()

Production Safety

This method is wrapped in #if DEBUG macros. The entire function and its UI logic are physically stripped from your app during the release build process, ensuring zero overhead and no accidental internal data leaks in production.

Handling Paywall Push Notifications

Cohort.ai can trigger automated push notifications targeting specific user cohorts. When users tap these notifications, you should route them directly to your app's paywall.

1. Payload Structure

Cohort push notifications include a custom payload with the following key-value pair in the data dictionary:

  • Key: "action"
  • Value: "open_paywall"

2. Implementation & Integration Checklist

To route users correctly when they tap a notification, update your application's notification handler methods:

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    let userInfo = response.notification.request.content.userInfo

    // Intercept paywall actions
    if let action = userInfo["action"] as? String, action == "open_paywall" {
        // Navigate or post a local notification to open the paywall
        NotificationCenter.default.post(name: NSNotification.Name("OpenPaywallScreen"), object: nil)
    }

    completionHandler()
}

3. Key Considerations & Things to Watch Out For

Important

Handle Cold Starts vs Warm Starts: If a user taps the notification while the app is fully terminated (cold start), the notification payload is delivered inside the launchOptions?[.remoteNotification] key of application(_:didFinishLaunchingWithOptions:). Ensure your router can navigate to the paywall once your main UI setup completes.

Warning

Check SDK Initialization Timing: Do not attempt to query CohortSDK.shared.getCampaignConfig() until CohortSDK.shared.initialize() has run. Attempting to fetch campaigns before initialization will result in a runtime error.

Note

Dismiss Overlaid Screens: Before presenting the paywall, dismiss any alert dialogs or modal controllers to prevent view hierarchy presentation conflicts.

Architecture Notes

  • The SDK utilizes standard URLSession concurrency APIs (try await session.data(for: request)).
  • All requests are sent to /v1/campaigns and /v1/activities.
  • Automatically includes the x-sdk-version header in all requests to match the SDK's current version.
  • Exposes the SDK version string via the CohortSDK.version static property.
  • Response models automatically map JSON snake_case keys (like cohort_id and variant_id) to Swift's standard camelCase (like cohortId and variantId).
  • CampaignResponse contains the dynamic properties cohortId, variantId, discountEligible, bannerHeader, bannerBody, marketingHeader, marketingBody, pushTitle, and pushBody.