1. rb-de0

    Posted

    rb-de0
Changes in title
+VaporAPNSを使ってプッシュ通知を送る
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,159 @@
+APIサーバーをSwiftで構築できるようになった今、プッシュ通知用のサーバーもSwiftで構築したい!ということがあるかもしれません。そこで「[VaporAPNS](https://github.com/matthijs2704/vapor-apns)」です。
+
+この記事ではVaporAPNSを使ってプッシュ通知を送る方法を紹介します。実際はデバイストークンを受け取ってDBに保存したりしますが、その部分は省きデバイストークンが分かっている前提で紹介します。デバイストークンを受け取るサーバー自体もVaporで簡単に実装できるのでぜひ試してみてください。
+
+## 環境
+
+以下の環境で検証しました。
+
+- OS X El Capitan 10.11.5
+- Swift 3.0.1
+- VaporAPNS 1.1.1
+- iOS 10.1
+
+## 準備
+
+### HTTP/2
+
+APNs Provider APIを利用するためにHTTP/2に対応したクライアントが必要なため以下のようにします。
+
+```bash
+$ brew reinstall curl --with-openssl --with-nghttp2
+$ brew link curl --force
+```
+
+### 証明書
+
+APNsとの通信に使用する証明書を準備します。証明書の作成方法は検索すれば沢山ヒットするため省きます。新しくAuthentication Keyを使って認証する方式もありますが、そちらについてはこの記事では触れません。検証してはいませんが、VaporAPNSのドキュメントには、Authentication Keyを使った方法についても触れているので確認してみてください。
+
+従来方式を使用する場合は以下のようにしてp12ファイルから証明書と秘密鍵を取り出してください。
+
+```bash
+$ openssl pkcs12 -in Certificates.p12 -out push.crt.pem -clcerts -nokeys
+$ openssl pkcs12 -in Certificates.p12 -out push.key.pem -nocerts -nodes
+```
+
+## 導入
+
+まずはSwift Package Managerでパッケージを作成します。今回は「vapor-apns」というディレクトリに作成しています。
+
+```bash
+$ swift package init --type executable
+```
+
+次にPackage.swiftにライブラリの依存関係を記述します。
+
+```Swift
+import PackageDescription
+
+let package = Package(
+ name: "vapor-apns",
+ dependencies: [
+ .Package(url:"https://github.com/matthijs2704/vapor-apns.git", majorVersion: 1, minor: 1)
+ ]
+)
+```
+
+フェッチします。
+
+```bash
+$ swift package fetch
+```
+
+次に必須ではないですがXcodeのプロジェクトファイルを生成します。Xcodeを使うと普段アプリを開発している環境でサーバーも実装できるので便利です。
+
+```bash
+$ swift package generate-xcodeproj
+```
+
+## 実装
+
+次にVaporAPNSを使って実際にプッシュ通知を受け取る実装をします。main.swiftに
+
+```Swift
+import VaporAPNS
+
+let devicetToken = "デバイストークン"
+
+let options = try! Options(topic: "バンドルID", certPath: "証明書のパス", keyPath: "秘密鍵のパス")
+let vaporAPNS = try VaporAPNS(options: options)
+let payload = Payload(message: "hoge")
+let pushMessage = ApplePushMessage(priority: .immediately, payload: payload)
+
+vaporAPNS.send(pushMessage, to: devicetToken)
+
+```
+
+こんな感じのコードを実装します。アプリ側では、
+
+```Swift
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+
+ let center = UNUserNotificationCenter.current()
+ center.delegate = self
+ center.requestAuthorization(options: [.badge, .sound, .alert]){ isGranded, _ in
+
+ if isGranded {
+ application.registerForRemoteNotifications()
+ }
+ }
+
+ return true
+ }
+
+ func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
+
+ let characterSet = CharacterSet(charactersIn: "<>")
+ let deviceToken = String(format: "%@", deviceToken as CVarArg)
+ .trimmingCharacters(in: characterSet)
+ .replacingOccurrences(of: " ", with: "")
+
+ print("deviceToken: \(deviceToken)")
+ }
+}
+
+extension AppDelegate: UNUserNotificationCenterDelegate {
+
+ func userNotificationCenter(_ center: UNUserNotificationCenter,
+ willPresent notification: UNNotification,
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
+
+ completionHandler([.badge, .sound, .alert])
+ }
+
+ func userNotificationCenter(_ center: UNUserNotificationCenter,
+ didReceive response: UNNotificationResponse,
+ withCompletionHandler completionHandler: @escaping () -> Void) {
+ completionHandler()
+ }
+}
+```
+
+こんな感じに実装して、端末にインストールします。
+
+あとはコンパイルして実行するだけです。
+
+```bash
+$ swift build
+$ .build/debug/vapor-apns
+```
+
+## 結果
+
+<img src="https://blog.reb-dev.com/wp-content/uploads/2016/12/スクリーンショット-2016-12-11-14.18.47.png" width="50%">
+
+
+やりました。
+
+
+## 参考
+- [iOSのプッシュ通知送信時にトークン認証が使えるようになったので調べてみた](http://qiita.com/Tueno@github/items/9b4b59a9191b64299cf8)
+
+
+
+