# Initialize the SDK

> Start the SDK when the app launches, pass Apple's token through, and forward notification taps.

URL: https://docs.xulo.io/ios/initialize
iOS SDK version: 0.1.4

## Start

Call `Xulo.start` once, when the app launches, with the App ID from **Settings → Keys & IDs**.

**SwiftUI**

```swift
import SwiftUI
import UserNotifications
import Xulo

final class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        Xulo.start(appId: "YOUR_APP_ID")
        return true
    }

    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Xulo.setDeviceToken(deviceToken)
    }

    func application(
        _ application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: Error
    ) {
        Xulo.didFailToRegister()
    }

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse
    ) async {
        Xulo.didReceive(userInfo: response.notification.request.content.userInfo)
    }
}

@main
struct ExampleApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```
**UIKit**

```swift
import UIKit
import UserNotifications
import Xulo

@main
final class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        Xulo.start(appId: "YOUR_APP_ID")
        return true
    }

    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Xulo.setDeviceToken(deviceToken)
    }

    func application(
        _ application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: Error
    ) {
        Xulo.didFailToRegister()
    }

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse
    ) async {
        Xulo.didReceive(userInfo: response.notification.request.content.userInfo)
    }
}
```

## What start does

- `appId` is the App ID. It is not a secret and it cannot send.
- `start` reads the app's bundle id. Pass `bundleId:` only when the bundle id registered in the dashboard is not the app's own.
- If the App ID is empty, `start` does not register and logs an error.
- If notification permission is already allowed, or the app holds provisional permission, `start` registers for a token and does not ask again.
- `start` calls `https://api.xulo.io`. You do not pass a server address.

```swift
Xulo.start(appId: "YOUR_APP_ID", bundleId: "app.example.ios")
```

## Token and taps

- `Xulo.setDeviceToken` passes Apple's token to Xulo.
- `Xulo.didFailToRegister` records that Apple refused to register the device.
- `Xulo.didReceive(userInfo:)` records the click and hands the link and data to [Xulo.onOpen](https://docs.xulo.io/ios/deep-links).

If your app does not set a notification center delegate, the SDK handles taps itself. If it does, and the delegate handles taps, call `Xulo.didReceive(userInfo:)` from it as above.

While the app is in the foreground, a push shows as a system banner. If your delegate implements `willPresent`, its choice is used instead.

## Logging

```swift
Xulo.logLevel = .verbose
```

| Level | Prints |
| --- | --- |
| `.off` | Nothing. This is the default. |
| `.error` | Failures only. |
| `.verbose` | The full trace, in the Xcode console. |

Leave logging off in a live build. The log never includes the device token. The extensions read the same level from the App Group after `start`.

Next: [Permission prompt](https://docs.xulo.io/ios/permission-prompt).
