Come il titolo ci fa intendere, lo scopo di questo script è riuscire ad installare una PWA Blazor. Perché sì, per ottenere una PWA è sufficiente una spunta all'interno di una check-box al momento della creazione del progetto, ma per riuscire a mostrare all'utente la possibilità di installazione, abbiamo bisogno di scrivere vari passaggi: partendo dall'intercettazione dell'evento di installazione, alla proposizione all'utente, fino al salvataggio della risposta alla domanda "Vuoi installare l'applicazione?".
La condizione di partenza è un progetto PWA ready: con Visual Studio all'interno del wizard di creazione si può spuntare la casella appropriata, oppure da linea di comando è necessario aggiungere l'argomento --pwa
dotnet new blazorwasm -o mia-app --pwa
L'applicazione Blazor avrà dunque un file manifest.json, contenente il nome, descrizione, metadati e il rifiremento alle icone; ed un service worker: un insieme di processi gestiti direttamente dal browser, che gestiscono, tra le altre, notifiche, cache e i processi di installazione della PWA sul dispositivo.
Mettiamo ora mano al codice, partendo dal javascript, sottoscrivendoci all'emissione di un evento che informa riguardo la possibilità di installazione, che salveremo all'inteno di una variabile, per poterlo poi utilizzare in un secondo momento, quando l'utente avrà confermato la volontà di installare l'applicazione.
if ('serviceWorker' in navigator) { window.addEventListener('beforeinstallprompt', function (e) { e.preventDefault(); window.PWADeferredPrompt = e; // il timeout è necessario per poter dare a Blazor il tempo necessario per l'inizializzazione setTimeout(function () { if (localStorage.getItem('skipInstall') != "true") { DotNet.invokeMethod("MiaApplicazione.Blazor", "BlazorInstallHandler"); } }, 3000); }); } window.BlazorPWA = (function () { return { dismissInstallPWA: function () { localStorage.setItem('skipInstall', "true"); }, installPWA: function () { localStorage.setItem('skipInstall', "true"); if (window.PWADeferredPrompt) { // Use the stashed event to continue the install process window.PWADeferredPrompt.prompt(); window.PWADeferredPrompt.userChoice .then(function (choiceResult) { window.PWADeferredPrompt = null; }); } } } })();
La funzione BlazorInstallHandler, per poter essere chiamata tramite JSInterop, deve essere statica, il che può essere un problema, dato che a seguito dell'esecuzione dovremo modificare lo stato dell'interfaccia. Per questo motivo, in MainLayout.razor, creiamo e configuriamo una Action, che ci permetterà di chiamare funzioni non statiche del componente.
@inject IJSRuntime jsRuntime <div class="page @CurrentTheme"> <div class="sidebar"> <NavMenu /> </div> <main> <div class="top-row px-4"> <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> </div> @if (showInstallButton) { <button class="btn btn-primary" @onclick="@(() => HideInstallButton(true))">Si</button> <button class="btn btn-primary" @onclick="@(() => HideInstallButton(false))">No</button> } <article class="content px-4"> @Body </article> </main> </div> @code{ bool showInstallButton = false; private static Action action; protected override async Task OnInitializedAsync() { // associazione action action = ShowInstallModal; await base.OnInitializedAsync(); } [JSInvokable] public static Task BlazorInstallHandler() { action.Invoke(); return Task.CompletedTask; } public void ShowInstallModal() { showInstallButton = true; // richiediamo il refresh del componente this.StateHasChanged(); } private async Task HideInstallButton(bool choice) { if (choice) { await jsRuntime.InvokeVoidAsync("BlazorPWA.installPWA"); } else { await jsRuntime.InvokeVoidAsync("BlazorPWA.dismissInstallPWA"); } showInstallButton = false; } }
A seconda del bottone premuto chiameremo nuovamente il codice javascript che attiverà l'evento o salverà la volontà dell'utente di non voler installare l'applicazione, in modo che al refresh della pagina non riapparirà nuovamente la scelta.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Sviluppare applicazioni serverless con Azure Container Apps
Gestire la query string nell'output cache di ASP.NET Core
Utilizzare la keyword with in JavaScript
Specificare il numero di parentesi graffe nella string interpolation in combinazione con i string literal in C#
Monitorare metriche delle risorse Azure con Load Testing
Q# for Quantum Programming, an "only for the brave" session
Effettuare test di carico con Azure Load Testing
Usare gateway dedicati con Azure Cosmos DB per migliorare le prestazioni
Chiamare un endpoint ASP.NET Core protetto da Certificate Authentication
Usare il throttling per limitare la frequenza degli eventi in Blazor
Scrivere CSS Media Query utilizzando una range syntax
Ottenere il riferimento alla finestra che ha aperto un'altra finestra con HTML5 e JavaScript
I più letti di oggi
- Taggare la output cache in base al routing in ASP.NET Core
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- .NET Conference Italia 2022 - Milano e Online
- Silverlight su mobile: Nokia
- Visual Studio 2010 e .NET Framework 4.0: beta 2 e data di release RTM
- Anteprima del Service Pack 1 di WCF RIA Services: spunta il supporto all'italiano
- Disponibile al download la versione finale di Internet Explorer 9
- Windows Phone 'Mango' beta presto nei device ufficiali?