iOSエンジニアだけが知っているGmailのなにげないすごさ
はじめに
Gmailは太古の昔からモバイルアプリも提供されており、高い完成度を誇っている。
iOSエンジニアしか気づかないすごいポイントがあるので紹介したい。
Gmailアプリのすごさ
Gmailアプリのすごさは、メールをiPhoneで受信したあとの挙動にある。
普通に通知が届く

他の端末でメールを既読にすると、通知センターから通知が消える

どこがすごいのかわからないですよね
プッシュ通知は世の中の多くのアプリで利用されているけど
そのほとんどは プッシュ通知を送りっぱなしで、ユーザーが通知をタップするか手動で消すまで残り続ける。
通知が「他デバイスの操作」によってリアルタイムに更新される仕組みは作れるけどほとんど実装されてない。
これシンプルに見えて実はかなり難易度が高い。
一般的なプッシュ通知の仕組み
まずは普通の通知の流れから。
iOSアプリでプッシュ通知を受け取るには、
Appleの APNs(Apple Push Notification service) を使う。
- サーバーがイベント(例: 新着メール)を検知
- APNsに通知リクエストを送信
- APNsがiPhoneに通知を配信
- 通知センターに表示される
ここまではごく一般的な話。
Gmailアプリがやっていること
APNsは基本的にサーバー→APNS→アプリへの一方通行の通信であり、
APNsに対して 「この通知を消してほしい」 というリクエストを送ることはできない。
iOSアプリになんらかの方法でリアルタイムにデータを渡して、アプリ側から通知を消す処理を実装する必要がある。
データを渡すやり方が単純なPub/Subだと アプリが起動していない or バックグラウンドにいる ケースに対応できないので、サイレントプッシュ※を使う必要がある。
そのためにGmailアプリは以下のような仕組みを実装していると考えられる。
- 他の端末でメールが既読になる
- Googleのサーバーがそのイベントを検知
- サイレントプッシュ(content-available) で、既読になったメッセージIDをiPhoneアプリに送信
- アプリがバックグラウンドで受信し、
UIApplicationDelegateのapplication(_:didReceiveRemoteNotification:fetchCompletionHandler:)で処理を開始 -
UNUserNotificationCenterのgetDeliveredNotifications()を使って通知一覧を取得 - 対応するメッセージIDの通知を特定し、
removeDeliveredNotifications(withIdentifiers:)で削除
なぜほとんどの会社がやらないのか
- 通知センターからプッシュ通知を消すためだけにバックエンドとiOSアプリの両方で実装が必要
- ちゃんと実現しようとするとiOS以外との複数プラットフォームとも同期が必要になることが多い(Android、Webなど)
大変なわりに通知センターから通知が消えるだけだから。
そんなわけで多くのアプリではこのような仕組みは後回しにされることが多く、プロダクトバックログの下の方で眠っている。自分も仕事で作ったことはない。
おわりに
こういうなにげないところまでユーザー体験を高めるために手間をかけているGmailアプリはやはりすごいなーと思う次第。
コアな機能・ユーザー体験に向き合っていくぜという強い意思を感じる。Gmailアプリはそういう意味でやはり高みにあるなーと。さすGoogleである。
Discussion