Blazor Serverside在移动设备上不触发PWA安装对话框。

huangapple go评论54阅读模式
英文:

Blazor Serverside does not trigger Install PWA dialogue on mobile?

问题

"Install PWA"对话框为什么不显示?
是否可能在应用程序未安装的情况下自动显示这样的对话框?如果可能的话,要如何实现?

"Install PWA"对话框不显示可能有多种原因,需要进一步检查。要自动在应用程序未安装的情况下显示该对话框,您需要执行以下步骤:

  1. 确保您的Web应用已经正确地配置为支持渐进式Web应用(Progressive Web App,PWA)。这包括在manifest.json文件中提供相关信息,如应用的名称、图标和其他属性。

  2. 确保Service Worker已经正确注册和激活。Service Worker负责在后台处理PWA的缓存和其他任务。检查Service Worker的JavaScript文件是否正确,确保它没有错误。

  3. 在代码中,您似乎有一个onBtnInstallClick方法,该方法调用BlazorPWA.installPWA。确保此方法在按钮单击时正确触发,并且没有任何错误发生。

  4. 在某些情况下,浏览器可能不会自动显示PWA安装对话框。这可能取决于浏览器的策略和用户的交互。您可以尝试在onBtnInstallClick方法中添加逻辑,以检查应用是否已安装,并根据情况来触发安装对话框。这需要根据浏览器的不同来执行不同的操作。

请检查以上步骤,确保您的PWA配置正确,并且代码中没有错误,以确保"Install PWA"对话框可以按预期显示。如果问题仍然存在,您可能需要更详细地调查浏览器控制台中的任何错误消息,以了解问题的根本原因。

英文:

Trying to auto trigger or at least trigger with a in-application UI element ( a button ) the installation dialogue. Yet, due some reason it doesn't triggers at all, and there is nothing specific in the Chrome's console.

the manifest.json:

{
   "name": "IRIS Application",
   "short_name": "IRIS ",
   "description": "Shows the state of IRIS panels",
   "start_url": "/",
   "scope": "/",
   "display": "standalone",
   "background_color": "#ffffff",
   "theme_color": "#03173d",
   "prefer_related_applications": false,
   "icons": [
      {
         "src": "icon-48.png",
         "sizes": "48x48",
         "type": "image/png"
      },
      {
         "src": "icon-72.png",
         "sizes": "72x72",
         "type": "image/png"
      },
      {
         "src": "icon-96.png",
         "sizes": "96x96",
         "type": "image/png"
      },
      {
         "src": "icon-144.png",
         "sizes": "144x144",
         "type": "image/png"
      },
      {
         "src": "icon-192.png",
         "type": "image/png",
         "sizes": "192x192"
      },
      {
         "src": "icon-512.png",
         "type": "image/png",
         "sizes": "512x512"
      }
   ]
}

ServiceWorkerRegister.js:

const serviceWorkerFileName = '/ServiceWorker.js';
const swInstalledEvent = 'installed';
const staticCachePrefix = 'blazor-cache-v';
const updateAlertMessage = 'Update available. Reload the page when convenient.';
const blazorAssembly = 'Teletek';
const blazorInstallMethod = 'PWAInstallable';
window.updateAvailable = new Promise(function (resolve, reject) {
    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register(serviceWorkerFileName)
            .then(function (registration) {
                console.log('Registration successful, scope is:', registration.scope);
                registration.onupdatefound = () => {
                    const installingWorker = registration.installing;
                    installingWorker.onstatechange = () => {
                        switch (installingWorker.state) {
                            case swInstalledEvent:
                                if (navigator.serviceWorker.controller) {
                                    resolve(true);
                                } else {
                                    resolve(false);
                                }
                                break;
                            default:
                        }
                    };
                };
            })
            .catch(error =>
                console.log('Service worker registration failed, error:', error));
    }
});
window[ 'updateAvailable' ]
    .then(isAvailable => {
        if (isAvailable) {
            alert(updateAlertMessage);
        }
    });


function showAddToHomeScreen() {
    DotNet.invokeMethodAsync(blazorAssembly, blazorInstallMethod)
        .then(function () { }, function (er) { setTimeout(showAddToHomeScreen, 1000); });
}

window.triggerInstall = function ()
{
    showAddToHomeScreen();
};

window.BlazorPWA = {
    installPWA: function () {
        if (window.PWADeferredPrompt) {
            window.PWADeferredPrompt.prompt();
            window.PWADeferredPrompt.userChoice
                .then(function (choiceResult) {
                    window.PWADeferredPrompt = null;
                });
        }
    }
};

ServiceWorker.js:

self.addEventListener('fetch', () => { });

_Layout.cshtml:

@using Microsoft.AspNetCore.Components.Web
@namespace TeletekServer.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="~/" />
    <link href="manifest.json" rel="manifest" />
    <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
    <link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
    <link href="IRIS.styles.css" rel="stylesheet" />
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
    <link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
    <script src="_content/MudBlazor/MudBlazor.min.js"></script>

    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
    @RenderBody()

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>

    <script src="_framework/blazor.server.js"></script>
    <script src="ServiceWorkerRegister.js"></script>
</body>
</html>

index.razor:

@page "/"

@using MudBlazor

@inject IJSRuntime jSRuntime

<PageTitle>IRIS Server</PageTitle>
<div id="imgDiv">

    <img src="/logo.png" width="70%" height="15%" />
    <br />
    
</div>
<br />
<div id="btnDiv">
    <MudButton ButtonType="ButtonType.Button" Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto" OnClick="onBtnInstallClick">Install</MudButton>
</div>
@code
{
    public async void onBtnInstallClick( MouseEventArgs e )
    {
        
        await jSRuntime.InvokeVoidAsync( "BlazorPWA.installPWA" );
    }
}

<style>
    #imgDiv {
        display: flex;
        justify-content: center;
    }

    #btnDiv {
        display: flex;
        justify-content: center;
    }
</style>
  • Why the "Install PWA" dialogue does not appears ?
  • It is possible to auto appear such a dialogue if the application is not installed ?, and "how?" if it is possible.

答案1

得分: 1

你的Blazor调用JS调用BlazorPWA.installPWA,然后应该使用存储的PWADeferredPrompt来要求用户安装...

然而,你从未将任何内容存储为PWADeferredPrompt

在这种情况下,PWADeferredPrompt应该是传递给窗口beforeinstallprompt事件处理程序的事件实例。

你缺少这段代码,或者类似的代码:

window.addEventListener('beforeinstallprompt', function (e) {
    // Prevent Chrome 67 and earlier from automatically showing the prompt
    e.preventDefault();
    // Stash the event so it can be triggered later.
    window.PWADeferredPrompt = e;

    showAddToHomeScreen();

});
英文:

Your call from Blazor to JS calls BlazorPWA.installPWA which should then use the stored PWADeferredPrompt to ask the user to install...

However, you never store anything as PWADeferredPrompt.

PWADeferredPrompt in this case should be the event instance passed to the handler for the beforeinstallprompt event of the window.

You are missing this code - or a variant of it:

window.addEventListener('beforeinstallprompt', function (e) {
    // Prevent Chrome 67 and earlier from automatically showing the prompt
    e.preventDefault();
    // Stash the event so it can be triggered later.
    window.PWADeferredPrompt = e;

    showAddToHomeScreen();

});

huangapple
  • 本文由 发表于 2023年5月15日 02:38:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76249120.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定