In het begin van de mobiele revolutie was de keuze simpel: als app ontwikkelaar kies je in de eerste plaats voor iOS. Daarmee bereik je de meeste klanten, met de diepste buidels. Mocht dat een succes zijn, dan kan je later altijd nog nadenken over het ondersteunen van andere platformen. Inmiddels is die keuze niet meer zo eenvoudig: dankzij de opkomst van Android en het toenemende aantal spelers op de markt, is het misschien juist beter om je aandacht te spreiden en je bereik daarmee te vergroten. Het onderhouden van verschillende apps, in verschillende programmeertalen en voor verschillende platformen, kan echter verschrikkelijk gecompliceerd worden. PhoneGap biedt dan uitkomst. 

Wat is Phonegap?

PhoneGap is een ontwikkel-framework voor mobiele applicaties, dat ontwikkelaars in staat stelt om applicaties te bouwen voor een groot aantal verschillende mobiele besturingssystemen, met gebruik van vertrouwde web technologieën als HTML, CSS en JavaScript. Het open source-project ontstond op het iPhoneDevCamp in 2008, met als idee het maken van applicaties voor iOS te vergemakkelijken. Er zijn namelijk heel veel meer web ontwikkelaars—die HTML, CSS en JavaScript tot in de puntjes beheersen—dan er ontwikkelaars zijn met kennis van het relatief obscure Objective-C, de vereiste programmeertaal voor ‘native’ iOS-applicaties. De uitdaging was om de mogelijkheden van een native app, zoals bijvoorbeeld toegang tot de camera, geolocatie en dataopslag, beschikbaar te maken voor web ontwikkelaars.

De oorspronkelijke gedachte was om iOS ontwikkeling te vergemakkelijken, maar al snel ontstond er interesse om hetzelfde te bewerkstelligen in Android. Een voordeel van web applicaties is dat ze platform onafhankelijk zijn, dus het openen van andere platformen was een logische keuze. Met andere woorden, PhoneGap is een ‘hybride’-oplossing: het verbindt de platform-onafhankelijkheid van web apps met de kracht en functionaliteit van native apps. Daarmee werd PhoneGap een erg interessante keuze voor mobiele app ontwikkeling: gebruikmakend van vertrouwde en makkelijke web technologieën kan je tegelijkertijd verschillende platformen ondersteunen.

Cordova
De onderliggende software van PhoneGap heet Apache Cordova. In 2011 kocht Adobe het Canadese Nitobi Software, de oorspronkelijke ontwikkelaar van PhoneGap. Bij die overname werd besloten dat PhoneGap zou worden gedoneerd aan de Apache Foundation, om daarmee te garanderen dat PhoneGap open source zou blijven. Adobe is PhoneGap wel blijven ondersteunen en door blijven ontwikkelen als onderdeel van hun verzameling software voor designers en ontwikkelaars, met bijvoorbeeld volledige integratie van PhoneGap in Dreamweaver en de mogelijkheid om apps ‘in te cloud’ te bouwen, waarover verderop meer.

Platformen
PhoneGap ondersteunt de volgende platformen: iOS, Android, BlackBerry, Windows Phone, Tizen, Amazon Fire OS, WebOS en Symbian. Ontwikkelen met PhoneGap kan op Windows, Mac OS X en Linux. In ons geval gebruiken we natuurlijk het laatste, maar het is belangrijk om te benadrukken dat PhoneGap zich netjes aan de regels houdt: als een bepaalde partij eist dat hun SDK (Software Development Kit) alleen op een bepaald besturingssysteem werkt, dan houdt PhoneGap zich daar aan. Wij zullen hier Linux en Android gebruiken als voorbeeld, maar voor iOS ontwikkeling heb je dus Mac OS X nodig, en voor Windows Phone moet je je ontwikkelomgeving in Windows hebben.

Gelukkig is er tegenwoordig Adobe PhoneGap Build, waarmee je je code “in de cloud” kunt bouwen voor je gewenste platform. Je hebt dus geen aparte ontwikkelomgeving met bijbehorende SDK te hebben voor elk platform—alles (helaas met uitzonering van Windows apps) wordt voor je gebouwd in de cloud. Via PhoneGap Build kan je zelfs mensen je apps laten testen op verschillende platformen, je apps digitaal ondertekenen en kant en klaar downloaden om in een app store te uploaden. Ook hier speelt PhoneGap netjes volgens de regels, dus heb je een Apple ontwikkelaarsaccount nodig om dat voor iOS te doen en een Android-keystore voor Android.

WebView
PhoneGap applicaties zijn afhankelijk van een config.xml-bestand waarin alle informatie over de app is opgeslagen. De applicatie zelf is geïmplementeerd als een webpagina, standaard is dat index.html genaamd, waarin je alle CSS, Javascript en andere resources (plaatjes, filmpjes, andere media bestanden) aanroept. Dat index.html bestand wordt in je applicatie als een WebView weergegeven, zeg maar een browser venster dat in een native app is geopend. De interactie van de web app in de WebView met de native app buiten de WebView gebeurt via het phonegap.js-bestand. Je bent trouwens niet gebonden aan de WebView: je kunt het PhoneGap gedeelte van je app ook inbouwen in een grotere native user interface, zodat de WebView een component wordt in een grotere hybride applicatie die ook native elementen aanbiedt. De communicatie verzorgt PhoneGap door middel van een steeds groter wordende verzameling plug-ins.

Hoe installeer je Phonegap?
Om PhoneGap te installeren heb je allereerst Node.js en de NPM package manager nodig. Deze installeer je door de juiste packages voor jouw distributie te installeren, bijvoorbeeld:

sudo yum install nodejs npm

voor Fedora. Voor Ubuntu en Mint moeten we wat meer stappen uitvoeren omdat we een recentere versie van npm nodig hebben:

sudo apt-get update
sudo apt-get install -y python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs

Vervolgens zorgen we dat npm de juiste packages kan vinden en installeren we Apache Cordova en PhoneGap:

sudo npm config set registry http://registry.npmjs.org/
sudo npm install -g cordova
sudo npm install -g phonegap

Android-ontwikkeling
In het achterhoofd houdende dat we PhoneGap Build kunnen gebruiken voor het compileren van de app voor andere platformen, gebruiken we hier Android als doelplatform. Zoals je weet als je de Android App workshop in eerdere Linux Magazine edities hebt gevolgd, hebben we de Android Developer Tools (ADT) nodig voor het ontwikkelen van apps. Deze tools zijn een uitbreiding op de Eclipse ontwikkelomgeving. Je kunt de complete bundel downloaden op http://developer.android.com/sdk/installing/bundle.html. Pak het .ZIP bestand uit in je thuis map. In de eclipse map vind je een Eclipse versie met ADT voorgeïnstalleerd. We moeten de locatie van de ADT bundel nu ook vindbaar maken door PhoneGap, door onze PATH environment variabele aan te passen vanuit bijvoorbeeld .bash_profile:

echo “export PATH=${PATH}:/home/linuxmag/adt-bundle/sdk/platform-tools: /home/linuxmag /adt-bundle/sdk/tools” >> ~/.bash_profile
source ~/.bash_profile

We hoeven voor de ontwikkeling van onze app niet per se Eclipse te gebruiken. Voor web applicatie ontwikkeling zijn andere omgevingen waarschijnlijk geschikter. De voornaamste reden dat we de ADT bundel nodig hebben is voor de Android Virtual Device Manager, waarmee we erg makkelijk nieuwe virtuele Android apparaten kunnen aanmaken om onze PhoneGap app op uit te proberen. Maak bijvoorbeeld een virtueel Nexus S apparaat aan met Android 4.4 (zie afbeelding 2).

 Aanmaken van een virtueel Nexus apparaat

Hello World

We gebruiken het phonegap commando om een nieuw project aan te maken. Laten we ons eerste project HelloWorld noemen. We hoeven niets te veranderen, want een nieuwe PhoneGap app is standaard een “hello world”:

 

linmag@linmag.nl:~$ phonegap create hello com.example.hello HelloWorld
[phonegap] missing library phonegap/www/3.3.0
[phonegap] downloading https://github.com/phonegap/phonegap-app-hello-world/archive/3.3.0.tar.gz…
[phonegap] created project at /home/linmag/hello

 

Vervolgens testen we of onze configuratie werkt. Start de emulator in de Android Development Tools door op de Start knop te drukken. Ga vervolgens naar de map van het project, stel Android in als platform, en geef de opdracht om onze nieuwe app op Android te installeren:

 

cd hello
cordova platform add android
phonegap install android

 

Vervolgens zien we de app in onze emulator. Door er op te klikken opent de PhoneGap versie van “Hello world”, een WebView met de standaard index.html die aangeeft dat PhoneGap op de juiste manier werkt door “Device is ready” weer te geven (afbeelding 3).

Om met één commando de app te builden, installeren en meteen uit te voeren gebruik je:

phonegap run android

Alternatief
De Android emulator staat er om bekend dat hij nogal langzaam is. Dat kan soms best vervelend werken, maar PhoneGap biedt het voordeel dat het als web applicatie makkelijker is te testen en te ontwikkelen. Er bestaat zelfs een web gebaseerde emulator voor PhoneGap, compleet met het “device ready” signaal waarop elke app wacht, via http://emulate.phonegap.com. Door met de Google Chrome browser naar die website te gaan zie je een scherm waarbij je Ripple, de door BlackBerry ontwkkelde browser emulator, kunt downloaden en installeren als Chrome extensie. Je kunt daarmee alles simuleren in de browser, van het type apparaat tot geolocation en de acceleratometer, op een veel makkelijkere en snellere manier dan een echte emulator (afbeelding 4).

 Bijschrift: Simulatie in de browser

Plugins

Interactie met het native systeem verloopt via plugins. De volgende plugins zijn beschikbaar voor de meeste platformen:

        Accelerometer

        Camera

        Capture

        Compass

        Connection

        Contacts

        Device

        Events

        File

        Geolocation

        Globalization

        InAppBrowser

        Media

        Notification

        Splashscreen

        Storage

De meeste van deze plug-ins spreken voor zich. Laten we bijvoorbeeld de Accelerometer plug-in nemen. Met deze plug-in kunnen we meten op welke manier het apparaat wordt bewogen. Allereerst installeren we de plug-in:

 

linmag@linmag.nl:~/hello$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion.git
[phonegap] adding the plugin:
https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion.git
[phonegap] successfully added the plugin

 

We hoeven alleen maar de plugins te installeren die we ook daadwerkelijk in de app nodig hebben.

Standaard

Bij het aanmaken van het project via “phonegap create” werden er al een hoop bestanden aangemaakt. Ons index.html bestand ziet er bijvoorbeeld zo uit:

 

<html>
    <head>
        <meta charset=”utf-8″ />
        <meta name=”format-detection” content=”telephone=no” />
        <meta name=”viewport” content=”user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi” />
        <link rel=”stylesheet” type=”text/css” href=”css/index.css” />
        <title>Hello World</title>
    </head>
    <body>
        <div class=”app”>
            <h1>Hello World</h1>
            <div id=”deviceready” class=”blink”>
                <p class=”event listening”>Connecting to Device</p>
                <p class=”event received”>Device is Ready</p>
            </div>
        </div>
        <script type=”text/javascript” src=”phonegap.js”></script>
        <script type=”text/javascript” src=”js/index.js”></script>
        <script type=”text/javascript”>
            app.initialize();
        </script>
    </body>
</html>

Dit bestand is overzichtelijk genoeg: we kunnen makkelijk zien wat waar plaatsvindt. Om javascript code aan onze app toe te voegen moeten we in www/js/index.js zijn. Het phonegap.js bestand biedt ons alle benodigde functionaliteiten, en zorgt er voor dat we de code van de plugins die we hebben geïnstalleerd ook daadwerkelijk kunnen gebruiken. De belangrijkste methode in het index.js bestand is “onDeviceReady”—wat doen we als ons apparaat klaar is om met de app aan de gang te gaan? Nou, laten we bijvoorbeeld eens kijken naar de beweging van de telefoon, door het volgende aan onDeviceReady toe te voegen:

 

navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);

 

De getCurrentAcceleration functie neemt twee callback functies als argumenten: één voor als het goed is gegaan en één voor foutafhandeling. Deze functie kunnen we apart in index.js definiëren:

 

    function onSuccess(acceleration) {
        alert(‘Acceleratie X: ‘ + acceleration.x + ‘\n’ +
              ‘Acceleratie Y: ‘ + acceleration.y + ‘\n’ +
              ‘Acceleratie Z: ‘ + acceleration.z + ‘\n’ +
              ‘Tijdstempel: ‘      + acceleration.timestamp + ‘\n’);
    }
    function onError() {
        alert(‘Er is iets fout gegaan!’);
    }

 

Als we de app nu in bijvoorbeeld de PhoneGap emulator laden dan zien we dat er wel wat gebeurt, maar niet zo heel erg veel. Dit komt omdat we de beweging van de telefoon slechts één keer meten, namelijk als onDeviceReady wordt aangeroepen. Om constant te blijven meten, moeten we een andere functie gebruiken. Laten we allereerst een div toevoegen aan index.html waarin we de acceleratie informatie kunnen wegschrijven:

 

            <div id=”acceleratieinfo”>
                <p>Nog geen acceleratie informatie beschikbaar</p>
            </div>

 

Nu kunnen we onSuccess aanpassen om niet meer een alert() uit te sturen, maar om netjes de inhoud van de acceleratieinfo div aan te passen:

    function onSuccess(acceleration) {
        var element = document.getElementById(‘acceleratieinfo’);
        element.innerHTML = ‘<p>Acceleratie X: ‘ + acceleration.x + ‘<br>\n’ +
              ‘Acceleratie Y: ‘ + acceleration.y + ‘<br>\n’ +
              ‘Acceleratie Z: ‘ + acceleration.z + ‘<br>\n’ +
              ‘Tijdstempel: ‘      + acceleration.timestamp + ‘</p>\n’;
    }

Verander nu de eerdere getCurrentAcceleration functie in een nieuwe methode die elke 3 seconden nieuwe acceleratieinformatie opvraagt:

        var options = { frequency: 3000 };
        watchID = navigator.accelerometer.watchAcceleration(onSuccess, onError, options);

Mochten we klaar zijn en geen interesse meer hebben in het bekijken van de beweging van de telefoon, dan roepen we “navigator.accelerometer.clearWatch(watchID);” aan om aan te geven dat we klaar zijn. In de PhoneGap emulator kunnen we goed zien dat de app doet wat we willen  (afbeelding 5).

 

Config.xml
Veel aspecten van het gedrag van je app kunnen worden gecontroleerd via het centrale configuratiebestand, config.xml, dat je in de www/ map kunt vinden. Dit bestand ziet er als volgt uit:

<widget id=”com.example.hello” version=”0.0.1″>
        <name>HelloWorld</name>
        <descr
iption>
            A sample Apache Cordova application that responds to the deviceready event.
        </description>
        <author email=”dev@callback.apache.org” href=”http://phonegap.com”>
            Apache Cordova Team
        </author>
        <content src=”index.html” />
        <access origin=”*” />
        <preference name=”Fullscreen” value=”true” />
        <preference name=”WebViewBounce” value=”true” />
    </widget>

We kunnen dit natuurlijk zelf aanpassen om onze eigen informatie weer te geven. Verder zijn er een hoop andere instellingen, zoals bijvoorbeeld de standaard oriëntatie van het scherm:

<preference name=”Orientation” value=”landscape” />

Het aanpassen van het config.xml bestand is van belang als je via een aparte SDK of IDE werkt, bijvoorbeeld als je je Android ontwikkeling vanuit Eclipse blijft doen, maar ook voor de uiteindelijke app de je wilt gaan bouwen en in de verschillende app stores wilt aanbieden.

Build
De laatste stap in een workshop over het maken van apps moet altijd gaan over het bouwen we apps, en belangrijker, hoe krijgen we de app in de app stores? Als gezegd kun je zelf je apps bouwen door middel van de SDK die je lokaal hebt geinstalleerd. Voor Android kunnen we in ons geval dus vrij snel apps bouwen, maar we willen juist gebruik maken van het gemak van PhoneGap om in een keer apps voor verschillende platformen te ontwikkelen.

Maak een account aan op http://build.phonegap.com en kies voor de ‘Free’-optie. Hiermee kunnen we gratis één app laten bouwen om te distribueren. Je kunt een bestaande Adobe ID gebruiken als je er een hebt, of er een aan maken. Als alternatief kun je via GitHub inloggen. Aangenomen dat je je code al in GitHub hebt staan (en dat is wel aan te raden!), kan je met veel gemak je code om zetten in een gebouwde app. Wil je geen GitHub gebruiken, dan kan je een .ZIP bestand met je app uploaden. Zodra je je app hebt geupload, begint PhoneGap Build met het bouwen van je app voor de verschillende aangeboden platformen (afbeelding 6).

Zoals je kunt zien is het BlackBerry logo grijs, en dat betekent dat PhoneGap Build nog bezig is met het compileren van BlackBerry. We zien dat iOS rood is—dit komt vanwege de eisen van Apple, en we onze developer key dus nodig hebben voordat we voor iOS kunnen bouwen. Voor elk van de geslaagde compilaties kunnen we nu de package downloaden. Om onze app in de Android Market te krijgen moeten we daar onze gegevens invullen, en hoeven we vervolgens alleen ons .apk bestand te uploaden om een werkende app te hebben. Niet vergeten de app met je key te ondertekenen natuurlijk, maar dat is zo gedaan. En dat alles zonder complexe programmeertalen en verschillende versies voor elk besturingssysteem. Simpeler kan bijna niet!

Verder leesvoer
PhoneGap is ideaal voor ontwikkelaars die snel voor verschillende platformen mobiele applicaties willen ontwikkelen. Het gebruik van web technologieën maakt het ontwikkelen van apps een fluitje van een cent. Natuurlijk zijn de prestaties van PhoneGap niet vergelijkbaar met echte native prestaties, maar in veel gevallen is dat ook helemaal niet nodig. De moeite die je moet doen om met verschillende SDK’s te werken, in verschillende programmeertalen en in verschillende ontwikkelomgevingen, verhelpt PhoneGap zonder problemen. De PhoneGap Emulator en PhoneGap Build schelen verschrikkelijk veel tijd. Zelf altijd al eens mobiele apps willen ontwikkelen? Als je een beetje ervaring hebt met HTML, CSS en JavaScript, dan heb je dankzij PhoneGap binnen de kortste keren je eigen app in alle grote app stores staan… Succes!

Referenties

http://www.phonegap.com

http://cordova.apache.org/

https://github.com/linuxmagNL/PG-HelloWorld