web-dev-qa-db-ja.com

ユーザーが既にChromeのホーム画面にPWAをインストールしているかどうかを確認しますか?

Chromeのドキュメント で説明されているように、プログレッシブWebアプリに[ホーム画面に追加]ボタンを作成しようとしています。

通常は、Chromeのbeforeinstallpromptイベントが発生したときに表示されるいくつかの非表示ボタンがある所定のパターンに従っています。イベントが発生したらキャプチャし、イベントを使用して、独自のインストールボタンがクリックされたらネイティブインストールダイアログを開始します。サンプルコードは次のとおりです。

_let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the Prompt
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;
  // Update UI notify the user they can add to home screen
  btnAdd.style.display = 'block';
});

btnAdd.addEventListener('click', (e) => {
  // hide our user interface that shows our A2HS button
  btnAdd.style.display = 'none';
  // Show the Prompt
  deferredPrompt.Prompt();
  // Wait for the user to respond to the Prompt
  deferredPrompt.userChoice
    .then((choiceResult) => {
      if (choiceResult.outcome === 'accepted') {
        console.log('User accepted the A2HS Prompt');
      } else {
        console.log('User dismissed the A2HS Prompt');
      }
      deferredPrompt = null;
    });
});
_

実行中の問題は、ユーザーが既にホーム画面にWebアプリをインストールしている場合、インストールボタン(btnAdd)を表示したくなく、その方法がわからないことです。そのシナリオを確認します。

上記のコードを次のように変更したいと思っていました。

_window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the Prompt
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;

  // If the user has not already installed...
  deferredPrompt.userChoice
    .then(choiceResult => {
      if (choiceResult === undefined) {
        // Update UI notify the user they can add to home screen
        btnAdd.style.display = 'block';
      }
    });
});
_

そのため、ユーザーが既にインストールしている場合、インストールボタンは表示されません。しかし、これはうまくいかないようです。まだ選択していない場合は、userChoiceにアクセスすると、ユーザーにネイティブダイアログが直接表示されます。

beforeinstalleventがどのように機能するのかはよく分からないので、これは良い戦略でさえないかもしれません。理想的には、これがnavigator.serviceWorker.ready()のようなもので動作することを望んでいました。これは、ブラウザイベントを使用して、準備ができたときに判断するのではなく、Promiseを返します。

いずれにせよ、ホーム画面のインストールボタンを表示する前に、ユーザーがホーム画面にインストールしたことを確認する方法についてのアイデアはありますか?

Edit:Mathiasがコメントしているように、ボタンを表示する前にイベントをチェックするだけで十分です。私が抱えていた問題は、ローカルホストを使用した結果であると考えています。ローカルホストは、インストール後もbeforeinstallpromptイベントを継続的に発生させるようです。コードをホストすることで問題が解決しました。

15
David Scales

おそらく、自動ポップアップをインターセプトするまでボタンを表示しないでください。

または
コードで、ウィンドウがスタンドアロンかどうかを確認します
そうであれば、ボタンを表示する必要はありません

if (window.matchMedia('(display-mode: standalone)').matches) {  
    // do things here  
    // set a variable to be used when calling something  
    // e.g. call Google Analytics to track standalone use   
}  

私のサンプルテスターはこちら
https://a2hs.glitch.me

テスターのソースコード
https://github.com/ng-chicago/AddToHomeScreen

13
Mathias