6 enkla steg mot en mer app-lik webbtjänst

När man bygger webbtjänster som skall användas på iOS-enheter finns det en del enkla knep att ta till för att få lite mer app-känsla. Här visar Viktor Fröberg hur man enkelt kan utnyttja vissa verktyg som redan finns i Mobile Safari för att skapa en bättre upplevelse för sina användare.

I vårt samarbete med Ebeco och deras webbtjänst Garantera Ebeco ville vi skapa en produkt som var lättillgänglig både på datorn och i mobilen. Som ett led i det tänket undersökte vi möjligheterna att höja upplevelsen i mobilen genom att exempelvis skapa en genväg till tjänsten på hemskärmen, och att starta tjänsten i fullskärmsläge. I takt med att vi arbetade fram en lösning som vi var nöjda med kom vi fram till en del intressanta insikter, som jag tänkte dela med mig av här.

Hemskärmsikon

Både iOS och Android erbjuder möjligheten att spara ned en genväg till en webbsida på hemskärmen på respektive plattform. Detta gör det enkelt för en återkommande besökare att hitta tillbaka till webbplatsen utan att behöva skriva in adressen till sidan igen. Det första man bör se till är att det finns en ikon specificerad för att visas på hemskärmen (saknas en ikon använder iOS en skärmdump av webbsidan, Android använder sig av faviconen). Denna lägger man enkelt in med en link-tagg med rel-attributet "apple-touch-icon-precomposed". Nyare iOS-enheter hittar dessa ikoner oavsett om det finns en link-tagg specificerad, så länge själva ikonen är korrekt namngiven och ligger i roten av webbplatsen. Äldre versioner av iOS och även Android behöver dock link-taggen, så det får anses vara best practice att ändå inkludera den.

Det finns i dagsläget sex stycken olika storlekar på ikonerna som var och en bör specificeras var för sig. Dessutom bör de ligga i en speciell ordning (se nedan) för att äldre versioner av iOS samt Android (som inte har stöd för sizes-attributet) ändå skall få rätt ikon levererad.

<!-- För iPad med högupplöst skärm och iOS 7 eller senare -->
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="/apple-touch-icon-152x152-precomposed.png">
<!-- För iPad med lågupplöst skärm och iOS 6 eller tidigare -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144x144-precomposed.png">
<!-- För iPhone med iOS 7 eller senare -->
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="/apple-touch-icon-120x120-precomposed.png">
<!-- För iPhone med högupplöst skärm och iOS 6 eller tidigare -->
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/apple-touch-icon-114x114-precomposed.png">
<!-- För iPad med lågupplöst skärm -->
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/apple-touch-icon-72x72-precomposed.png">
<!-- För iPhone och iPod Touch med lågupplöst skärm, samt Android 2.1+ -->
<link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-precomposed.png">

Applikationsnamn

När man skapar genvägen till webbplatsen på hemskärmen väljer Mobile Safari automatiskt ett namn från den aktuella webbsidans title-tagg. Namnet får endast vara 12 tecken långt och i många fall blev våra titlar nerkortade. Apple har dock gjort det möjligt att specifiera en genvägstitel med hjälp av en meta-tagg på följande sett:

<meta name="apple-mobile-web-app-title" content="Namnet på din webbplats">

Fullskärmsläge

Man kan även använda sig av Javascript-pluginen Add to homescreen  för att informera besökaren om att det går att spara ner webbplatsen på hemskärmen.

iOS erbjuder även möjligheten att köra webbplatsen i fullskärmsläge istället för att öppnas i Mobile Safari. Detta gör man genom att via en meta-tagg säga till Mobile Safari att webbplatsen är anpassad för att kunna användas som en webbapp. Detta medför att när man klickar på hemskärmsikonen öppnas webbplatsen som en egen applikation, utan adress- och verktygsfält.

<meta name="apple-mobile-web-app-capable" content="yes" />

Bibehålla fullskärmsläget

En liten detalj att ta hänsyn till när man använder fullskärmsläget är att iOS öppnar Mobile Safari så fort du klickar på en länk som triggar en gammal hederlig sidladdning. Detta är inget problem om man bygger exempelvis Single Page Applications (SPA) som laddar in sidinnehåll via Javascript, men för mer traditionella konstruktioner krävs lite handpåläggning för att man inte skall lämna helskärmsläget så fort man klickar på en länk.

För att spara tid och slippa att behöva bygga om delar av webbtjänsten valde vi att lösa problemet på ett snabbt och enkelt sätt: Med hjälp av Javascript lyssnar vi på alla länkar som besökaren klickar på. Vid ett klick så laddar vi in hela sidan som länken leder till via Javascript istället för att göra en ”vanlig” sidladdning. Detta får som resultat att vi egentligen aldrig lämnar sidan, även om innehållet byts ut dynamiskt.

$('a').click(function(event) {
  // Hindra att länken öppnas
  event.preventDefault();
  // Ladda in länkens href med Javascript istället
  window.location.href = this.href;
});

Ett mer ellegant sätt att lösa problemet på hade varit att använda sig av exempelvis PJAX (PushState Ajax) för att åstakomma samma resultat. PJAX fungerar på ett liknande sätt, men i det fallet laddas endast själva huvudinnehållet in  (inte sidhuvd, sidfot, css- och js-filer etc.) vilket leder till en snabbare upplevelse.

Ett problem med koden ovan är att även externa länkar kommer att öppnas i samma fönster. Detta kan leda till problem eftersom det inte finns någon tillbaka-knapp och därmed har användaren tappat möjligheten att navigera tillbaka till applikationen och tvingas starta om den. Detta kan man dock lösa genom att skruva till föregående kodsnutt en smula.

// Lyssna endast på länkar som antingen innehåller bas-urlen eller är relativa.
$('a[href^="' + baseUrl + '"], a[href^="/"]').click(function(event) {
  // Hindra att länken öppnas
  event.preventDefault();
  // Ladda in länkens href med Javascript istället
  window.location.href = this.href;
});

I fallet med Garantera Ebeco hade vi sedan tidigare definierat lyssnare på ett antal länkar för att kunna styra funktionalitet. Vi var därmed tvunga att ta hänsyn till dessa för att funktionaliteten inte skulle gå förlorad. Vi hade exempelvis en funktion som lyssnade på om användaren slängde en produkt, varpå en dialogruta öppnades och frågade om användaren var säker på om den ville fortsätta.  Med nuvarande lösning öppnades länken i bakgrunden och slängde produkten även om användaren valde att avbryta, vilket får anses vara lite okänsligt. Lösningen på detta blev att vi hindrade andra lyssnare från att noteras om klicket. jQuery har en metod som heter stopImmediatePropagation() som gör precis detta.

$('.js-confirm').click(function(event) {
  // Hindra andra lyssnare för att noteras om klick-eventet
  event.stopImmediatePropagation();
  // Kod som slänger produkten om man klickar "OK" …
});

Viewport

Nästa utmaning vi stötte på var att webbplatsen inte fyllde upp hela skärmhöjden på en iPhone med 4-tumsskärm (iPhone 5 och nyare). Normalt sett använder man sig av en meta-tagg med attributet ”name=viewport” för att zooma in innehållet efter storleken på skärmen. Meta-taggen brukar mer eller mindre se ut på följande sett:

<meta name="viewport" content="width=device-width" />

Problemet med detta är att när man specificerar "width=device-width" tror iOS fortfarande att det rör sig om en 3,5-tumsskärm och sätter automatiskt höjden till 480px oavsett om du tittar på webbplatsen med en iPhone 5 (vars skärm är 568px hög). Tar man bort "width=device-width" och ersätter med "initial-scale=1" så har man en lösning som fungerar på de flesta enheter (förutom Android 2.3).

<meta name="viewport" content="initial-scale=1" />

Uppstartsbild

När man öppnar webbplatsen i fullskärmsläge från hemskärmen så har man möjlighet att specificera en bild som visas medan webbsidan laddas in, vilket gör att användaren slipper se en blank vit skärm i någon sekund.

<!-- För iPhone med lågupplöst skärm -->
<link rel="apple-touch-startup-image" href="/apple-touch-startup-image-320x460.png" media="(device-width: 320px)">
<!-- För iPhone med högupplöst skärm -->
<link rel="apple-touch-startup-image" href="/apple-touch-startup-image-640x920.png" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)">
<!-- För iPhone 5 -->
<link rel="apple-touch-startup-image" href="/apple-touch-startup-image-640x920.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)">
<!-- För iPad med lågupplöst skärm i porträtt-->
<link rel="apple-touch-startup-image" href="/apple-touch-startup-image-768x1004.png" media="(device-width: 768px) and (orientation: portrait)">
<!-- För iPad med lågupplöst skärm i landskap -->
<link rel="apple-touch-startup-image" href="/apple-touch-startup-image-748x1024.png" media="(device-width: 768px) and (orientation: landscape)">
<!-- För iPad med högupplöst skärm i porträtt -->
<link rel="apple-touch-startup-image" href="/apple-touch-startup-image-1536x2008.png" media="(device-width: 1536px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)">
<!-- För iPad med högupplöst skärm i landskap -->
<link rel="apple-touch-startup-image" href="/apple-touch-startup-image-2048x1496.png" media="(device-width: 1536px)  and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)">

En bra grund

Dessa förbättringar lämpar sig mer för webbtjänster med återkommande, inloggade användare än vanliga hederliga företagspresentationer. En hemskärmsikon får däremot anses vara en hygienfaktor nuförtiden, och borde alltid finnas specificerad. Det finns naturligtvis mängder med fler förbättringar man kan göra för att höja upplevelsen på de mobila plattformarna, men utnyttjar du möjligheterna som jag har gått igenom här ovan är du en bra bit på väg för att göra dina mobila användare glada.