> ## 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 identity and delivery events

> Identify iOS users, handle notification callbacks, and add confirmed background delivery.

## User identity and callbacks

```swift theme={null}
try await Pushctl.shared.waitForRegistration()
try await Pushctl.shared.login(user.id)

Pushctl.shared.notificationOpened = { notification in
    notification.actionURL.map(router.open)
}

Pushctl.shared.notificationWillDisplay = { notification in
    analytics.track("push_foreground", notification.notificationId)
}
```

Call `try await Pushctl.shared.logout()` during sign-out. The installation remains anonymously subscribed. Login and logout throw when the installation is not registered or the API update fails.

## Confirm background receipt and display

Without a Notification Service Extension, iOS limits what the main app can observe while it is not running. Add an extension for confirmed background `received` and `displayed` events.

<Steps>
  <Step title="Add a Notification Service Extension target">
    ```swift theme={null}
    import Pushctl

    final class NotificationService: PushctlNotificationServiceExtension {}
    ```
  </Step>

  <Step title="Create an App Group">Enable the same App Group capability for the main app and extension.</Step>

  <Step title="Initialize with the group">
    ```swift theme={null}
    Pushctl.initialize(
        applicationKey: "push_live_your_client_token",
        appGroupIdentifier: "group.com.example.app.pushctl"
    )
    ```
  </Step>

  <Step title="Configure the extension">Add `PushctlAppGroupIdentifier` with the same value to the extension's `Info.plist`.</Step>
</Steps>

<Note>Events are deterministic for installation, delivery, and type. If the extension and app see the same transition, the API treats both reports as one event.</Note>
