Как перехватить приглашение установки приложения в Angular PWA?

Я создал PWA, используя Angular Guidelines. У меня проблема с перехватом баннера установки приложения. Я использую этот код, чтобы отложить его на более поздний момент:

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;
  console.log("Intercepting the app install banner prompt");

  setTimeout(function() {
    deferredPrompt.prompt();
  }, 20000);

  // 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;
  });
});

Мой файл манифеста:

{
  "name": "TreadWill",
  "short_name": "TreadWill",
  "theme_color": "#2a3b3d",
  "background_color": "#2a3b3d",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

Когда я пробую этот код в localhost, сообщение, включенное в console.log, регистрируется, но через 20 секунд я получаю сообщение об ошибке:

Uncaught (in promise) DOMException

в этой строке:

deferredPrompt.prompt();

Когда я размещаю код и пробую его на мобильном устройстве, баннер установки приложения отображается мгновенно, а не через 20 секунд.

Я попытался поместить этот код в сам файл index.html, в отдельный файл js и вызвать его в файле index.html. Создание сервиса и включение почти аналогичного кода в файл.ts. Ничего не сработало. Хотя я пробую js решения из отчаяния, я бы предпочел угловые решения проблемы. В идеале я хотел бы перехватить и сохранить событие beforeinstallprompt в глобальной переменной и запросить событие в разных точках.

Как решить эту проблему?

2 ответа

Решение

Вы, вероятно, делаете это правильно, но согласно этой статье:
"Мини-информационная панель появится, когда сайт соответствует критериям добавления на домашний экран, независимо от того, используете ли вы предопределение Default() для события beforeinstallprompt или нет".
Так и для меня, это показывает сразу.

Пит ЛеПейдж (@petele) - хороший человек, чтобы следить за обновлениями A2HS в твиттере.

Вот тестер Add To Home Screen (A2HS), который я построил. Внизу страницы есть ссылка на исходный код. Не стесняйтесь использовать все, что может быть полезным. Я недавно не обновлял его до самой последней версии angular. Но все должно работать, так как это основной код.
https://a2hs.glitch.me/

Ссылки, приведенные в ответе Матиаса, помогли мне решить проблему. Я просто добавляю несколько моментов, которые явно не упомянуты в ответе, но могут помочь кому-то еще.

  • Баннер установки приложения может отображаться только на некоторых действиях пользователя. Например - нажатие кнопки. Это не может быть предложено через setTimeout.
  • В настоящее время перехват файла beforeinstallprompt и его последующее отображение работает в Chrome и Edge, поскольку Chrome и Edge запускают событие автоматически, когда пользователь посещает сайт. Firefox не запускает событие beforeinstallprompt и, следовательно, он не работает в Firefox.
Другие вопросы по тегам