英文:
Blazor Serverside does not trigger Install PWA dialogue on mobile?
问题
"Install PWA"对话框为什么不显示?
是否可能在应用程序未安装的情况下自动显示这样的对话框?如果可能的话,要如何实现?
"Install PWA"对话框不显示可能有多种原因,需要进一步检查。要自动在应用程序未安装的情况下显示该对话框,您需要执行以下步骤:
-
确保您的Web应用已经正确地配置为支持渐进式Web应用(Progressive Web App,PWA)。这包括在manifest.json文件中提供相关信息,如应用的名称、图标和其他属性。
-
确保Service Worker已经正确注册和激活。Service Worker负责在后台处理PWA的缓存和其他任务。检查Service Worker的JavaScript文件是否正确,确保它没有错误。
-
在代码中,您似乎有一个
onBtnInstallClick
方法,该方法调用BlazorPWA.installPWA
。确保此方法在按钮单击时正确触发,并且没有任何错误发生。 -
在某些情况下,浏览器可能不会自动显示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();
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论