こんにちは。iOS エンジニアのもとにしです。iOS 版 LINE のバージョン 15.14.0 において、アプリ内通知をシステム通知で表示するようアップデートしました。
| 変更前 | 変更後 |
|---|---|
![]() | ![]() |
このように、これまでカスタムビューで表示していた通知が、iOS 標準の通知バナーで表示できるようになりました。
表示を変更するだけのシンプルな作業に思えましたが、開発を進めていく中で、想像以上に考慮すべきポイントが多いことに気づきました。この記事では、これまでの iOS や LINE アプリでの制限をふり返りつつ、移行の過程で向き合ったことや工夫した点を紹介します。
なぜこれまでカスタムビューが使われていたのか?
昔は OS による制限があった
iOS 9 まで、OS の制限により、アプリがフォアグラウンド状態のときに OS 標準のシステム通知を表示することはできませんでした。LINE アプリでは、フォアグラウンドでも通知バナーを表示するために、UIView で実装された独自バナーによりユーザー通知を表示していました(以降「カスタム通知」と呼びます)。カスタム通知の短所として、iOS の通知センターに表示されなかったり、下の画像のように他のアプリの通知とビューが被ってしまったりといった問題がありました。

iOS 10 でフォアグラウンドのシステム通知が解禁された
iOS 10 で登場した UserNotifications Framework により、ユーザー通知まわりの機能が刷新されました。それまでローカル通知に使われていた UILocalNotification が非推奨となり、以下の流れでローカル通知を登録できるようになりました。(事前に UNUserNotificationCenter.current().requestAuthorization() で通知の許可を取る必要があります。)
let content = UNMutableNotificationContent()
content.title = "Sample Title"
content.subtitle = "Sample Subtitle"
content.body = "Sample Body"
let request = UNNotificationRequest(
identifier: UUID().uuidString,
content: content,
trigger: nil
)
UNUserNotificationCenter.current().add(request)

さらに、フォアグラウンド状態でもシステム通知を表示することができるようになりました。以下のように UNUserNotificationCenterDelegate の関数を実装することで表示できます。
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
completionHandler([.banner, .sound, .badge])
}
LINE アプリでシステム通知への移行が遅れた理由
LINE アプリでは iOS 9 以前から、バックグラウンド時にはサーバーからのプッシュ通知を表示していました。ですので、UNUserNotificationCenterDelegate を実装するだけで、フォアグラウンド時に もプッシュ通知が表示され、システム通知への移行が完了するはずでした。しかし、LINE アプリでは、iOS 10 以降もカスタム通知が利用されてきました。いくつかの LINE 特有の問題により、プッシュ通知をフォアグラウンドで利用できなかったのです。
まず、これまで LINE ではアプリがフォアグラウンド状態のときにプッシュ通知を送っていませんでした。これはサーバーの負荷軽減のためであり、システム通知をフォアグラウンドでも表示するためにプッシュ通知を送ってもらうのは難しい状況でした。
また、フォアグラウンド状態でプッシュ通知を表示すると、別経路で更新されるトークリスト画面との整合性が取れなくなる可能性があるといった課題もありました。トークリストは Core Data で管理されており、プッシュ通知とは別の方法で同期されています。そのため、たとえばネットワークの問題などで、プッシュ通知が成功したのにトークリストの同期に失敗した場合、通知バナーが表示されるがトークリストにメッセージは来ていないという状態になってしまい、ユーザー体験を損なう懸念がありました。
以上の理由により、フォアグラウンドのカスタム通知をシステム通知に置き換えるには、ローカルでシステム通知を登録する処理を新たに加える必要があり、実装コストが大きかったのです。
今回は、遅ればせながら LINE アプリのカスタム通知をシステム通知に置き換える実装を行いました。基本的にはカスタム通知を表示している箇所をUNUserNotificationCenter.current().add(request) に置き換えるだけでしたが、その過程で工夫したこと、苦労したことを共有します。

