Skip to content

Commit

Permalink
beta.2 (#5)
Browse files Browse the repository at this point in the history
* beta.2

* updates

* remove extra spaces
  • Loading branch information
tanner0101 authored Dec 9, 2019
1 parent 769117c commit 3fcd6e8
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 71 deletions.
2 changes: 2 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github: [tanner0101] # loganwright, joscdk
open_collective: vapor
18 changes: 18 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: test
on:
- pull_request
jobs:
xenial:
container:
image: vapor/swift:5.1-xenial
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: swift test --enable-test-discovery --sanitize=thread
bionic:
container:
image: vapor/swift:5.1-bionic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: swift test --enable-test-discovery --sanitize=thread
17 changes: 10 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
// swift-tools-version:5.0
// swift-tools-version:5.1
import PackageDescription

let package = Package(
name: "apns-kit",
name: "apns",
platforms: [
.macOS(.v10_14)
],
products: [
.library(name: "APNSKit", targets: ["APNSKit"]),
.library(name: "APNS", targets: ["APNS"]),
],
dependencies: [
.package(url: "https://github.com/kylebrowning/APNSwift.git", from: "1.3.0"),
.package(url: "https://github.com/vapor/async-kit.git", from: "1.0.0-alpha.1"),
.package(url: "https://github.com/kylebrowning/APNSwift.git", .branch("master")),
.package(url: "https://github.com/vapor/vapor.git", .branch("master")),
],
targets: [
.target(name: "APNSKit", dependencies: ["AsyncKit", "APNSwift"]),
.testTarget(name: "APNSKitTests", dependencies: ["APNSKit"]),
.target(name: "APNS", dependencies: ["APNSwift", "Vapor"]),
.testTarget(name: "APNSTests", dependencies: ["APNS", "XCTVapor"]),
]
)
149 changes: 149 additions & 0 deletions Sources/APNS/APNS.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import Vapor

extension Application {
public var apns: APNS {
.init(application: self)
}

public struct APNS {
final class Storage {
var pool: EventLoopGroupConnectionPool<APNSConnectionSource>?
init() { }
}

struct Key: StorageKey {
typealias Value = Storage
}

struct Lifecycle: LifecycleHandler {
func shutdown(_ application: Application) {
if let pool = application.apns.storage.pool {
pool.shutdown()
}
}
}

var storage: Storage {
if self.application.storage[Key.self] == nil {
self.initialize()
}
return self.application.storage[Key.self]!
}

let application: Application

public func configure(_ configuration: APNSwiftConfiguration) {
assert(self.storage.pool == nil, "APNS can only be configured once")
self.storage.pool = .init(
source: .init(configuration: configuration),
maxConnectionsPerEventLoop: 1,
logger: self.application.logger,
on: self.application.eventLoopGroup
)
}

func initialize() {
self.application.storage[Key.self] = .init()
self.application.lifecycle.use(Lifecycle())
}
}
}

private struct BasicNotification: APNSwiftNotification {
let aps: APNSwiftPayload
init(aps: APNSwiftPayload) {
self.aps = aps
}
}

extension Request {
public var apns: APNS {
.init(request: self)
}

public struct APNS {
let request: Request

public func send(
_ alert: APNSwiftPayload.APNSwiftAlert,
pushType: APNSwiftConnection.PushType = .alert,
to deviceToken: String,
with encoder: JSONEncoder = JSONEncoder(),
expiration: Date? = nil,
priority: Int? = nil,
collapseIdentifier: String? = nil,
topic: String? = nil
) -> EventLoopFuture<Void> {
self.send(APNSwiftPayload(alert: alert), pushType: pushType, to: deviceToken, with: encoder, expiration: expiration, priority: priority, collapseIdentifier: collapseIdentifier, topic: topic)
}

public func send(
_ payload: APNSwiftPayload,
pushType: APNSwiftConnection.PushType = .alert,
to deviceToken: String,
with encoder: JSONEncoder = JSONEncoder(),
expiration: Date? = nil,
priority: Int? = nil,
collapseIdentifier: String? = nil,
topic: String? = nil
) -> EventLoopFuture<Void> {
self.send(BasicNotification(aps: payload), pushType: pushType, to: deviceToken, with: encoder, expiration: expiration, priority: priority, collapseIdentifier: collapseIdentifier, topic: topic)
}

public func send<Notification>(
_ notification: Notification,
pushType: APNSwiftConnection.PushType = .alert,
to deviceToken: String,
with encoder: JSONEncoder = JSONEncoder(),
expiration: Date? = nil,
priority: Int? = nil,
collapseIdentifier: String? = nil,
topic: String? = nil
) -> EventLoopFuture<Void>
where Notification: APNSwiftNotification
{
guard let pool = self.request.application.apns.storage.pool else {
fatalError("APNS not configured. Configure with app.apns.configure(...)")
}
return pool.withConnection(
logger: self.request.logger,
on: self.request.eventLoop
) {
$0.send(
notification,
pushType: pushType,
to: deviceToken,
with: encoder,
expiration: expiration,
priority: priority,
collapseIdentifier: collapseIdentifier,
topic: topic
)
}
}
}
}

public final class APNSConnectionSource: ConnectionPoolSource {
private let configuration: APNSwiftConfiguration

public init(configuration: APNSwiftConfiguration) {
self.configuration = configuration
}
public func makeConnection(
logger: Logger,
on eventLoop: EventLoop
) -> EventLoopFuture<APNSwiftConnection> {
APNSwiftConnection.connect(configuration: self.configuration, on: eventLoop)
}
}

extension APNSwiftConnection: ConnectionPoolItem {
public var eventLoop: EventLoop {
self.channel.eventLoop
}

public var isClosed: Bool {
self.channel.isActive
}
}
1 change: 1 addition & 0 deletions Sources/APNS/Exported.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@_exported import APNSwift
9 changes: 0 additions & 9 deletions Sources/APNSKit/Exported.swift

This file was deleted.

18 changes: 0 additions & 18 deletions Sources/APNSKit/apns_kit.swift

This file was deleted.

7 changes: 0 additions & 7 deletions Tests/APNSKitTests/XCTestManifests.swift

This file was deleted.

28 changes: 28 additions & 0 deletions Tests/APNSTests/APNSTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import APNS
import XCTVapor

class APNSTests: XCTestCase {
func testApplication() throws {
let app = Application(.testing)
defer { app.shutdown() }

try app.apns.configure(.init(
keyIdentifier: "9UC9ZLQ8YW",
teamIdentifier: "ABBM6U9RM5",
signer: .init(buffer: ByteBufferAllocator().buffer(capacity: 1024)),
topic: "com.grasscove.Fern",
environment: .sandbox
))

app.get("test-push") { req -> EventLoopFuture<HTTPStatus> in
req.apns.send(
.init(title: "Hello", subtitle: "This is a test from vapor/apns"),
to: "98AAD4A2398DDC58595F02FA307DF9A15C18B6111D1B806949549085A8E6A55D"
).map { .ok }
}

try app.test(.GET, "test-push") { res in
XCTAssertEqual(res.status, .internalServerError)
}
}
}
6 changes: 0 additions & 6 deletions Tests/LinuxMain.swift

This file was deleted.

24 changes: 0 additions & 24 deletions circle.yml

This file was deleted.

0 comments on commit 3fcd6e8

Please sign in to comment.