Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DocC and remove warnings #210

Merged
merged 2 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ let package = Package(
]
),
],
swiftLanguageVersions: [.v6]
swiftLanguageModes: [.v6]
)
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