APNSwift Documentation

repository·main·Indexed 21 days ago

https://github.com/kylebrowning/apnswift

A non-blocking Swift module built on AsyncHttpClient for sending remote Apple Push Notification (APNs) requests. It provides structures for standard alerts and Live Activities, supporting JWT authentication and customizable logging for background operations and notification requests.

Tokens
1.8K
Snippets
5
Records
7
Agent score
24%

What's inside APNSwift

  1. Configure Logging in APNSwift

    main

    By default, APNSwift uses a no-op logger. To enable logging, pass a logger instance to the appropriate location:

    1. Background Activity Logger: Pass this into the APNSClient to log background operations like connection pooling and auth token refreshes.
    2. Notification Send Logger: Pass this into any of the send: methods to log details related to a specific single send request.
  2. Install APNSwift via Swift Package Manager

    main

    Add APNSwift as a dependency in your Package.swift file. Use the following dependency declaration to include the package:

    dependencies: [
        .package(url: "https://github.com/swift-server-community/APNSwift.git", from: "6.0.0"),
    ]
  3. Configure JWT Authentication

    main

    Apple recommends using jwt authentication. This requires an encrypted version of your .p8 file in pem format. If you have a standard .p8 file, you can convert it using OpenSSL:

    openssl pkcs8 -nocrypt -in /path/to/my/key.p8 -out ~/Downloads/key.pem

    Pass the resulting PEM representation, your keyIdentifier, and teamIdentifier to the APNSClientConfiguration.

  4. Initialize an APNSClient

    main

    To send notifications, you must first set up an APNSClient. This requires an APNSClientConfiguration specifying your authentication method (e.g., .jwt) and the environment (e.g., .development). You also need to provide an eventLoopGroupProvider, a responseDecoder, and a requestEncoder. Remember to call try await client.shutdown() when the client is no longer needed to clean up resources.

    let client = APNSClient(
        configuration: .init(
            authenticationMethod: .jwt(
                privateKey: try .init(pemRepresentation: privateKey),
                keyIdentifier: keyIdentifier,
                teamIdentifier: teamIdentifier
            ),
            environment: .development
        ),
        eventLoopGroupProvider: .createNew,
        responseDecoder: JSONDecoder(),
        requestEncoder: JSONEncoder()
    )
    
    // Shutdown the client when done
    try await client.shutdown()
  5. Send a simple alert notification

    main

    You can send notifications by calling sendAlertNotification. This method requires a deviceToken and a notification object. The notification object includes an alert (containing title, subtitle, and body), expiration, priority, topic (your app's bundle ID), and a payload. The payload can be any type that conforms to Encodable.

    struct Payload: Codable {}
    
    try await client.sendAlertNotification(
        .init(
            alert: .init(
                title: .raw("Simple Alert"),
                subtitle: .raw("Subtitle"),
                body: .raw("Body"),
                launchImage: nil
            ),
            expiration: .immediately,
            priority: .immediately,
            topic: "com.app.bundle",
            payload: Payload()
        ),
        deviceToken: "device-token"
    )
  6. Send a Live Activity Start notification

    main

    To start a Live Activity, use sendStartLiveActivityNotification.

    Requirements:

    • attributes and contentState must match the live activity attributes provided in attributesType.
    • The alert must contain a title, body, and sound. The title and body are visible to the device's paired Apple Watch when starting the activity.
    • Provide the pushToStartToken.
    let response = try await client.sendStartLiveActivityNotification(
        .init (
            expiration: .immediately,
            priority: .immediately,
            appID: "com.app.bundle",
            contentState: contentState,
            timestamp: Int(Date().timeIntervalSince1970),
            attributes: attributes,
            attributesType: "YourActivityAttributes",
            alert: .init(
                title: .raw("Your title"),
                body: .raw("Your body"),
                sound: .fileName("default.aiff")
            )
        ),
        pushToStartToken: pushToStartToken
    )
  7. Send Live Activity Update or End notifications

    main

    Use sendLiveActivityNotification to manage the lifecycle of an existing Live Activity. The contentState must conform to Encodable and Sendable and match the activity's configuration.

    To Update: Set the event to .update.

    To End: Set the event to .end. You can optionally provide a dismissalDate to alter default behavior.

    // Update
    try await client.sendLiveActivityNotification(
        .init(
              expiration: .immediately,
              priority: .immediately,
              appID: "com.app.bundle",
              contentState: ContentState,
              event: .update,
              timestamp: Int(Date().timeIntervalSince1970)
        ),
        deviceToken: activityPushToken
    )
    
    // End
    try await client.sendLiveActivityNotification(
        .init(
              expiration: .immediately,
              priority: .immediately,
              appID: "com.app.bundle",
              contentState: ContentState,
              event: .end,
              timestamp: Int(Date().timeIntervalSince1970),
              dismissalDate: .immediately // Optional to alter default behaviour
        ),
        deviceToken: activityPushToken
    )