こんちは。渡部です。
今回はプッシュ通知についてです。
プッシュ通知はリモートだと証明書やらで非常に面倒になります。
なので比較的に簡単な実装方法を紹介します。
プッシュ通知とは?
プッシュ通知とは、システム側が外部のサーバーと連携して能動的に情報を取得してユーザーに通知する方式のことである。
www.weblio.jp
要は外部から通知が届く仕組みです。
LINEとかメッセージ届くときますよね?
あれです。
動作環境
・macOS Sierra(10.12.6)
・Xcode8.3.2(古い!)
・Swift3.0(古い!)
・実機(iPhone SE iOS10.2 古い!)
注意点
・シミュレータでは検証できないので実機でおねしゃす!
・AppleDeveloperProgramには加入済み前提で進めます。
・証明書CSRファイルは取得済み前提です。
・今回はAdHocでやります。
・訳あってiOS、Xcodeとも古いままです。
・サーバサイドはノータッチ!
プッシュ通知の種類
リモートとローカル
簡単に言うと、ローカルはアプリ側のプログラムで通知が完結するもの
リモートは外部のサーバを使って通知を可能にするもの
と自分は定義しています。
プッシュ?リッチ?ペイロード?なんぞ?
通常のプッシュ通知のみの実装がプッシュ通知、
プッシュ通知を開くとWebViewが表示できるのがリッチプッシュ、
プッシュ通知からメッセージなどのデータをペイロード取得
する通知があります。
今回は面倒なのでシンプルなリモートのプッシュ通知です。
次回はローカルの記事を書くかもしれません。
書かないかもしれません。
詳しい仕組みは偉人たちの記事を参照してください(投げやり) 。
チャット風メッセージアプリを作ります。
Web側のメッセージ送信時にアプリがフォアグラウンドにない場合に
通知を表示させるだけの簡単な仕様です。
チャット?
どうやって作んの?の人はこちら。
今回は画像付きで長くなるで!
手順
・APNs証明書作成
・アプリの設定
・コーディング
・実行
APNs証明書作成
AppleDeveloperにログインし、「Certificates,IDs & Profiles」を選択します。
右ペインのメニューから「Certificates」を選択し、右上の「+」ボタンで証明書を作成します。
Apple Push Notification service SSL(Sandbox)を選択し
使いたいアプリのApp IDを選択します。
このページは華麗にスルー
CSRファイルを選択すればおけ!
アプリの設定
まずプロジェクトでプッシュ通知を使うための設定をします。
プロジェクトを選択し、「Capabilities」から「Push Notifications」と「Background Modes」をONにします。
「Background Modes」は「Background fetch」と「Remote Notifications」にチェックを入れます。
コーディング
プッシュ通知の基本ですが通知を受け取るには許可が必要です。
許可をもらった後に、デバイストークンを取得してサーバサイドに渡す必要があります。
いくつか注意点があるのでコメントを読んでください。
まずはインポートとDelegateの設定です。
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, networkManagerDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
didFinishLaunchingWithOptionsで通知の設定をします。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.badge, .sound, .alert], completionHandler: { (granted, error) in
if error != nil {
return
}
if granted {
debugPrint("通知許可")
center.delegate = self
application.registerForRemoteNotifications()
} else {
debugPrint("通知拒否")
}
})
} else {
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
UIApplication.shared.registerForRemoteNotifications()
}
return true
}
通知が許可された場合の処理です。
ここでデバイストークンを取得します。
以降もずっとこのデバイストークンを使うのでUserDefaults等に保存しておきます。
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let deviceTokenString: String = deviceToken.map { String(format: "%.2hhx", $0) }.joined()
print("deviceTokenString \(deviceTokenString)")
util.setUserDefaultsObject(value: deviceTokenString, key: udDeviceToken)
}
逆に通知が許可されなかった場合の処理です。
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
debugPrint("リモート通知の設定は拒否されました")
}
ここまで書けば一応動きます。
通知が来た時、通知から起動した時は
withCompletionHandlerなどを使います。
もちろん、はしょります。
実行
ビルドして実機にインストールします。
ここでビルド成功後にエラーが出たりしますがそこは頑張ってください。
多分プロビジョニングとかが悪さしてることが多いです。
今回は速攻で通知の許可アラートが表示されるはずです。
許可した後にアプリを一度バックグラウンドにします。
Web側でメッセージを送信!
来た!
おまけ
サーバサイドはノータッチとしてましたが
今回はAWSのこちらを使っています。
aws.amazon.com
まとめ
準備から実装まで面倒なプッシュ通知ですが
ユーザーのアプリ復帰率を上げるためには必須と言えます。
通知自体もだんだんリッチになるので
今のうちに簡単な通知ができるようになった方が良いな、と思いこの記事を書きました。
どこかの誰かのお役に立てればと思います。