【実験】iOS16.4_PWAで「ローカル通知」はできるのか!?【結果あり】
【2023/05/17 追記】
本記事の内容で PWA Night でLT登壇しました!
スライドは以下のツイートで公開しました。
どうも、こんにちは。たまには技術者らしい記事を書くNeji(ねじ)です。
本日のテーマ:iPhoneのPWAで「ローカル通知」を送信したい
はじめに
本日参加した PWA Night のオンラインイベントにインスピレーションを受け、この調査をしました。感謝!
あらまし
Webエンジニアのみなさん、こんにちは。
2023年3月、iOS16.4 がリリースされましたね!
これにより、iPhoneにインストールしたPWAが「プッシュ通知」を扱えるようになりました!
通知、大事ですよね。ユーザーに「アプリを開いてね」と声掛けできる。
ところで「通知」って、2種類ありますよね。
※以下、用語が正確である保障はありません。あくまで本ドキュメントの中のものとして使わせて頂きます。
【通知の種類】
プッシュ通知(Webプッシュ)
アプリの運営組織が、世界中のユーザーに向けて送る通知。
ローカル通知
デバイス(例えばiPhone)1台の中で発生し表示される通知。
iOS16.4でいろいろ技術検証をされている技術者はたくさんいらっしゃって(日々感謝)、通知に関しては「プッシュ通知、動いた!」系の記事が多いです。
あれ?ローカル通知って需要ないのかな?
……これは、確認しないと。
課題(確認したいこと)
iOS16.4の「PWAが通知に対応」の結果、ローカル通知は扱えるんだろうか?
本日、こちらの検証をしてみたので、内容をココに整理いたします。
結論:
動いた!が、不都合な挙動があり「このままだと使えない」
そもそも、どんなことがしたかった?
iPhoneで使えるToDoアプリを作りたかった。
ToDoアプリには、リマインダー(予定の10分前ですよ!)をつけたい。
PWAでこれができるのか、知りたい!
確認方法:
「実験用の小さなPWA」を作成し、ローカル通知を飛ばすことの出来るいくつかの方法を実装しました。
作成した検証ページ
https://neji-bit.github.io/pages/
GithubPages。実際にアクセス可能です。
ソースコードはこちら。https://github.com/Neji-bit/pages
また手持ちの以下の環境で、それぞれ挙動を確認しました。
iPhone(iPhone 12 mini, iOS16.4):本命の調査対象
MacBook:挙動の比較用
Chrome
Safari
PWAのインストール等については以下の記事に丁寧にまとめられています。(まぁし様記事)
実験メニュー
今回は、以下の内容を確認しました。
実験1:iPhoneのPWAからローカル通知は飛ばせるか?
実験2:ローカル通知を飛ばせる状態/飛ばせない状態の確認
それぞれの内容と結果を、以下にまとめます。
実験1: iPhoneのPWAからローカル通知は飛ばせるか?
結論:できました。
できる=「ユーザーがPWAを開いている状況で、iPhoneで通知を表示することができる」。
実験した通知の方法3点
今回は、以下の3つのコードを試しました。
※コードの詳細は、Githubをご参照下さい。
A: サイト上のJavaScript(=サービスワーカーではない)で "new Notification"。
B: サービスワーカーを呼び出し "showNotification"。
C: サービスワーカーでタイマーを仕掛け、10秒後に "showNotification"。
結果詳細
iPhoneのPWAで確認: A: 動かない / B: 動いた / C: 動いた
MacBookのChromeで確認: A: 動いた / B: 動いた / C: 動いた
MacBookのSafariで確認: A: 動いた / B: 動いた / C: 動いた
考察/備考
通知を発生させる際は、サービスワーカーの showNotification で行うのが良い。
iPhoneの通知では、バイブレーションは動かなかった。
最初に「通知の許可を得る(Notification.requestPermission())」ステップが必要だが、iPhoneではこれを「window.onload()」の中で実施することは出来ない。ユーザーの操作(ボタンクリックなど)に紐づく形で行うこと。(MacBookのブラウザ2件では、window.onload()で処理できた)
実験2:ローカル通知を飛ばせる状態/飛ばせない状態の確認
結論:残念!PWAをバックグラウンドに回すと「ローカル通知を飛ばす役のヒト(=サービスワーカー)が動けない」ため飛ばせない
確認内容
コードは、上記の検証ページを引き続き使い、「ボタンを押して10秒後に通知が飛ぶ」機能を使いました。
検証環境も同じ3種類です。
「確認する状態」は、以下の3つになります。
A: ブラウザを開き、ユーザーが操作している状態
B: ブラウザを開き、画面外に送った状態(=別のアプリを操作している)
C: 検証ページを開いているブラウザを、閉じる。(プロセス終了)
結果詳細
iPhoneのPWA で確認
A: 通知が表示される
B: 通知は「10秒後には飛ばない」(重要)
C: 通知は出ない
MacBookの Chrome および Safari で確認
A: 通知が表示される
B: 通知が表示される
C: 通知は出ない
iPhoneの「10秒後には飛ばない」について
ボタン押下後すぐにPWAをバックグラウンドに送ると、10秒後には通知は飛ばなかった。
その後、検証ページPWAを再度開くと、そのタイミングで通知が飛ぶ。
また、10秒以内に「なんでもいいから他のPWA」を開いていた場合、なんと通知は飛んでくる。
考察/備考
iPhoneのPWAサービスワーカーは、PWAがバックグラウンドに回ると「休止状態」になる。
「さくらのナレッジ」さん等で書かれている通り。
だからサービスワーカーのコード内に記載された「showNotification」を実行することができない。
iPhoneの内部では、複数のPWAは「ひとまとめ」でサービスワーカーが動かされている?ような挙動。
結論と希望
今回の検証の結果、以下がわかりました。
iPhoneのPWAにおいて、「通知」に期待する「アプリを閉じているユーザーに声をかける」挙動は、現在のローカル通知ではできない。
iPhoneでPWAを利用中のユーザーに通知を表示させることはできる。
それだと、ダイアログ表示とさして変わらないか。。
今後の希望として「iPhoneで、バックグラウンドに回ったPWAのサービスワーカーをタイマーで起こす方法」がなにかないか、探したいと思います。
なにか、ネイティブ機能などを利用してバックグラウンドでのタイマー処理、できないものか。なんならネイティブ機能に「10分後にローカル通知を出して!」を依頼できるなら、それで良い。
将来、いつかはできるようになると思うのだが。。
なんなら「PWAとデータ連携してローカル通知を出すだけ」のアプリを作ってリリースしたら、いろいろ便利になるのだろうか?
……それはそれで、面白そうw
最後に
ここまで読んで頂き、ありがとうございました。
PWA、iPhoneアプリ共に、私の経験値は「これから何か作ってみたい!」程度です。
「まずこれを読んでおくといいよ」「ここで試していない方法でソレ出来るよ」等の情報を頂けると、飛んで喜びます。ご存知の方、ぜひコメント頂けますようお願いいたします。
本日は、以上です。
この記事が気に入ったらサポートをしてみませんか?