# APNS Vapor's Apple Push Notification Service (APNS) API makes it easy to authenticate and send push notifications to Apple devices. It's built on top of [APNSwift](https://github.com/swift-server-community/APNSwift). ## Getting Started Let's take a look at how you can get started using APNS. ### Package The first step to using APNS is adding the package to your dependencies. ```swift // swift-tools-version:5.8 import PackageDescription let package = Package( name: "my-app", dependencies: [ // Other dependencies... .package(url: "https://github.com/vapor/apns.git", from: "4.0.0"), ], targets: [ .target(name: "App", dependencies: [ // Other dependencies... .product(name: "VaporAPNS", package: "apns") ]), // Other targets... ] ) ``` If you edit the manifest directly inside Xcode, it will automatically pick up the changes and fetch the new dependency when the file is saved. Otherwise, from Terminal, run `swift package resolve` to fetch the new dependency. ### Configuration The APNS module adds a new property `apns` to `Application`. To send push notifications, you will need to set the `configuration` property with your credentials. ```swift import APNS import VaporAPNS import APNSCore // Configure APNS using JWT authentication. let apnsConfig = APNSClientConfiguration( authenticationMethod: .jwt( privateKey: try .loadFrom(string: "<#key.p8 content#>"), keyIdentifier: "<#key identifier#>", teamIdentifier: "<#team identifier#>" ), environment: .development ) app.apns.containers.use( apnsConfig, eventLoopGroupProvider: .shared(app.eventLoopGroup), responseDecoder: JSONDecoder(), requestEncoder: JSONEncoder(), as: .default ) ``` Fill in the placeholders with your credentials. The above example shows [JWT-based auth](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns) using the `.p8` key you get from Apple's developer portal. For [TLS-based auth](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns) with a certificate, use the `.tls` authentication method: ```swift authenticationMethod: .tls( privateKeyPath: <#path to private key#>, pemPath: <#path to pem file#>, pemPassword: <#optional pem password#> ) ``` ### Send Once APNS is configured, you can send push notifications using `apns.send` method on `Application` or `Request`. ```swift // Custom Codable Payload struct Payload: Codable { let acme1: String let acme2: Int } // Create push notification Alert let dt = "70075697aa918ebddd64efb165f5b9cb92ce095f1c4c76d995b384c623a258bb" let payload = Payload(acme1: "hey", acme2: 2) let alert = APNSAlertNotification( alert: .init( title: .raw("Hello"), subtitle: .raw("This is a test from vapor/apns") ), expiration: .immediately, priority: .immediately, topic: "<#my topic#>", payload: payload ) // Send the notification try! await req.apns.client.sendAlertNotification( alert, deviceToken: dt, deadline: .distantFuture ) ``` Use `req.apns` whenever you are inside of a route handler. ```swift // Sends a push notification. app.get("test-push") { req async throws -> HTTPStatus in try await req.apns.client.send(...) return .ok } ``` The first parameter accepts the push notification alert and the second parameter is the target device token. ## Alert `APNSAlertNotification` is the actual metadata of the push notification alert to send. More details on the specifics of each property are provided [here](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html). They follow a one-to-one naming scheme listed in Apple's documentation. ```swift let alert = APNSAlertNotification( alert: .init( title: .raw("Hello"), subtitle: .raw("This is a test from vapor/apns") ), expiration: .immediately, priority: .immediately, topic: "<#my topic#>", payload: payload ) ``` This type can be passed directly to the `send` method. ### Custom Notification Data Apple provides engineers with the ability to add custom payload data to each notification. In order to facilitate this we accept `Codable` conformance to the payload parameter on all `send` apis. ```swift // Custom Codable Payload struct Payload: Codable { let acme1: String let acme2: Int } ``` ## More Information For more information on available methods, see [APNSwift's README](https://github.com/swift-server-community/APNSwift).