Titanium er et godt – rigtig godt – framework til iPhone-udvikling og til prototyper. Man kommer hurtigt i gang og kan hurtigt vise et resultat frem. Titaniums værdi er begrænset, når det kommer til WORA (Write Once, Run Anywhere), og det er farligt (og i sidste ende dyrt!) at regne med, at man kan bruge den samme kode til Android og iPhone, da opførslen af de underliggende platforme er meget forskellig. Har man en simpel brugergrænseflade og ingen afhængigheder af specielle ting på underliggende platform, er Titanium et fint valg, der – næsten – giver en følelse af at sidde med en ‘native app’. Har man større krav til hastighed, brugergrænsefladen eller til den underliggende platform bør man, før man vælger Titanium, først afprøve om det er ladsiggørligt – på begge platforme!

Man føler sig nemt fristet af Titanium Appcelerators løfter om to fluer med et smæk, når der skal vælges strategi for den mobile app.

Onlinemagasinet Version2.dk skrev for eksempel i marts 2011 om deres nye apps til iPhone og Android:

“Begge applikationer er lige på nippet til at dukke op i iTunes App Store og Android Market, og de er lavet uden at kode hverken Objective-C eller Java. I stedet har Version2 valgt at benytte sig af open source-systemet Titanium Appcelerator, som gør det muligt at kode en applikation i Javascript og herefter køre den native på både iPhone og Android-mobiler.“

Det lyder jo næsten for godt til at være sandt!?!?

Og går man i gang med Titanium har man faktisk på meget kort tid udviklet en app, der fungerer rimeligt godt.

Men pas på… Det er desværre for godt til at være sandt..!

For det første afvikles Titaniums Javascript ikke ‘native’. Det er kun de underliggende Java-script-kald – altså Titaniums funktioner – der afvikles ‘native’ i C eller Java [1].

For det andet er ideen om WORA – Write Once, Run Anywhere – en illusion i Titanium. Man kan ikke kode applikationen én gang og derefter forvente at den kører på både iPhone og Android.

Version2’s Android-version blev heller ikke ligefrem nogen success:

Det virker som om Version2 har troet på WORA, udviklet deres app til iPhone, og derefter ikke formået at få den til at virke på Android. I hvert fald har iPhone-versionen fået en betydelig bedre vurdering:

Hos Lund&Bendsen har vi en del erfaringer med Titanium Appcelerator, både gode og dårlige.  Vi mener at disse erfaringer er vigtige at dele, for der er mange udviklere der har brændt sig på Titanium, brugt måneder på “de sidste småting”, og derefter måttet opgive Titanium helt og/eller udvikle separate udgaver på hver platform. [2]

Java og WORA (Write Once, Run Anywhere) – lidt historie

Idéen med WORA er jo ikke ny. For at sætte problematikkerne i cross-platform-biblioteker lidt i perspektiv, så lad os se på det mest udbredte sprog til cross-platform udvikling og WORA – nemlig Java.

Der er meget man kan lære af Javas historie. Specielt har brugergrænsefladebiblioteker været en kæmpe udfordring.

WORA i AWT: Vi skærer alt kødet fra

Først forsøgte man at skrive klasser der abstraherede væk fra den underliggende platform. Disse klasser tegnede ikke noget selv, men havde ‘peer’-klasser, der formidler de forskellige kald videre til den underliggende platform. Dette kom til at hedde AWT (Abstract Windowing Toolkit), og filosofien her var altså, at når programmøren arbejder med f.eks. en knap, java.awt.Button, så sender knappen kaldene videre til en ‘rigtig’ Windows-knap (eller MacOS- eller Linux-knap).

Det lyder jo umiddelbart fint, men hvad gør man med de lidt mere raffinerede funktioner, såsom animation eller gennemsigtighed? Vil man følge WORA-princippet er der ikke meget andet at gøre end simpelthen at udelade disse funktioner. Videreudviklingen af AWT strandede (blandt andet) på at toolkittet var fattigt fordi kun laveste fællesnævner kunne implementeres.

WORA i SWING: Vi skriver det hele selv

Næste forsøg var at skrive komponenterne i ren java, og kun overlade de mest basale tegnefunktioner til det underliggende styresystem. Det gav det meget rige og fleksible komponentbibliotek SWING og fuld understøttelse for MVC-modellen (Model View Controller), der giver programmøren frihed til mange rare ting (bl.a. kan to komponenter dele ‘model’, f.eks. en knap og et menupunkt, sådan at programmøren kan nøjes med at bekymre sig om håndteringen af én af dem). En knap af typen javax.swing.JButton kan også have gennemsigtighed selvom det ikke understøttes af de ‘native’ knapper på den underliggende platform.

SWING var et kæmpe skridt fremad, men havde også nogle ulemper: Det tog tid at indlæse, brugte mere RAM og den indbyggede garbage collector måtte køre engang imellem og brugerne oplevede derfor at programmerne ‘frøs’ kortvarigt og generelt føltes langsommere end AWT, og selvom der senere kom hurtigere processorer, bedre JVMer og mere fleksible garbage-collectorer så kom programmer skrevet i SWING aldrig helt til at føles som ‘native’ MacOS/Linux/Windows-programmer.

WORA i SWT: Vi gør vores bedste

Senere skabte IBM en del kontroverser ved at introducere SWT (Standard Widget Toolkit) som minder om AWT men hvor funktioner, der ikke understøttes på alle platforme er tilladte og man derfor ikke behøver holde sig ved mindste fællesnævner. Manglende funktioner bliver ofte emuleret a la SWING, men generelt kan programmøren ikke regne med at WORA-princippet holder.

WORA i Titanium: Findes ikke

Titanium er gået et skridt videre end IBM gik med SWT. Man tilstræber at lignende metodekald på Android og iOS hedder det samme, men ikke at de rent faktisk gør det samme.

Eksempelvis lyder Titaniums dokumentation for Geolocation.getCurrentPosition således:

‘Retrieve the last known location from the device.
On Android, the radios are not turned on to update the location.
On iOS the radios MAY be used if the location is too “old”. ‘ [3]

Dette dækker over at man på iOS kan kalde metoden og regne med at få en nogenlunde præcis geoplacering…. mens den samme funktion på Android kan give en placering der er flere dage gammel !

Har man skrevet kode der bruger geoplacering med Titanium/iOS-udgaven skal man altså sandsynligvis skrive sin kode helt om for at få den til at virke i Titanium/Android-udgaven.

Eksemplet er ikke enestående. Dokumentation er fuld af bemærkninger som ‘(Android only)’, ‘(iOS only)’ og ‘(iOS 4.0+ only)’ som man altså må tage højde for i sin kode, og de samme kald opfører sig mange steder helt forskelligt på grund af forskellighederne i de underliggende platforme.

I det hele taget har WORA en meget begrænset værdi på mobilplatformen, da iPhone og Android er så grundlæggende forskellige.
Det mest iøjenfaldende i  brugergrænsefladen er selvfølgelig, at den fysiske tilbage- og menuknap mangler på iPhone, hvorfor der enten skal være plads til dem på touchskærmen eller brugeren skal opdrages til at bruge en eller anden form for gestus til disse funktioner. På Android virker det på den anden side unaturligt, grænsende til amatøragtigt, hvis der er tilbageknapper på skærmen (‘Kender de ikke noget til Android??!?’).

Konklusion

Titanium er et godt – rigtig godt – framework til iPhone-udvikling og til prototyper. Man kommer hurtigt i gang og kan hurtigt vise et resultat frem.

Titaniums værdi er begrænset, når det kommer til WORA, og det er farligt (og i sidste ende dyrt!) at regne med, at man kan bruge den samme kode til Android og iPhone, da opførslen af de underliggende platforme er meget forskellig.

Har man en simpel brugergrænseflade og ingen afhængigheder af specielle ting på underliggende platform, er Titanium et fint valg, der – næsten – giver en følelse af at sidde med en ‘native app’.

Har man større krav til hastighed, brugergrænsefladen eller til den underliggende platform bør man, før man vælger Titanium, først afprøve om det er ladsiggørligt – på begge platforme!

Sammenlign selv

Vi har lige været igennem et forløb for vi skrev DRs Radio-app om til Java, fra at være en Titanium-app som nogle rigtig dygtige fyre havde brugt meget tid på at skrive i JavaScript.

Du kan hente dem og selv sammenligne dem herunder. Prøv f.eks. at åbne kanalvalget

  • DR Radio v1 (Titanium):

I DR Radio-appens tilfælde var det ikke så meget brugergrænsefladen men medieafspilleren i Android der ikke var nok kontrol over fra Titanium: Den stoppede simpelthen efter et par minutter, og det viste sig at være meget svært at løse.

WOOTO?

I stedet for WORA bør man måske overveje WOOTO – Write One, Outsource The Other, dvs. begynde med den platform man er bedst til, og når man har et program, der er modent nok til, at design etc. ligger fast, så finde en partner i Østeuropa eller Asien, der kan udvikle den anden version.

Har man meget forretningslogik, kan det betale sig at skrive logikken i Java, da Java automatisk kan oversættes til Objective-C [4], men ikke omvendt.

Ligemeget hvad man vælger at starte med, mener jeg, at det er vigtigt, at man finder en i Danmark med solid erfaring, der kan stå for den sidste afpudsning og kvalitetskontrol.

Referencer

[1] Citat fra https://en.wikipedia.org/wiki/Appcelerator_Titanium “It is noteworthy however, that for Titanium Mobile, the term cross-compiler is misleading: All application source code gets deployed to the mobile device, and it is only there that it “cross-compiled”, or, more accurately it is interpreted.” Citat fra en af udviklerne af Titanium-frameworket på https://stackoverflow.com/questions/4217551/what-happens-to-javascript-code-after-app-is-compiled-using-titanium-mobile “JS Source is base64’d and inlined as a variable into a generated C file”

[2] Se f.eks. https://usingimho.wordpress.com/2011/06/14/why-you-should-stay-away-from-appcelerators-titanium/ Citat udvikler der bruger Titanium på http://www.version2.dk/artikel/saadan-laver-version2-gratis-apps-til-android-og-iphone-18280#comment-81382 : “Overraskende nok har det vist sig at det endte med at være hurtigere for os at lære et helt nyt sprog og framework at kende og udvikle applikationerne native end at forsøge at løse de mange problemer der var med Titanium.“