TL;DR
"Fungerar offline" är fyra skilda beslut, och leverantörer levererar oftast ett av dem och kallar det klart. Här är vad vart och ett kostar, vad den här fältappen gör, och det enda ställe där den medvetet gör mindre än den skulle kunna — eftersom att göra mer skulle visa ett företags arbete för ett annat.
Först: det är en webbapp, inte en native app
Fältappen installeras från webbläsaren till hemskärmen. Den finns inte i App Store eller på Google Play.
Det är en verklig begränsning och värd att säga före allt annat. En webbapp på iOS kan inte läsa position i bakgrunden, kan inte använda varje sensor i telefonen, och är beroende av webbläsarmotorn under sig. Är kravet en native app är det här inte en.
Vad den ger i stället: en kodbas, ingen granskning i en butik mellan ett fel och dess rättelse, ingen installationsprocedur per enhet för ett säsongslag som byts ut i april, och en länk som fungerar på vilken telefon någon redan har. Den öppnar i helskärm i porträttläge och startar på uppdragsvyn i stället för på kontorsvyn.
Sedan: skalet cachas, data gör det inte
En service worker förcachar fyra saker: startdokumentet, ikonen och manifestet. Allt annat bygget producerar är innehållshashat och namngivet vid byggtid, vilket en handskriven worker inte kan känna till i förväg, så de filerna cachas allteftersom de efterfrågas. Det kostar ett besök med täckning innan appen öppnar utan, och varje fälttelefon har haft ett sådant när den når en kund.
Eftersom byggets filer är innehållshashade kan en cachad kopia aldrig vara fel version av någonting, så tillgångar serveras ur cachen och uppdateras i bakgrunden. En sidnavigering försöker nätet först — så att en driftsättning fångas upp — och faller tillbaka på det cachade skalet, vilket är det som får appen att öppna i en källare.
Sedan regeln som väger tyngre än varje cachestrategi: ingenting från API:et cachas någonsin.
Varje API-svar hör till en organisation och en inloggad användare. En cachad kopia överlever båda. Att servera gårdagens svar till någon som sedan dess bytt mellan två kontor — eller loggat ut, eller tagits bort ur företaget — skulle visa en kunds arbete för en annan, och det skulle göra det från ett lager som ingen mängd korrekt avgränsning på servern når.
Så för att vara ärlig om vad "offline" betyder här: appen öppnar utan täckning och allt personalen rapporterar läggs i kö. En kallstart utan uppkoppling ger dig appen, inte gårdagens uppdragslista. Det är en medveten avvägning, och säkerhetsskälet är hela motiveringen.
Det andra service worker-beslutet värt att kopiera: en ny version tar inte över en öppen flik av sig själv. Att byta ut filerna under ett halvifyllt formulär är hur någon förlorar ett avslut — och i den här appen kan det formuläret ha en kund bredvid sig som väntar på att signera. Den nya versionen tar över vid nästa laddning, eller när sidan bedömer att stunden är lämplig.
Sedan: utkorgen
Allt som rapporterar ett faktum i stället för att ställa en fråga går genom en kö: skrivs till disk först, skickas när det finns uppkoppling, tas bort först när servern har kvitterat det.
IndexedDB, inte localStorage. Fotografier går genom samma kö och en handfull av dem överskrider de få megabyte ett stränglager ger. Det är också det enda weblagret som pålitligt överlever att en hemskärmsapp på iOS kastas ur minnet mitt i ett pass.
Skrivet före sänt, alltid — även med bra uppkoppling. Att skicka först och köa vid fel lämnar en lucka: anropet är i luften, appen dödas, arbetet är borta. Den luckan öppnar sig precis när nätet är dåligt, vilket är precis när fältarbete sker. Att skriva först kostar några millisekunder och stänger den. Det ger också en ordningsgaranti gratis: en utstämpling kan aldrig springa om den instämpling den stänger, eftersom båda lämnar genom samma kö.
Id och tidpunkt sätts på enheten, i handlingens ögonblick. Inte när posten till slut skickas. En timme i en källare får inte registreras som en timme som började när bilen kom upp på stora vägen.
Positionen följer med posten. Tagen vid trycket, skickad med anropet när kön än töms. Att ta den när kön töms skulle registrera var bilen var när den hittade täckning — en annan plats, och en sämre lögn än ingen position alls.
Och: hur kön töms, och när den ger upp
Det är här de flesta offline-implementationer tyst går fel.
Serieordnad. Posterna sorteras efter när de skedde och skickas en i taget. De är inte oberoende händelser: en utstämpling stänger en bestämd instämpling, och en checklistebock hänvisar till ett jobb servern kanske inte hört talas om än. Att skicka dem parallellt vore snabbare och skulle komma fram i fel ordning tillräckligt ofta för att spela roll.
Stannar vid första riktiga felet, i stället för att hoppa förbi det. Det som misslyckades är nästan säkert uppkopplingen. Att hoppa förbi skulle leverera senare arbete medan det som det beror på fortfarande ligger i kön.
Tre statuskoder betyder "färdigbehandlad, på ett eller annat sätt". En 409 på en instämpling betyder att servern redan har den: anropet landade och svaret försvann, vilket är precis vad en ostadig uppkoppling gör. En 422 är en nyttolast servern avvisar en gång och kommer att avvisa varje gång. En 404 pekar på ett jobb som är borta. Ingen av de tre blir bättre av att skickas igen, och att göra om i evighet skulle spärra kön bakom en post som aldrig kan lyckas — med varje utstämpling bakom sig fast tillsammans med den. Alla tre tas bort.
Allt annat görs om. En timeout, en 500, inget nät alls. Antalet försök och det senaste felet ligger kvar på posten, så att en kö som verkligen har fastnat syns i stället för att vara tyst.
Vad som köas i dag, och vad som inte gör det
Vi är exakta här, eftersom "fungerar offline" är frasen folk köper på.
In- och utstämpling går genom kön. Det är de två handlingar som sker åtta gånger om dagen på platser utan täckning, och det är deras tidpunkter som betyder mest.
Kön har definierade platser för checklistebockar, fotografier och signaturer. Ingenting lägger dem i kön än, och sändningskoden för de typerna kastar medvetet ett fel i stället för att tyst lyckas — en tyst framgång där skulle rapportera en kunds signatur som levererad och sedan släppa den, vilket är det enda utfall som är värt att skriva kod för att förhindra. Att avsluta ett jobb kräver i dag uppkoppling i sändningsögonblicket.
Avslutar era lag jobb på platser helt utan täckning: vet om det före köpet, inte efter.
Vad ni ska säga till laget
Tre meningar, vilket är ungefär så mycket någon minns:
- Öppna appen på wifi en gång före första jobbet. Sedan öppnar den var som helst.
- Stämpla in och ut när det händer, inte när ni får täckning. Tiden tas från din telefon i det ögonblick du trycker.
- Siffran bredvid klockan är vad som väntar på att skickas. Den nollställer sig när du får täckning. Nollställs den inte på en hel dag: säg till på kontoret.