Open10
iOSのプッシュ通知(リモート通知)について
プッシュ通知(リモート通知)とは
- アプリが実行していない時でも、アプリを使用するデバイスにデータを通知することで、ユーザに情報を提供する
- ユーザにアクションを促す通知だけではなく、バックグラウンドで動作するバックグラウンド更新のプッシュもある(後述)
処理の流れ
1. デバイストークンを送る
- デバイストークン
- APNsに登録する、グローバルで一意なトークン。デバイス上のアプリのアドレス。
- アプリを起動する度に、アプリを登録し、デバイストークンを受け取る
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.you’re
UIApplication.shared.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: Data) {
self.sendDeviceTokenToServer(data: deviceToken)
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError
error: Error) {
// Try again later.
}
2. プッシュ情報を送信(POSTリクエスト)
- POSTでリクエストするときには、以下の情報を含める
- JSONペイロード
- デバイストークン
- 通知の配信方法を指定するリクエストヘッダー
- (トークンベースの認証の場合)プロバイダーサーバの現在の認証トークン
認証トークンでリクエストする場合の例
HEADERS
- END_STREAM
+ END_HEADERS
:method = POST
:scheme = https
:path = /3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0
host = api.sandbox.push.apple.com
authorization = bearer eyAia2lkIjogIjhZTDNHM1JSWDciIH0.eyAiaXNzIjogIkM4Nk5WOUpYM0QiLCAiaWF0I
jogIjE0NTkxNDM1ODA2NTAiIH0.MEYCIQDzqyahmH1rz1s-LFNkylXEa2lZ_aOCX4daxxTZkVEGzwIhALvkClnx5m5eAT6
Lxw7LZtEQcH6JENhJTMArwLf3sXwi
apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
apns-push-type = alert
apns-expiration = 0
apns-priority = 10
apns-topic = com.example.MyApp
DATA
+ END_STREAM
{ "aps" : { "alert" : "Hello" } }
JSONペイロード
- リクエストの本文に入れる
{
"aps" : {
"badge" : 9, // アプリアイコンにつくバッジ
"sound" : "bingbong.aiff" // 再生するサウンド
"alert" : {
"title" : "Game Request", // プッシュ通知のタイトル
"subtitle" : "Five Card Draw", // プッシュ通知のサブタイトル
"body" : "Bob wants to play poker" // プッシュ通知の本文
},
"category" : "GAME_INVITATION" // 何じゃこりゃ
},
"gameID" : "12345678" // カスタムキー(自由に設定できるキー)
}
通知の配信方法を指定するリクエストヘッダー
フィールド | 必須/任意 | 説明 |
---|---|---|
method | 🟢 | POST |
path | 🟢 | デバイストークンへのパス。 |
authorization | (トークンベースの認証の場合は必要) | bearer <provider_token> |
apns-push-type | (watchOS 6 以降では必須。macOS、iOS、tvOS、および iPadOS では推奨) | payloadの内容を正確に反映する |
apns-id | 通知の一意なUUID。エラーが発生した場合、この値がレスポンスされる。このヘッダーが省略された場合は、APNsが自動でUUIDを作成してレスポンスする。 | |
apns-expiration | 通知が無効になる日付。値がゼロ以外の場合、APNs は通知を保存し、少なくとも 1 回配信を試み、指定された日付まで必要に応じて配信を試みる。値が0の場合、APNs は通知の配信を 1 回だけ試行し、保存しない。 | |
apns-priority | 通知の優先度。省略するとAPNsは10 を設定する。・ 10 :通知をすぐに配信する・ 5 :ユーザのデバイスの電源に関する考慮をして通知を配信する・ 1 :配信よりもデバイスの電源に関する考慮をし、デバイスが起動するのを防ぐ |
|
apns-topic | (トークンベースの認証の場合は必要) | 通知のトピック。通常はアプリのBundle IDかアプリID。 |
apns-collapse-id | 複数の通知をユーザ向けの一つの通知に結合するために使用される識別子。同じ通知を複数回送信する場合は、このヘッダーで同じ値を使用してリクエストを結合する。 |
apns-push-type
の種類
種類 | 説明 |
---|---|
alert | アラート、バッジ、サウンドなど、ユーザインタラクションをトリガーする通知。 |
background | backgroundバックグラウンドでコンテンツを配信し、ユーザー インタラクションをトリガーしない通知。 |
location | ユーザーの位置情報を要求する通知。 |
voip | Voice-over-IP (VoIP) 通話の着信に関する情報を提供する通知。 |
complication | watchOS アプリのコンプリケーションの更新情報を含む通知。 |
fileprovider | ファイル プロバイダー拡張機能への変更を通知 |
mdm | mdm管理対象デバイスに MDM サーバーに接続するように指示する通知。 |
APNsとの接続の確立方法
- トークンベース
- 証明書ベース
4.レスポンスを返却する
- 成功した場合
HEADERS
+ END_STREAM
+ END_HEADERS
apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b // リクエストヘッダーにある値と同じ
:status = 200 // ステータスコード
- 失敗した場合
HEADERS
- END_STREAM
+ END_HEADERS
:status = 400
content-type = application/json
apns-id: <a_UUID>
DATA
+ END_STREAM
{ "reason" : "BadDeviceToken" } // reasonは、失敗の理由を示すエラー コード
APNsと保管についての詳細
(いつか書く)
APNsに接続している間のベストプラクティス
(いつか書く)
バックグラウンド更新のプッシュ
- アプリのコンテンツがコンテンツが頻繁に変更されない、または不規則な間隔で変更される場合にこの通知を使用する
- 新しいコンテンツが利用可能になったときに、アプリに通知する
- アラート表示、サウンド再生、アプリのアイコンにバッジをつけるなどは行わないリモート通知
- バックグラウンドでアプリを起動し、サーバからのダウンロードを開始してコンテンツを更新する時間を与える
参考資料
プッシュ通知のUIのカスタマイズ
通知センターで表示されるUIをカスタマイズすることができる
右のようにデフォルトのUI部分を非表示にするためには、Info.plistにあるUNNotificationExtensionDefaultContentHidden
のkeyを追加してtrue
にする必要がある
iOS15以降の変化
- 通知センターで表示されるバナーのUIが変わっている
- payloadの
title
が設定されている場合、アプリ名が表示されずtitle
の値が代わりに表示される模様(iOS13と14ではアプリ名もtitle
もsubtitle
も表示されていたが、iOS15から変わったみたい)
- payloadの
- (他にも何かあるかも)