App Store審査を通過した後、次に取り組んだのが「記録し忘れを防ぐリマインダー通知」機能でした。毎日決まった時間に「今日の飲酒量を記録しましょう」と通知してくれる、ごく普通のローカル通知です。シンプルな機能だと思っていたのですが、実装してみると想像以上につまずくポイントが多かったので記録しておきます。
1. 通知の許可リクエストを起動直後に出して失敗した
最初、アプリを起動した直後にUNUserNotificationCenterの許可リクエストをいきなり出すようにしていました。
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
// 許可されたかどうか
}
しかし、アプリの中身も見せていない段階でいきなり「通知を送ってもいいですか?」と聞かれても、ユーザーはまず拒否します。実際、自分でテストしていても反射的に「許可しない」を押してしまっていました。
一度拒否されると、ユーザーは設定アプリから手動で許可し直さない限り、二度とダイアログは出てきません。今は、リマインダー機能の画面に遷移したタイミングで初めて許可を求めるように変更し、「なぜ通知が必要か」を一言添えるようにしました。
2. アプリを開いている間は通知が表示されなかった
許可も取れて通知の予約もできたのに、アプリを開いたまま待っていると通知バナーが出てこない、という現象に遭遇しました。
原因は、UNUserNotificationCenterDelegateを設定しておらず、フォアグラウンド(アプリを開いている状態)での通知表示方法を明示していなかったことでした。
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.banner, .sound])
}
このデリゲートメソッドを実装して初めて、アプリを開いている間もバナーが表示されるようになりました。バックグラウンドでは普通に通知が来ていたので、「実機で確認したのにアプリを開いてるときだけ来ない」という状態にしばらく混乱しました。
3. 繰り返し通知の間隔で審査に近いエラーに気づいた
「毎日20時に通知」をUNCalendarNotificationTriggerとrepeats: trueで実装したのですが、テスト用に「1分ごとに繰り返し」で動作確認しようとしたところ、意図通りに動きませんでした。
調べてみると、UNTimeIntervalNotificationTriggerでrepeats: trueを指定する場合、インターバルは60秒以上でなければならない、という制約がありました。60秒未満を指定してもエラーにはならず、静かに無視されるだけだったので、原因に気づくまで時間がかかりました。
// NG: repeats: true なのに60秒未満は無視される
UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: true)
// OK
UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
日次のリマインダー自体はUNCalendarNotificationTrigger(時刻指定)を使えば問題なかったのですが、デバッグ中に短い間隔でテストしようとして初めてこの制約にぶつかりました。
4. シミュレータでの通知テストに時間を使いすぎた
実機がすぐ手元にない時間帯は、シミュレータで動作確認をしていました。基本的にはシミュレータでもローカル通知は動作するのですが、通知センターの挙動が実機と微妙に異なる場面があり、「シミュレータでは来ないのに実機では来る(もしくはその逆)」という状態に何度か遭遇しました。
最終的には、ロジックの確認はシミュレータで素早く行い、実際の通知の見え方・タイミングの最終確認は必ず実機で行う、という役割分担に落ち着きました。
まとめ
- 通知の許可リクエストは起動直後ではなく、必要性が伝わるタイミングで出す
- フォアグラウンド中に通知を表示するには
UNUserNotificationCenterDelegateのwillPresent実装が必須 repeats: trueの繰り返し通知は間隔60秒未満だと静かに無視される- シミュレータと実機で通知の挙動が微妙に異なることがあるので、最終確認は実機で行う
「通知を送るだけ」のシンプルな機能のはずが、ユーザー体験に関わる部分(許可の取り方、表示タイミング)で思ったよりも配慮が必要だと実感しました。同じようにローカル通知を実装しようとしている方の参考になれば幸いです。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。

コメント