> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pushctl.com/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS quickstart

> Install and initialize the Pushctl iOS SDK and register with APNs.

The iOS SDK supports iOS 15+ and Swift 6.

## Prerequisites

* An iOS platform with matching APNs credentials and environment in Pushctl
* A **Client** application token
* The Push Notifications capability on the app target

<Warning>
  Select **Sandbox** for a development-signed build installed from Xcode. Select **Production** for TestFlight and App Store builds. A mismatch commonly causes `400 BadDeviceToken`. See the [iOS FAQ](/sdks/ios/faq).
</Warning>

<Tabs>
  <Tab title="Swift Package Manager">
    Add `https://github.com/Pushctl/Pushctl-iOS-SDK.git`, choose a version from `0.3.0`, and add the `Pushctl` product to the app target.
  </Tab>

  <Tab title="CocoaPods">
    ```ruby theme={null}
    pod 'Pushctl', '~> 0.3.0'
    ```

    ```bash theme={null}
    pod install
    ```
  </Tab>
</Tabs>

<Steps>
  <Step title="Initialize once">
    ```swift theme={null}
    import Pushctl

    @main
    struct ExampleApp: App {
        init() {
            Pushctl.initialize(applicationKey: "push_live_your_client_token")
        }
    }
    ```
  </Step>

  <Step title="Request permission">
    ```swift theme={null}
    let granted = try await Pushctl.shared.requestPermission()
    ```

    Ask from a user-initiated point where the value of notifications is clear.
  </Step>

  <Step title="Forward the APNs token">
    ```swift theme={null}
    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Pushctl.shared.setDeviceToken(deviceToken)
    }

    func application(
        _ application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: Error
    ) {
        Pushctl.shared.reportRemoteNotificationRegistrationFailure(error)
    }
    ```
  </Step>

  <Step title="Wait for confirmed registration">
    ```swift theme={null}
    try await Pushctl.shared.waitForRegistration()
    ```

    This returns only after the Pushctl API accepts the APNs token. It throws on APNs or API failure, or when no token arrives before the default 15-second timeout.
  </Step>
</Steps>

<Warning>Do not disable another notification provider based only on permission or receipt of an APNs token. Wait for confirmed Pushctl registration first.</Warning>
