LoginSignup
22
15

More than 5 years have passed since last update.

VaporAPNSを使ってプッシュ通知を送る

Posted at

APIサーバーをSwiftで構築できるようになった今、プッシュ通知用のサーバーもSwiftで構築したい!ということがあるかもしれません。そこで「VaporAPNS」です。

この記事では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に対応したクライアントが必要なため以下のようにします。

$ brew reinstall curl --with-openssl --with-nghttp2
$ brew link curl --force

証明書

APNsとの通信に使用する証明書を準備します。証明書の作成方法は検索すれば沢山ヒットするため省きます。新しくAuthentication Keyを使って認証する方式もありますが、そちらについてはこの記事では触れません。検証してはいませんが、VaporAPNSのドキュメントには、Authentication Keyを使った方法についても触れているので確認してみてください。

従来方式を使用する場合は以下のようにしてp12ファイルから証明書と秘密鍵を取り出してください。

$ 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」というディレクトリに作成しています。

$ swift package init --type executable

次にPackage.swiftにライブラリの依存関係を記述します。

import PackageDescription

let package = Package(
    name: "vapor-apns",
    dependencies: [
        .Package(url:"https://github.com/matthijs2704/vapor-apns.git", majorVersion: 1, minor: 1)
    ]
)

フェッチします。

$ swift package fetch

次に必須ではないですがXcodeのプロジェクトファイルを生成します。Xcodeを使うと普段アプリを開発している環境でサーバーも実装できるので便利です。

$ swift package generate-xcodeproj

実装

次にVaporAPNSを使って実際にプッシュ通知を受け取る実装をします。main.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)

こんな感じのコードを実装します。アプリ側では、

@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()
    }
}

こんな感じに実装して、端末にインストールします。

あとはコンパイルして実行するだけです。

$ swift build
$ .build/debug/vapor-apns

結果

やりました。

参考

22
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
15