La parte più difficile della navigazione web non era la mappa. Era il telefono.
Pensavo che “scansiona un QR code e cammina” fosse la versione facile della navigazione. Poi ho provato a farla funzionare su browser mobile reali, con rumore GPS reale, e con persone reali a cui non importa perché il puntino sta teleportando.
Ho costruito una mappa. Poi ho provato a farle guidare qualcuno.
L’idea iniziale era quasi noiosa: una mappa web che si apre al volo. Niente installazioni. Niente account. Niente drama da App Store. Scansioni un QR code, vedi il percorso, inizi a camminare.
Quella parte funzionava. Una mappa web è ingegneria già risolta. Le tile si caricano. I marker compaiono. I percorsi disegnano linee pulite. La gente sorride. Poi qualcuno fa la domanda ovvia: “Ma naviga?” Non “mostra un percorso.” Naviga. Cioè: tieni il puntino blu in movimento, mantieni la direzione stabile, e non mentire quando sei nel torto.
Ho detto sì. Non perché fosse facile, ma perché non avevo ancora capito cosa significhi davvero “navigazione” sul web mobile.
Il GPS non è un puntino. È una stima che si muove, con un raggio di fiducia.
La prima volta che guardi un utente reale camminare con una navigazione nel browser, smetti di credere alle demo pulite. Il puntino entra nei palazzi. Si ferma agli incroci come se stesse pensando. Salta sulla strada parallela. A volte gira su sé stesso, come se la mappa cercasse di evocare la direzione a sentimento.
Niente di tutto questo è un “bug” nel senso che lo sistemi con un loop migliore. La Geolocation API è chiara su cosa è e cosa non è: ricevi dati di posizione, ma non c’è nessuna promessa che sia la “posizione reale” del dispositivo. L’API non dice da quali segnali arrivano i dati, e la precisione dipende da cosa il telefono e il sistema operativo riescono a offrire in quel momento. In indoor, in un “canyon urbano”, vicino a vetri riflettenti, o in una strada affollata, stai combattendo la fisica più del codice.
Quando lo accetti, smetti di trattare ogni aggiornamento come verità. Lo tratti come un flusso rumoroso. Guardi i timestamp. Guardi l’accuratezza. Dai per scontato che ogni tanto sarà sbagliato, e progetti di conseguenza.
Se la tua interfaccia si comporta come se il GPS fosse certo, i tuoi utenti impareranno a non fidarsi più.
È qui che ho iniziato ad aggiungere le funzioni poco glamour che fanno sembrare la navigazione “vera”: uno stato chiaro tipo “GPS debole”, uno smoothing che non nasconde i salti grossi, e una logica che si rifiuta di reagire troppo a un singolo aggiornamento pessimo. L’obiettivo non era l’inseguimento perfetto. Era un inseguimento onesto.
Il problema iPhone: permessi, sensori, e la realtà di WebKit.
Android mi dava problemi normali: precisione variabile, comportamenti diversi da dispositivo a dispositivo, ottimizzazioni batteria, e qualche stranezza occasionale. iPhone mi ha dato un’altra categoria di dolore: regole che cambiano in base al gesto, al contesto, e a qualunque cosa Safari abbia deciso che oggi è “sicura”.
Partiamo dai permessi. La Geolocation API richiede l’autorizzazione dell’utente, e in teoria è semplice: chiedi una volta, poi o sei autorizzato o non lo sei. In pratica, su iOS può diventare imprevedibile. Persino nei forum ufficiali Apple trovi sviluppatori che chiamano i permessi di geolocalizzazione in Safari “un incubo”, perché lo stato può restare su “prompt” in vari casi e non si mappa bene su come vorresti gestire la UX.
Poi c’è la direzione. La vera guida “turn-by-turn” vuole una direzione stabile. Sul web di solito usi eventi di movimento/orientamento e costruisci una bussola. Ma i browser moderni bloccano l’accesso ai dati di movimento e orientamento dietro flussi di permesso espliciti, e su iOS spesso devi attivare la richiesta con un’interazione dell’utente. Sembra ragionevole finché non provi a costruire un flusso che non sembri un percorso a ostacoli fatto di pop-up. E lo standard è chiaro: la specifica sull’orientamento del dispositivo richiede un permesso esplicito tramite chiamate in stile requestPermission().
Infine c’è il fatto scomodo che nessuno vuole sentire: su iOS la “diversità” dei browser è limitata nella pratica, perché WebKit è stato storicamente il motore richiesto per i browser su iOS. Quindi se Safari fatica su qualcosa, “prova Chrome” non ti salva per forza, perché stai ancora vivendo dentro gli stessi vincoli del motore. Apple ha iniziato a supportare motori alternativi nell’UE in condizioni specifiche, ma non puoi costruire un prodotto dando per scontato che ogni utente benefici già di quel cambiamento.
Questa è la parte in cui ti dicono “basta implementarlo correttamente”, come se il codice corretto potesse scavalcare le policy di piattaforma. Non può. Finisci per costruire una navigazione che è metà ingegneria e metà negoziazione con iOS.
Quando lo schermo si addormenta, la navigazione muore.
Il bug più brutale non era un crash. Era il silenzio. Un utente inizia a camminare. Tutto si aggiorna. Poi lo schermo si attenua, oppure passa a un’altra app, oppure il dispositivo decide che la pagina è “inattiva”. All’improvviso il tuo loop fluido smette di ricevere aggiornamenti, i timer sballano, e tu resti lì a far finta che non sia successo niente.
Se fai un passo indietro, non è sorprendente. iOS è progettato per sospendere il lavoro in background, a meno che tu non sia un’app nativa con una modalità di esecuzione in background specifica. La documentazione Apple è abbastanza diretta: le app di solito vengono sospese in background e le modalità consentite sono limitate. Una pagina web non vincerà quella battaglia.
Quindi provi workaround. Riduci la frequenza degli update. Re-inizializzi watchPosition() quando l’app torna in primo piano. Rilevi la “stale-ness” controllando i timestamp. Mostri un banner che dice “tieni lo schermo acceso per la navigazione live”, perché quella è la verità anche se sembra una regressione.
Poi guardi la Screen Wake Lock API. In teoria è esattamente quello che ti serve: mantenere lo schermo acceso durante la navigazione. Esiste per questo tipo di scenario. In pratica, il supporto è stato irregolare tra versioni e modalità, e le web app “installate” hanno avuto le loro stranezze e bug, inclusi report WebKit in cui il wake lock funziona in Safari ma fallisce quando lo stesso sito è aggiunto alla schermata Home. Ed è esattamente questo genere di caso limite che rende la navigazione web mobile un progetto artigianale, non una spunta su una checklist.
Cosa ha finalmente reso tutto più affidabile
Ho smesso di inseguire la “navigazione perfetta” e ho iniziato a consegnare un sistema che si comporta come una guida prudente. Non va nel panico. Non promette troppo. Continua ad andare avanti, ma ti dice quando gli input sono deboli.
I cambiamenti che hanno contato non erano esotici. Erano pratici:
- Tratta la posizione come un flusso, non come una verità. Smussa il rumore piccolo, ma non nascondere i salti grossi.
- Usa accuratezza e timestamp. Se l’ultimo fix è vecchio o “largo”, dillo.
- Progetta una modalità “segnale debole” che aiuta comunque: mostra il percorso, mostra il prossimo punto di riferimento, smetti di fingere che il puntino sia preciso.
- Chiedi i permessi dei sensori in un momento pulito, attivato da un’azione deliberata dell’utente, non da un loop di modali a sorpresa.
- Pianifica il sonno. Dai per scontato che il dispositivo metterà in pausa la pagina e rendi il resume elegante.
- Usa il wake lock quando disponibile, e metti un fallback chiaro quando non lo è.
Il risultato finale non è magia. È qualcosa di meglio: è prevedibile (più o meno). Gli utenti perdonano la deriva se la tua app resta coerente. Non perdonano una UI che punta con sicurezza nella direzione sbagliata.
E sì: iPhone è stata la piattaforma più difficile per questo. Non perché sia “hardware scadente”, ma perché il web mobile su iOS ha barriere più rigide, un comportamento in background meno indulgente e meno vie di fuga (e lo odio!). Una volta che accetti quei vincoli (io non l’ho fatto), puoi costruire qualcosa di onesto che funziona la maggior parte del tempo e fallisce in un modo che non insulta l’intelligenza dell’utente (io invece la insulterò!).
Windsurf
All my projects and even this website is build using Windsurf Editor. Windsurf is the most intuitive AI coding experience, built to keep you and your team in flow.
Contattaci
Se ti serve uno sviluppatore che consegna soluzioni veloci, affidabili e pratiche, contattami. Trasformiamo insieme la tua idea o il tuo progetto in qualcosa che funziona davvero.