Skip to content

Commit

Permalink
Cleanup logger usage, rename APNSwiftClient and use custom httpclient (
Browse files Browse the repository at this point in the history
…#132)

* Cleanup logger usage, rename APNSwiftClient and use custom httpclient

* fix readme

* One More

* Shutdown

* Cleanup token factory

* make signer an actor

* Renames

* updte readme

* Update Copyright and contributers list

* Add documentation

* update

* fixed ELG and formatted

* cleanup

* updates

* add more documentation
kylebrowning authored Jun 11, 2022

Verified

This commit was signed with the committer’s verified signature.
billyjacoby Billy Jacoby
1 parent 2f7c21c commit 4d2c0ed
Showing 21 changed files with 536 additions and 539 deletions.
6 changes: 6 additions & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
@@ -12,13 +12,19 @@ needs to be listed here.
- Craig Newell <[email protected]>
- Eduardo Perez <[email protected]>
- Florian Reinhart <[email protected]>
- Geoff Verdouw <[email protected]>
- Jeffrey Macko <[email protected]>
- Jonny <[email protected]>
- Kyle Browning <[email protected]>
- Laurent Gaches <[email protected]>
- Lukáš Petr <[email protected]>
- Mads Odgaard <[email protected]>
- Nikola Paunović <[email protected]>
- Roderic Campbell <[email protected]>
- Simon Kempendorf <[email protected]>
- Tanner <[email protected]>
- Tanner Nelson <[email protected]>
- Timothy Ellis <[email protected]>
- grosch <[email protected]>
- itcohorts <[email protected]>
- tanner0101 <[email protected]>
30 changes: 18 additions & 12 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -13,20 +13,26 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-crypto.git", "1.0.0" ..< "3.0.0"),
.package(url: "https://github.com/apple/swift-crypto.git", "1.0.0"..<"3.0.0"),
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.10.0"),
],
targets: [
.executableTarget(name: "APNSwiftExample", dependencies: [
.target(name: "APNSwift"),
]),
.testTarget(name: "APNSwiftTests", dependencies: [
.target(name: "APNSwift"),
]),
.target(name: "APNSwift", dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "AsyncHTTPClient", package: "async-http-client")
]),
.executableTarget(
name: "APNSwiftExample",
dependencies: [
.target(name: "APNSwift")
]),
.testTarget(
name: "APNSwiftTests",
dependencies: [
.target(name: "APNSwift")
]),
.target(
name: "APNSwift",
dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "AsyncHTTPClient", package: "async-http-client"),
]),
]
)
70 changes: 34 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[![sswg:incubating|94x20](https://img.shields.io/badge/sswg-incubating-yellow.svg)](https://github.com/swift-server/sswg/blob/master/process/incubation.md#sandbox-level)
[![License](https://img.shields.io/badge/License-Apache%202.0-yellow.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Build](https://github.com/kylebrowning/APNSwift/workflows/test/badge.svg)](https://github.com/kylebrowning/APNSwift/actions)
[![Swift](https://img.shields.io/badge/Swift-5.2-brightgreen.svg?colorA=orange&colorB=4E4E4E)](https://swift.org)
[![Swift](https://img.shields.io/badge/Swift-5.6-brightgreen.svg?colorA=orange&colorB=4E4E4E)](https://swift.org)
[![Documentation](https://img.shields.io/badge/documentation-blueviolet.svg)](https://swiftpackageindex.com/swift-server-community/APNSwift/master/documentation/apnswift)


# APNSwift

@@ -20,117 +22,113 @@ dependencies: [
## Getting Started

```swift
struct BasicNotification: APNSwiftNotification {
let aps: APNSwiftPayload
struct BasicNotification: APNSNotification {
let aps: APNSPayload
}

let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
var logger = Logger(label: "com.apnswift")
logger.logLevel = .debug

/// Create your HTTPClient (or pass in one you already have)
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(group))
/// Create your `APNSConfiguration.Authentication`

/// Create your `APNSwiftConfiguration.Authentication`
let authenticationConfig: APNSwiftConfiguration.Authentication = .init(
let authenticationConfig: APNSConfiguration.Authentication = .init(
privateKey: try .loadFrom(filePath: "/Users/kylebrowning/Documents/AuthKey_9UC9ZLQ8YW.p8"),
teamIdentifier: "ABBM6U9RM5",
keyIdentifier: "9UC9ZLQ8YW"
)

/// If you need to use an a secrets manager instead of read from disk, use
/// If you need to use a secrets manager instead of reading from the disk, use
/// `loadfrom(string:)`

let apnsConfig = try APNSwiftConfiguration(
let apnsConfig = try APNSConfiguration(
authenticationConfig: authenticationConfig,
topic: "com.grasscove.Fern",
environment: .sandbox,
logger: logger
)
let apns = APNSwiftConnection(configuration: apnsConfig, logger: logger)
let apns = APNSClient(configuration: apnsConfig)

let aps = APNSwiftPayload(alert: .init(title: "Hey There", subtitle: "Subtitle", body: "Body"), hasContentAvailable: true)
let aps = APNSPayload(alert: .init(title: "Hey There", subtitle: "Subtitle", body: "Body"), hasContentAvailable: true)
let deviceToken = "myDeviceToken"
try await apns.send(notification, pushType: .alert, to: deviceToken)
try await httpClient.shutdown()
try! group.syncShutdownGracefully()
exit(0)
```

### APNSwiftConfiguration
### APNSConfiguration

[`APNSwiftConfiguration`](https://github.com/kylebrowning/swift-nio-http2-apns/blob/master/Sources/APNSwift/APNSwiftConfiguration.swift) is a structure that provides the system with common configuration.
[`APNSConfiguration`](https://github.com/kylebrowning/swift-nio-http2-apns/blob/master/Sources/APNSwift/APNSConfiguration.swift) is a structure that provides the system with common configuration.

```swift
let apnsConfig = try APNSwiftConfiguration(
let apnsConfig = try APNSConfiguration(
authenticationConfig: authenticationConfig,
topic: "com.grasscove.Fern",
environment: .sandbox,
logger: logger
)
```

#### APNSwiftConfiguration.Authentication
[`APNSwiftConfiguration.Authentication`](https://github.com/swift-server-community/APNSwift/blob/master/Sources/APNSwift/APNSwiftConfiguration.swift#L26) is a struct that provides authentication keys and metadata to the signer.
#### APNSConfiguration.Authentication
[`APNSConfiguration.Authentication`](https://github.com/swift-server-community/APNSwift/blob/master/Sources/APNSwift/APNSConfiguration.swift#L26) is a struct that provides authentication keys and metadata to the signer.


```swift
let authenticationConfig: APNSwiftConfiguration.Authentication = .init(
let authenticationConfig: APNSConfiguration.Authentication = .init(
privateKey: try .loadFrom(filePath: "/Users/kylebrowning/Documents/AuthKey_9UC9ZLQ8YW.p8"),
teamIdentifier: "ABBM6U9RM5",
keyIdentifier: "9UC9ZLQ8YW"
)
```

### APNSwiftConnection
### APNSClient

[`APNSwiftConnection`](https://github.com/kylebrowning/swift-nio-http2-apns/blob/master/Sources/APNSwift/APNSwiftConnection.swift) provides functions to send a notification to a specific device token string.
[`APNSClient`](https://github.com/kylebrowning/swift-nio-http2-apns/blob/master/Sources/APNSwift/APNSClient.swift) provides functions to send a notification to a specific device token string.


#### Example `APNSwiftConnection`
#### Example `APNSClient`
```swift
let apns = APNSwiftConnection(configuration: apnsConfig, logger: logger)
let apns = APNSClient(configuration: apnsConfig)
```

### APNSwiftAlert
### APNSAlert

[`APNSwiftAlert`](https://github.com/kylebrowning/APNSwift/blob/tn-concise-naming/Sources/APNSwift/APNSwiftAlert.swift) is the actual meta data of the push notification alert someone wishes 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 1-1 naming scheme listed in Apple's documentation
[`APNSAlert`](https://github.com/kylebrowning/APNSwift/blob/tn-concise-naming/Sources/APNSwift/APNSAlert.swift) is the actual meta data of the push notification alert someone wishes 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 1-1 naming scheme listed in Apple's documentation


#### Example `APNSwiftAlert`
#### Example `APNSAlert`
```swift
let alert = APNSwiftAlert(title: "Hey There", subtitle: "Full moon sighting", body: "There was a full moon last night did you see it")
let alert = APNSAlert(title: "Hey There", subtitle: "Full moon sighting", body: "There was a full moon last night did you see it")
```

### APNSwiftPayload
### APNSPayload

[`APNSwiftPayload`](https://github.com/kylebrowning/APNSwift/blob/tn-concise-naming/Sources/APNSwift/APNSwiftPayload.swift) is the meta data of the push notification. Things like the alert, badge count. 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 1-1 naming scheme listed in Apple's documentation
[`APNSPayload`](https://github.com/kylebrowning/APNSwift/blob/tn-concise-naming/Sources/APNSwift/APNSPayload.swift) is the meta data of the push notification. Things like the alert, badge count. 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 1-1 naming scheme listed in Apple's documentation


#### Example `APNSwiftPayload`
#### Example `APNSPayload`
```swift
let alert = ...
let aps = APNSwiftPayload(alert: alert, badge: 1, sound: .normal("cow.wav"))
let aps = APNSPayload(alert: alert, badge: 1, sound: .normal("cow.wav"))
```

### Custom Notification Data

Apple provides engineers with the ability to add custom payload data to each notification. In order to facilitate this we have the `APNSwiftNotification`.
Apple provides engineers with the ability to add custom payload data to each notification. In order to facilitate this we have the `APNSNotification`.

#### Example
```swift
struct AcmeNotification: APNSwiftNotification {
let acme2: [String]
let aps: APNSwiftPayload
let aps: APNSPayload

init(acme2: [String], aps: APNSwiftPayload) {
init(acme2: [String], aps: APNSPayload) {
self.acme2 = acme2
self.aps = aps
}
}

let apns: APNSwiftConnection: = ...
let aps: APNSwiftPayload = ...
let apns: APNSClient: = ...
let aps: APNSPayload = ...
let notification = AcmeNotification(acme2: ["bang", "whiz"], aps: aps)
let res = try apns.send(notification, to: "de1d666223de85db0186f654852cc960551125ee841ca044fdf5ef6a4756a77e")
```
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//

/// This structure provides the data structure for an APNS Alert
public struct APNSwiftAlert: Codable {
public struct APNSAlert: Codable {
public let title: String?
public let subtitle: String?
public let body: String?
@@ -49,9 +49,15 @@ public struct APNSwiftAlert: Codable {
````
*/
public init(
title: String? = nil, subtitle: String? = nil, body: String? = nil,
titleLocKey: String? = nil, titleLocArgs: [String]? = nil, actionLocKey: String? = nil,
locKey: String? = nil, locArgs: [String]? = nil, launchImage: String? = nil
title: String? = nil,
subtitle: String? = nil,
body: String? = nil,
titleLocKey: String? = nil,
titleLocArgs: [String]? = nil,
actionLocKey: String? = nil,
locKey: String? = nil,
locArgs: [String]? = nil,
launchImage: String? = nil
) {
self.title = title
self.subtitle = subtitle
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
//
// This source file is part of the APNSwift open source project
//
// Copyright (c) 2019 the APNSwift project authors
// Copyright (c) 2022 the APNSwift project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
@@ -16,51 +16,46 @@ import Crypto
import Logging
import NIOCore

internal final actor APNSwiftBearerTokenFactory {
internal final actor APNSBearerTokenFactory {

private var cachedBearerToken: String?
internal var currentBearerToken: String? {

guard !isTokenStale, let cachedBearerToken = cachedBearerToken else {
do {
tokenCreated = NIODeadline.now()
let newToken = try makeNewBearerToken()
cachedBearerToken = newToken
return newToken
} catch {
internal func getCurrentBearerToken() async throws -> String {

logger?.error("Failed to generate token: \(error)")
return nil
}
guard !isTokenStale, let cachedBearerToken = cachedBearerToken else {
tokenCreated = NIODeadline.now()
let newToken = try await makeNewBearerToken()
cachedBearerToken = newToken
return newToken
}

logger?.debug("returning cached token \(cachedBearerToken.prefix(8))...")
logger?.debug("APNS cached token \(cachedBearerToken.prefix(8))...")
return cachedBearerToken
}

private var isTokenStale: Bool {
NIODeadline.now() - tokenCreated > TimeAmount.minutes(55)
}

private let signer: APNSwiftSigner
private let signer: APNSSigner
private let logger: Logger?
private var tokenCreated: NIODeadline = NIODeadline.now()

internal init(
authenticationConfig: APNSwiftConfiguration.Authentication,
authenticationConfig: APNSConfiguration.Authentication,
logger: Logger? = nil
) {
self.signer = APNSwiftSigner(
self.signer = APNSSigner(
privateKey: authenticationConfig.privateKey,
teamIdentifier: authenticationConfig.teamIdentifier,
keyIdentifier: authenticationConfig.keyIdentifier
)
self.logger = logger
}

private func makeNewBearerToken() throws -> String {
let newToken = try signer.sign()
logger?.debug("Creating a new APNS token \(newToken.prefix(8))...")
private func makeNewBearerToken() async throws -> String {
let newToken = try await signer.sign()
logger?.debug("APNS new token \(newToken.prefix(8))...")
return newToken
}

34 changes: 0 additions & 34 deletions Sources/APNSwift/APNSClient+LoggerConfig.swift

This file was deleted.

Loading

0 comments on commit 4d2c0ed

Please sign in to comment.