Skip to main content
Use the Swift SDK for native iOS apps.

Requirements

  • iOS 13.0+
  • Swift 5.7+
  • Swift Package Manager

Install with Swift Package Manager

Package repository: pnlight-dev/sdk-swift. Swift SDK version Add it in Xcode:
1

Open package settings

In Xcode, click File and then Add Packages….
2

Enter the repository URL

Enter https://github.com/pnlight-dev/sdk-swift.git.
3

Add the package

Add the package to your app target.

Initialize the SDK

Call initialization during app startup.
import PNLightSDK

await PNLightSDK.shared.initialize(apiKey: "pnlight_sdk_token")

Common calls

let userId = PNLightSDK.shared.getUserId()

await PNLightSDK.shared.addAttribution(
    provider: .appsFlyer,
    data: ["af_status": "Non-organic"],
    identifier: "appsFlyerCustomerId"
)

await PNLightSDK.shared.logEvent("paywall_viewed", eventArgs: [
    "placement": "paywall"
])
logEvent sends optional in-app events to PNLight. You can review them in Analytics → App Events, on the Events page, and in customer timelines.

IDFA after ATT

If PNLight initializes before the App Tracking Transparency prompt completes, call updateIdfa() after authorization so PNLight receives the granted IDFA.
import AppTrackingTransparency
import PNLightSDK

await ATTrackingManager.requestTrackingAuthorization()
await PNLightSDK.shared.updateIdfa()

Remote UI

Use RemoteUiView in SwiftUI when you want PNLight to render a configured placement.
import PNLightSDK
import SwiftUI

struct PaywallScreen: View {
    var body: some View {
        RemoteUiView(placement: "paywall", cardId: "paywall_card") { action in
            if action.logId == "purchase_button" {
                let productId = action.params["id"] ?? ""
                Task {
                    let success = await purchase(productId)
                    if success {
                        showMainScreen()
                    }
                }
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}
If you need to fetch the placement config yourself, use getUIConfig. On the first app launch, wait 4-5 seconds after AppsFlyer initialization when attribution is required. The SDK also waits for attribution internally when attributionRequired is true.
try? await Task.sleep(nanoseconds: 5_000_000_000)

let config = await PNLightSDK.shared.getUIConfig(placement: "paywall")
Use getUIConfigResult when your app needs to tell the difference between no UI for a placement and a loading error.
let result = await PNLightSDK.shared.getUIConfigResult(
    placement: "paywall",
    ignoreCache: true
)
See Remote UI for placement and action guidance.