Skip to content

Commit

Permalink
Fix README and DocC
Browse files Browse the repository at this point in the history
  • Loading branch information
fpseverino committed Sep 21, 2024
1 parent 091fb9a commit ab54efb
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 104 deletions.
74 changes: 33 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![sswg:graduated|94x20](https://img.shields.io/badge/sswg-graduated-green.svg)]([https://github.com/swift-server/sswg/blob/master/process/incubation.md#sandbox-level](https://www.swift.org/sswg/incubation-process.html#graduation-requirements))
[![Build](https://github.com/kylebrowning/APNSwift/workflows/test/badge.svg)](https://github.com/kylebrowning/APNSwift/actions)
[![Documentation](https://img.shields.io/badge/documentation-blueviolet.svg)](https://swiftpackageindex.com/swift-server-community/APNSwift/main/documentation/apnswift)
[![Documentation](https://img.shields.io/badge/documentation-blueviolet.svg)](https://swiftpackageindex.com/swift-server-community/APNSwift/documentation)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fswift-server-community%2FAPNSwift%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/swift-server-community/APNSwift)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fswift-server-community%2FAPNSwift%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/swift-server-community/APNSwift)
<h1> APNSwift</h1>
Expand All @@ -25,7 +25,7 @@ To install `APNSwift`, just add the package as a dependency in your [**Package.s

```swift
dependencies: [
.package(url: "https://github.com/swift-server-community/APNSwift.git", from: "5.0.0"),
.package(url: "https://github.com/swift-server-community/APNSwift.git", from: "6.0.0"),
]
```

Expand All @@ -44,15 +44,11 @@ let client = APNSClient(
),
eventLoopGroupProvider: .createNew,
responseDecoder: JSONDecoder(),
requestEncoder: JSONEncoder(),
byteBufferAllocator: .init(),
backgroundActivityLogger: logger
requestEncoder: JSONEncoder()
)
defer {
client.shutdown { _ in
logger.error("Failed to shutdown APNSClient")
}
}

// Shutdown the client when done
try await client.shutdown()
```

## Sending a simple notification
Expand All @@ -74,44 +70,40 @@ try await client.sendAlertNotification(
topic: "com.app.bundle",
payload: Payload()
),
deviceToken: "device-token",
deadline: .nanoseconds(Int64.max),
logger: myLogger
deviceToken: "device-token"
)
```

## Sending Live Activity Update / End
It requires sending `ContentState` matching with the live activity configuration to successfully update activity state. `ContentState` needs to conform to `Encodable`
It requires sending `ContentState` matching with the live activity configuration to successfully update activity state. `ContentState` needs to conform to `Encodable` and `Sendable`.

```swift
try await client.sendLiveActivityNotification(
.init(
expiration: .immediately,
priority: .immediately,
appID: "com.app.bundle",
contentState: ContentState,
event: .update,
timestamp: Int(Date().timeIntervalSince1970)
),
activityPushToken: activityPushToken,
deadline: .distantFuture
)
try await client.sendLiveActivityNotification(
.init(
expiration: .immediately,
priority: .immediately,
appID: "com.app.bundle",
contentState: ContentState,
event: .update,
timestamp: Int(Date().timeIntervalSince1970)
),
deviceToken: activityPushToken
)
```

```swift
try await client.sendLiveActivityNotification(
.init(
expiration: .immediately,
priority: .immediately,
appID: "com.app.bundle",
contentState: ContentState,
event: .end,
timestamp: Int(Date().timeIntervalSince1970),
dismissalDate: .dismissImmediately // Optional to alter default behaviour
),
activityPushToken: activityPushToken,
deadline: .distantFuture
)
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
)
```
## Authentication
`APNSwift` provides two authentication methods. `jwt`, and `TLS`.
Expand All @@ -121,8 +113,8 @@ These can be configured when created your `APNSClientConfiguration`

*Notes: `jwt` requires an encrypted version of your .p8 file from Apple which comes in a `pem` format. If you're having trouble with your key being invalid please confirm it is a PEM file*
```
openssl pkcs8 -nocrypt -in /path/to/my/key.p8 -out ~/Downloads/key.pem
```
openssl pkcs8 -nocrypt -in /path/to/my/key.p8 -out ~/Downloads/key.pem
```

## Logging
By default APNSwift has a no-op logger which will not log anything. However if you pass a logger in, you will see logs.
Expand Down
70 changes: 13 additions & 57 deletions Sources/APNS/APNS.docc/APNSwift.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
# ``APNSwift``
A non-blocking Swift package for sending remote Apple Push Notification requests to Apple's APNS.
# ``APNS``

A non-blocking Swift module for sending remote Apple Push Notification requests to APNS built on AsyncHttpClient.

## Installation

To install `APNSwift`, just add the package as a dependency in your [**Package.swift**](https://github.com/apple/swift-package-manager/blob/master/Documentation/PackageDescriptionV4.md#dependencies).

```swift
dependencies: [
.package(url: "https://github.com/swift-server-community/APNSwift.git", from: "4.0.0"),
.package(url: "https://github.com/swift-server-community/APNSwift.git", from: "6.0.0"),
]
```
If youd like to give our bleeding edge release a try, which is what the Readme is expecting use `5.0.0-alpha.N`. If you need the old Readme, see [here](https://github.com/swift-server-community/APNSwift/tree/4.0.0)

```swift
dependencies: [
.package(url: "https://github.com/swift-server-community/APNSwift.git", from: "5.0.0-alpha.5"),
]
```

## Foundations
`APNSwift` is built with a layered approach. It exposes three tiers of API's.
1. A [raw API](https://github.com/swift-server-community/APNSwift/blob/d60241fe2b6eb193331567a871697d3f4bdf70fb/Sources/APNSwift/APNSClient.swift#L254) that takes basic types such as `String`'s
2. A slightly more [semantically safe API](https://github.com/swift-server-community/APNSwift/blob/d60241fe2b6eb193331567a871697d3f4bdf70fb/Sources/APNSwift/APNSClient.swift#L183), which takes types, like [`APNSPriority`](https://github.com/swift-server-community/APNSwift/blob/main/Sources/APNSwift/APNSPriority.swift), [`APNSPushType`](https://github.com/swift-server-community/APNSwift/blob/main/Sources/APNSwift/APNSPushType.swift), [`APNSNotificationExpiration`](https://github.com/swift-server-community/APNSwift/blob/main/Sources/APNSwift/APNSNotificationExpiration.swift), etc.
3. The [safest API](https://github.com/swift-server-community/APNSwift/blob/d60241fe2b6eb193331567a871697d3f4bdf70fb/Sources/APNSwift/Alert/APNSClient%2BAlert.swift#L32) which takes fully semantic types such as [`APNSAlertNotification`](https://github.com/swift-server-community/APNSwift/blob/d60241fe2b6eb193331567a871697d3f4bdf70fb/Sources/APNSwift/Alert/APNSAlertNotification.swift#L177)

**We recommened using number 3, the semantically safest API to ensure your push notification is delivered correctly**. *This README assumes that you are using number 3.* However if you need more granular approach, or something doesn't exist in this library, please use 2 or 1. (Also please open an issue if we missed something so we can get a semantically correct version!)

## Getting Started
APNSwift aims to provide sementically correct structures to sending push notifications. You first need to setup a [`APNSClient`](https://github.com/swift-server-community/APNSwift/blob/main/Sources/APNSwift/APNSClient.swift). To do that youll need to know your authentication method
APNSwift aims to provide semantically correct structures to sending push notifications. You first need to setup a [`APNSClient`](https://github.com/swift-server-community/APNSwift/blob/main/Sources/APNS/APNSClient.swift). To do that youll need to know your authentication method

```swift
let client = APNSClient(
Expand All @@ -41,15 +27,11 @@ let client = APNSClient(
),
eventLoopGroupProvider: .createNew,
responseDecoder: JSONDecoder(),
requestEncoder: JSONEncoder(),
byteBufferAllocator: .init(),
backgroundActivityLogger: logger
requestEncoder: JSONEncoder()
)
defer {
client.shutdown { _ in
logger.error("Failed to shutdown APNSClient")
}
}

// Shutdown the client when done
try await client.shutdown()
```

## Sending a simple notification
Expand All @@ -71,9 +53,7 @@ try await client.sendAlertNotification(
topic: "com.app.bundle",
payload: Payload()
),
deviceToken: "device-token",
deadline: .nanoseconds(Int64.max),
logger: myLogger
deviceToken: "device-token"
)
```

Expand All @@ -85,8 +65,8 @@ These can be configured when created your `APNSClientConfiguration`

*Notes: `jwt` requires an encrypted version of your .p8 file from Apple which comes in a `pem` format. If you're having trouble with your key being invalid please confirm it is a PEM file*
```
openssl pkcs8 -nocrypt -in /path/to/my/key.p8 -out ~/Downloads/key.pem
```
openssl pkcs8 -nocrypt -in /path/to/my/key.p8 -out ~/Downloads/key.pem
```

## Logging
By default APNSwift has a no-op logger which will not log anything. However if you pass a logger in, you will see logs.
Expand All @@ -98,31 +78,6 @@ This logger can be passed into the `APNSClient` and will log background things l
#### **Notification Send Logger**
This logger can be passed into any of the `send:` methods and will log everything related to a single send request.

## Using the non semantic safe APIs

APNSwift provides the ability to send raw payloads. You can use `Data`, `ByteBuffer`, `DispatchData`, `Array`
Though this is to be used with caution. APNSwift cannot gurantee delivery if you do not have the correct payload.
For more information see: [Creating APN Payload](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html)

```swift
/// Extremely Raw,
try await client.send(
payload: payload,
deviceToken: token,
pushType: "alert", deadline: .distantFuture
)

/// or a little safer but still raw
try await client.send(
payload: payload,
deviceToken: token,
pushType: .alert,
expiration: .immediatly,
priority: .immediatly,
deadline: .distantFuture
)
```

## Server Example
Take a look at [Program.swift](https://github.com/swift-server-community/APNSwift/blob/main/Sources/APNSwiftExample/Program.swift)

Expand All @@ -136,3 +91,4 @@ Once inside configure your App Bundle ID and assign your development team. Build

* Pitch discussion: [Swift Server Forums](https://forums.swift.org/t/apple-push-notification-service-implementation-pitch/20193)
* Proposal: [SSWG-0006](https://forums.swift.org/t/feedback-nioapns-nio-based-apple-push-notification-service/24393)
* 5.0 breaking changings: [Swift Server Forums]([Blog post here on breaking changing](https://forums.swift.org/t/apnswift-5-0-0-beta-release/60075/3))
6 changes: 3 additions & 3 deletions Sources/APNS/APNSClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public final class APNSClient<Decoder: APNSJSONDecoder, Encoder: APNSJSONEncoder

/// Initializes a new APNS.
///
/// The client will create an internal ``HTTPClient`` which is used to make requests to APNs.
/// This ``HTTPClient`` is intentionally internal since both authentication mechanisms are bound to a
/// The client will create an internal `HTTPClient` which is used to make requests to APNs.
/// This `HTTPClient` is intentionally internal since both authentication mechanisms are bound to a
/// single connection and these connections cannot be shared.
///
///
Expand All @@ -67,7 +67,7 @@ public final class APNSClient<Decoder: APNSJSONDecoder, Encoder: APNSJSONEncoder
/// - eventLoopGroupProvider: Specify how EventLoopGroup will be created.
/// - responseDecoder: The decoder for the responses from APNs.
/// - requestEncoder: The encoder for the requests to APNs.
/// - backgroundActivityLogger: The logger used by the APNS.
/// - byteBufferAllocator: The `ByteBufferAllocator`.
public init(
configuration: APNSClientConfiguration,
eventLoopGroupProvider: NIOEventLoopGroupProvider,
Expand Down
2 changes: 1 addition & 1 deletion Sources/APNS/APNSConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public struct APNSClientConfiguration: Sendable {
/// Upstream proxy, defaults to no proxy.
public var proxy: HTTPClient.Configuration.Proxy?

/// Initializes a new ``APNSClient.Configuration``.
/// Initializes a new ``APNSClientConfiguration``.
///
/// - Parameters:
/// - authenticationMethod: The authentication method used by the ``APNSClient``.
Expand Down
2 changes: 1 addition & 1 deletion Sources/APNS/Coding/APNSJSONDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Foundation
import NIOCore
import NIOFoundationCompat

/// A protocol that is similar to the ``JSONDecoder``. This allows users of APNSwift to customize the decoder used
/// A protocol that is similar to the `JSONDecoder`. This allows users of APNSwift to customize the decoder used
/// for decoding the APNS response bodies.
public protocol APNSJSONDecoder {
func decode<T: Decodable>(_ type: T.Type, from buffer: ByteBuffer) throws -> T
Expand Down
2 changes: 1 addition & 1 deletion Sources/APNS/Coding/APNSJSONEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Foundation
import NIOCore
import NIOFoundationCompat

/// A protocol that is similar to the ``JSONEncoder``. This allows users of APNSwift to customize the encoder used
/// A protocol that is similar to the `JSONEncoder`. This allows users of APNSwift to customize the encoder used
/// for encoding the notification JSON payloads.
public protocol APNSJSONEncoder {
func encode<T: Encodable>(_ value: T, into buffer: inout ByteBuffer) throws
Expand Down

0 comments on commit ab54efb

Please sign in to comment.