SwiftDataのスキーマ変更を乗り越え、次にサーバー側から通知を送れるプッシュ通知(リモート通知)の実装に挑戦しました。以前ローカル通知を実装した経験があったので楽観視していたのですが、全く別物の難しさがありました。
1. ローカル通知と同じ感覚で始めて全く動かなかった
ローカル通知の実装経験があったので、似たようなコードで動くだろうと考えていたのですが、リモート通知は仕組みが根本的に違いました。
ローカル通知: アプリ自身が「いつ・何を」通知するか決めて予約する
リモート通知: サーバーがApple経由で通知を送り、アプリは受け取るだけ
アプリ内で完結するローカル通知に対し、リモート通知は「自分のサーバー→Apple Push Notification service (APNs)→端末」という外部を経由する仕組みだと理解してから、必要な設定の多さにも納得がいきました。
2. デバイストークンの取得だけで一苦労した
まず、端末を識別するための「デバイストークン」という文字列を取得する必要があったのですが、この取得だけでも複数のつまずきがありました。
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
print(token)
}
通知の許可をリクエストする処理と、このトークンを受け取る処理が別々のタイミングで呼ばれることを理解しておらず、許可が下りたのにトークンが取得できないと勘違いして数時間悩みました。両者は非同期に呼ばれる別のコールバックなのだと理解してからは、混乱なく実装できるようになりました。
3. シミュレーターでテストできず実機が必須だと知らなかった
コードを書き終えてシミュレーターで動作確認しようとしたら、そもそもデバイストークンが一切取得できず、原因究明に時間を費やしてしまいました。
リモート通知の実機テストには以下が必要
- 実機(近年のXcodeではシミュレーターでも一部テスト可能だが制限が多い)
- APNs用の証明書またはキー(App Store Connectで作成)
- Sandbox環境のプッシュ通知設定
結局のところ、ローカル通知のようにシミュレーターで手軽に試せる話ではなく、実機と正しい証明書設定がなければまともにテストできない機能だと分かりました。準備の負荷がローカル通知とは比較にならないほど高いと実感しました。
4. 証明書とプッシュ通知用のキーの違いで混乱した
Xcodeの証明書で学んだ内容と近いようで違う話に、また戸惑いました。App Store Connectで作る「APNs Auth Key」は、アプリの署名に使う開発用証明書とは全くの別物でした。
開発用証明書: アプリ自体の署名・実行許可に使う
APNs Auth Key: サーバーがAPNs経由で通知を送信する際の認証に使う
似たような「鍵」や「証明書」という言葉に何度も出てきますが、それぞれ役割が違うと理解してからは、エラーメッセージを見たときにどちらの設定を疑うべきかの判断がつきやすくなりました。
まとめ
- ローカル通知とリモート通知は仕組みが根本的に異なり、経験があっても油断できない
- 通知の許可リクエストとデバイストークンの取得は、別々の非同期コールバックで扱われる
- リモート通知の実機テストには証明書・キーの準備が必須で、シミュレーターだけでは完結しない
- 「開発用証明書」と「APNs Auth Key」は別物。似た言葉に惑わされず役割を区別する
サーバーとのやり取りが絡む分、アプリ内だけで完結する機能よりも準備の壁が高いと実感した実装でした。
次は、ウィジェット(WidgetKit)を実装してみて分かったことをまとめます。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。


コメント