1 Ontwikkeling van ADOBE AIR 1.5-toepassingen met ADOBE FLASH CS4 PROFESSIONAL2 Copyright 2008 Adobe Systems Incorporated. Alle rechten voorbehouden. ...
Hoofdstuk 2: Installatie van Flash CS3 voor Adobe AIR Systeemvereisten voor de Adobe AIR-update voor Flash CS3 Installatie van de Adobe AIR-update voor Flash CS3
Hoofdstuk 10: Werken met native vensters Aanvullende online informatie over native vensters Basisinformatie over AIR-vensters Vensters maken Vensters beheren
Hoofdstuk 14: Werken met het bestandssysteem Aanvullende online informatie over de AIR API voor het bestandssysteem Basisinformatie over AIR-bestanden Werken met File-objecten
Hoofdstuk 18: Werken met lokale SQL-databases Aanvullende online informatie over lokale SQL-databases Informatie over lokale SQL-databases Databases creëren en wijzigen
Hoofdstuk 1: Adobe AIR installeren Adobe® AIR™ stelt u in staat AIR-toepassingen uit te voeren op de desktop. U kunt de runtime op de volgende manieren installeren:
• U kunt de runtime afzonderlijk installeren (zonder ook een AIR-toepassing te installeren). • U kunt voor de eerste keer een AIR-toepassing installeren (u wordt dan ook gevraagd de runtime te installeren). • U kunt een AIR-ontwikkelomgeving instellen zoals de AIR SDK, Adobe® Flex™ Builder™ 3 of de Adobe Flex™ 3 SDK (die de AIR-opdrachtregelhulpprogramma’s bevat). De runtime hoeft op iedere computer maar eenmaal te worden geïnstalleerd. Hier worden de systeemvereisten beschreven om AIR en AIR-toepassingen te installeren en uit te voeren: Adobe AIR: Systeemvereisten (http://www.adobe.com/products/air/systemreqs/).
Adobe AIR installeren Houd u aan de volgende instructies voor het downloaden en installeren van de Windows®, Mac OS X- en Linux-versies van AIR. Voor het updaten van de runtime moet de gebruiker over beheerdersrechten voor de computer beschikken. De runtime installeren op een Windows-computer 1 Download het runtime-installatiebestand. 2 Dubbelklik op het runtime-installatiebestand. 3 Volg in het installatievenster de aanwijzingen om de installatie te voltooien.
De runtime installeren op een Mac-computer 1 Download het runtime-installatiebestand. 2 Dubbelklik op het runtime-installatiebestand. 3 Volg in het installatievenster de aanwijzingen om de installatie te voltooien. 4 Als het installatieprogramma een verificatievenster weergeeft, geeft u uw gebruikersnaam en wachtwoord voor Mac
OS op. De runtime installeren op een Linux-computer 1 Download het runtime-installatiebestand. 2 Stel de bestandsmachtigingen in zodat de installatietoepassing kan worden uitgevoerd:
Via de opdrachtregel kunt u de bestandsmachtigingen instellen met de opdracht chmod +x installer.bin. Met bepaalde versies van Linux kunt u de bestandsmachtigingen instellen via het menu Eigenschappen dat u hebt geopend via een contextmenu. 3 Voer het installatieprogramma uit vanaf de opdrachtregel of door te dubbelklikken op het runtime-
installatiebestand. 4 Volg in het installatievenster de aanwijzingen om de installatie te voltooien.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 2 Adobe AIR installeren
AIR wordt geïnstalleerd als rpm- of dpkg-pakket met de pakketnaam: adobeairv.nen adobecerts. Voor de installatie is een in bedrijf zijnde X-server vereist. AIR registreert het mime-type: application/vnd.adobe.airapplication-installer-package+zip.
Adobe AIR verwijderen Wanneer u de runtime hebt geïnstalleerd, kunt u deze als volgt verwijderen. De runtime verwijderen op een Windows-computer 1 Klik in het menu Start van Windows op Instellingen > Configuratiescherm. 2 Selecteer het onderdeel Software. 3 Kies “Adobe AIR” om de runtime te verwijderen. 4 Klik op de knop Wijzigen/Verwijderen.
De runtime verwijderen op een Mac-computer • Dubbelklik op de “Adobe AIR Uninstaller” in de map /Applications/Utilities. De runtime verwijderen op een Linux-computer Ga als volgt te werk:
• Selecteer de opdracht om Adobe AIR te verwijderen in het menu Toepassingen. • Voer het AIR-installatieprogramma binair uit met de optie -uninstall • Verwijder de AIR-pakketten (adobeairv.n en adobecerts) via het pakketbeheer.
AIR-voorbeeldtoepassingen installeren en uitvoeren Er zijn een paar voorbeeldtoepassingen beschikbaar waarin functies van AIR worden gedemonstreerd. U kunt deze als volgt openen en installeren: 1 Download de AIR-voorbeeldtoepassingen en voer ze uit. Zowel de gecompileerde toepassingen als de broncode zijn
beschikbaar. 2 Als u een voorbeeldtoepassing wilt downloaden en uitvoeren, klikt u op de knop Install Now van de
voorbeeldtoepassing. U wordt gevraagd de toepassing te installeren en uit te voeren. 3 Als u voorbeeldtoepassingen wilt downloaden en later wilt uitvoeren, selecteert u de downloadkoppelingen. U kunt
AIR-toepassingen op elk gewenst moment uitvoeren:
• In Windows dubbelklikt u op het toepassingspictogram op het bureaublad of selecteert u de toepassing in het menu Start van Windows.
• In Mac OS dubbelklikt u op het toepassingspictogram dat standaard is geïnstalleerd in de map Applications (Programma’s) van de gebruikersdirectory (bijvoorbeeld in Macintosh HD/Users/Gebruiker/Applications/).
• In Linux dubbelklikt u op het toepassingspictogram op het bureaublad of selecteert u de toepassing in het menu Toepassingen. AIR-toepassingen worden geïnstalleerd in een aparte map onder de map /opt. Opmerking: Updates van de AIR-releasenotes vindt u in http://www.adobe.com/go/learn_air_relnotes_nl.
3
Hoofdstuk 2: Installatie van Flash CS3 voor Adobe AIR De Adobe® AIR™-update voor Adobe® Flash® CS3 Professional breidt de Flash-ontwikkelingsomgeving uit met elementen waarmee u AIR-toepassingen met behulp van Flash kunt bouwen. U kunt er AIR-toepassingsbestanden in Flash mee maken, testen en debuggen. Adobe® Flash® CS4 Professional heeft ingebouwde ondersteuning voor het maken van AIR-applicaties. Zie Publishing for Adobe AIRin Using Flash voor meer informatie. De Adobe AIR-update voor Flash CS3 ondersteunt AIR 1.0 en 1.1 en Flash Player 9.x. Flash CS4 is vereist voor het ontwikkelen van toepassingen met AIR 1.5 en Flash Player 10.
Systeemvereisten voor de Adobe AIR-update voor Flash CS3 Om Flash CS3 te gebruiken voor de ontwikkeling en uitvoering van AIR-toepassingen, moet de volgende software geïnstalleerd zijn:
• Flash CS3 Professional Indien u geen exemplaar hebt van Flash CS3 Professional kunt u dit aankopen op de Adobe-website: http://www.adobe.com/products/flash/
• Adobe AIR Raadpleeg “Adobe AIR installeren” op pagina 1 voor meer informatie over het installeren van Adobe AIR.
• Adobe AIR-update voor Flash CS3 Indien u al een versie van de Adobe AIR-update voor Flash CS3 hebt geïnstalleerd, moet u deze installatie eerst verwijderen door de procedure te volgen in Installatie van de Adobe AIR-update voor Flash CS3 ongedaan maken. Als u de Adobe AIR-update voor Flash CS3 nog niet eerder hebt geïnstalleerd, gaat u naar de sectie “Installatie van de Adobe AIR-update voor Flash CS3” op pagina 3.
Installatie van de Adobe AIR-update voor Flash CS3 Voordat u de Adobe AIR-update voor Flash CS3 installeert, sluit u Flash af en ook alle browsers die u mogelijk hebt geopend.
• Download de Adobe AIR-update voor Flash CS3. • Nadat u de update hebt gedownload, dubbelklikt u op het update patch-bestand om het te installeren.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 4 Installatie van Flash CS3 voor Adobe AIR
Installatie van de Adobe AIR-update voor Flash CS3 verwijderen Indien u de Adobe AIR-update voor Flash CS3 reeds hebt geïnstalleerd, voert u volgende stappen uit om de installatie te verwijderen alvorens een nieuwe Adobe AIR-update voor Flash CS3 te installeren. 1 Verwijder volgende map:
(Windows) HD:\Program Files\Adobe\Adobe Flash CS3\\First Run\Commands\ (Mac) HD:/Applications/Adobe Flash CS3/First Run/Commands en verwijder de volgende bestanden/mappen:
• AIR-map • AIR - Application and Installer Settings.jsfl • AIR - Create AIR File.jsfl 3 Verwijder volgend bestand:
(Windows) HD:\Program Files\Adobe\Adobe Flash CS3\\Configuration\External Libraries\FLAir.dll (Mac) HD:/Applications/Adobe Flash CS3/Configuration/External Libraries/FLAir.bundle. 4 Verwijder het volgende bestand:
(Windows) HD:\Program Files\Adobe\Adobe Flash CS3\\Configuration\Players\AdobeAIR1_0.xml (Mac) HD:/Applications/Adobe Flash CS3/Configuration/Players/ AdobeAIR1_0.xml 5 Zoek de volgende locatie:
(Windows) HD:\Document and Settings\<username>\Local Settings\Application Data\Adobe\Flash CS3\\Configuration\Commands\ (Mac) HD:/Users/<username>/Library/Application Support/Adobe/Flash CS3//Configuration/Commands/ en verwijder de volgende bestanden/mappen:
• AIR-map • AIR - Application and Installer Settings.jsfl • AIR - Create AIR File.jsfl Opmerking: Als u de opgegeven locatie niet vindt in Windows schakelt u "Verborgen bestanden/mappen weergeven" in de mapopties in.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 5 Installatie van Flash CS3 voor Adobe AIR
AIR-uitbreidingen van Flash CS3 Na het installeren van de Adobe AIR-update kunt u volgende wijzigingen zien in Flash:
• In het dialoogvenster Publicatie-instellingen (Bestand -> Publicatie-instellingen), op het tabblad Flash, is er een nieuwe ingang in het menu Versie voor Adobe AIR 1.0
• Een bijgewerkt welkomscherm dat een ingang bevat voor het aanmaken van een Flash-bestand (Adobe AIR) (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\FirstRun\StartPage (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\FirstRun\StartPage\resources Opmerking: Op een MacIntosh-computer, verwijdert u de volgende map als het Flash-bestand (Adobe AIR) niet wordt weergegeven in het welkomscherm en start u Flash opnieuw op: HD:/Users/<username>/Libraries/Application Support/Adobe/Flash CS3//Configuration/StartPage
• Nieuw playerglobal.swc-bestand dat alle ActionScript 3.0 API's en Adobe AIR API's omvat in de map ActionScript 3.0/Classes (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\Configuration\ActionScript 3.0 Classes (Mac) HD:/Applications/Adobe Flash CS3/Configuration/ActionScript 3.0/Classes/
• Nieuwe jsfl-bestanden (AIR - Application and Installer Settings.jsfl, AIR - Publish AIR File.jsfl) (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\en\FirstRun\Commands (Mac) HD:/Applications/Adobe Flash CS3/First Run/Commands/
• Adobe AIR Software Development Kit (AIK) (Windows) HD:\Program Files\Adobe\Adobe Flash CS3\AIK
Hoofdstuk 3: Inleiding tot Adobe AIR Adobe® AIR™ is besturingssysteem overschrijdende runtime waarmee u uw bestaande webontwikkelingsvaardigheden kunt optimaliseren (Adobe® Flash® CS3 Professional, Adobe® Flash® CS4 Professional, Adobe® Flex™, Adobe® ActionScript® 3.0, HTML, JavaScript®, Ajax) om RIA's (Rich Internet Applications) te maken en te implementeren voor het bureaublad. Meer informatie over hoe u aan de slag gaat met en werkt met Adobe AIR vindt u op de Adobe AIR Developer Connection (http://www.adobe.com/devnet/air/). AIR stelt u in staat te werken in bekende omgevingen, gebruik te blijven maken van de hulpmiddelen en benaderingen die u goed kent en zo, mede dankzij de ondersteuning van Flash, Flex, HTML, JavaScript en Ajax, toepassingen te bouwen die optimaal aansluiten bij uw behoeften. U kunt bijvoorbeeld toepassingen ontwikkelen met behulp van een van de volgende technologieën of een combinatie daarvan:
• Flash / Flex / ActionScript • HTML / JavaScript / CSS / Ajax • PDF kan worden gebruikt met iedere toepassing. AIR-toepassingen kunnen daarom worden gebaseerd op:
• Flash of Flex: toepassingen waarvan de basisinhoud bestaat uit Flash/Flex (SWF); • Flash of Flex met HTML of PDF: toepassingen waarvan de basisinhoud bestaat uit Flash/Flex (SWF) met HTML(HTML, JS, CSS) of PDF-inhoud;
• HTML: toepassingen waarvan de basisinhoud bestaat uit HTML, JS, CSS; • HTML met Flash/Flex of PDF: toepassingen waarvan de basisinhoud bestaat uit HTML met Flash/Flex- (SWF) of PDF-inhoud. Gebruikers gebruiken AIR-toepassingen op dezelfde manier als native desktoptoepassingen. De runtime wordt éénmaal op de computer van de gebruiker geïnstalleerd, en daarna worden AIR-toepassingen geïnstalleerd en uitgevoerd net als elke andere desktoptoepassing. De runtime biedt een consistent platform voor meerdere besturingssystemen en een kader voor de implementatie van toepassingen waarbij de functionaliteit op verschillende desktops gegarandeerd constant is, zodat deze niet voor elke browser hoeft te worden getest. U richt zich bij de ontwikkeling op de runtime, niet op een specifiek besturingssysteem. Dit heeft de volgende voordelen:
• Toepassingen die zijn ontwikkeld voor AIR kunnen in meerdere besturingssystemen worden uitgevoerd zonder dat u extra werk hoeft te verrichten. De runtime garandeert een consistente en voorspelbare presentatie en interacties voor alle besturingssystemen die worden ondersteund door AIR.
• U kunt veel sneller toepassingen bouwen doordat u in staat bent gebruik te maken van bestaande webtechnologieën en ontwerppatronen, en doordat u uw webgebaseerde toepassingen kunt uitbreiden naar de desktop zonder dat u de traditionele technologieën voor desktopontwikkeling hoeft te leren of zich bezig hoeft te houden met de complexiteit van native code.
• Bij de ontwikkeling van toepassingen hoeft u geen gebruik te maken van laag-niveautalen zoals C of C++. U hoeft niet de complexe laag-niveau-API's te beheren die specifiek zijn voor ieder besturingssysteem.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 7 Inleiding tot Adobe AIR
Bij de ontwikkeling van toepassingen voor AIR kunt u gebruikmaken van een zeer uitgebreide set bestaande frameworks en API's:
• API's die specifiek zijn voor AIR en die worden geleverd door de runtime en het AIR-framework • ActionScript-API's die worden gebruikt in SWF-bestanden en Flex-frameworks (evenals andere ActionScriptgebaseerde bibliotheken en frameworks)
• HTML, CSS en JavaScript • De meeste Ajax-frameworks AIR zorgt voor een enorme verandering in de manier waarop toepassingen kunnen worden gemaakt, geïmplementeerd en ervaren. U krijgt meer creatieve controle en kunt uw Flash-, Flex-, HTML- en Ajax-gebaseerde toepassingen uitbreiden naar de desktop zonder dat u de traditionele desktopontwikkeltechnologieën hoeft te leren.
Nieuw in AIR 1.1 Adobe AIR 1.1 heeft de volgende nieuwe functies geïntroduceerd:
• Installatiedialoogvensters en andere runtime dialoogvensters zijn vertaald naar de volgende talen: • Portugees (Braziliaans) • Chinees (Traditioneel en Vereenvoudigd) • Frans • Duits • Italiaans • Japans • Koreaans • Russisch • Frans • Spaans • Ondersteuning voor het maken van internationale toepassingen, waaronder toetsenbordinvoer voor doublebytetalen. Zie “AIR-toepassingen lokaliseren” op pagina 351.
• Ondersteuning voor de vertaling van de naam- en beschrijvingskenmerken in het toepassingsdescriptorbestand. • Ondersteuning voor de vertaling van foutberichten, zoals SQLError.detailID en SQLError.detailArguments, in de SQLite-database.
• Toevoeging van de eigenschap Capabilities.languages om een array met voorkeurstalen voor de gebruikersinterface te verkrijgen zoals deze door het besturingssysteem zijn ingesteld.
• HTML-knoplabels en standaardmenu's, zoals snelmenu's en de Mac-menubalk, zijn vertaald naar alle ondersteunde talen.
• Ondersteuning voor certificaatmigratie van een zelfondertekende toepassing naar een toepassing die is gekoppeld aan een certificeringsinstantie (CA).
• Ondersteuning voor Microsoft Windows XP Tablet PC Edition en ondersteuning voor de 64-bits edities van Windows Vista® Home Premium, Business, Ultimate of Enterprise.
• Toevoeging van File.spaceAvailable-API om op te halen hoeveel schijfruimte beschikbaar is op een schijf.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 8 Inleiding tot Adobe AIR
• Toevoeging van de eigenschap NativeWindow.supportsTransparency om te bepalen of een venster door het huidige besturingssysteem als transparant kan worden getekend. Voor meer informatie over de AIR 1.1-versie raadpleegt u de Adobe AIR 1.1 Release-notities (http://www.adobe.com/go/learn_air_relnotes_nl).
Nieuw in AIR 1.5 Adobe AIR 1.5 heeft de volgende nieuwe functies geïntroduceerd:
• Ondersteuning voor de volgende functies van Flash Player 10. • Aangepaste filters en effecten • Uitgebreide teken-API • Dynamisch genereren van geluid • Gegevenstype Vector • Uitgebreide API's voor het uploaden en downloaden van bestanden • Real Time Media Flow Protocol (RTMFP) • 3D-effecten • Geavanceerde tekstondersteuning • Kleurbeheer • Tekstengine • Dynamische streaming • Speex-audiocodec Op http://www.adobe.com/products/flashplayer/features/ vindt u meer details over deze functies.
• Er worden meer talen ondersteund in het installatieprogramma en andere runtime dialoogvensters van AIR 1.5: Tsjechisch, Nederlands, Zweeds, Turks, Pools.
• Databasecodering. Databasebestanden kunnen in AIR 1.5 worden gecodeerd. Alle database-inhoud, inclusief de metagegevens, kan zo worden gecodeerd dat de gegevens onleesbaar zijn buiten de AIR-toepassing waarin ze zijn gecodeerd. Met deze functie kan een ontwikkelaar databasebestanden coderen, decoderen en opnieuw coderen. Zie “Gecodeerde gegevens opslaan” op pagina 220.
• De versie van WebKit die door Adobe AIR wordt gebruikt, is bijgewerkt, en bevat nu ondersteuning voor de JavaScript-interpreter SquirrelFish.
• Nieuwe XML-API's voor handtekeningvalidatie kunnen worden gebruikt om de integriteit en de identiteit van de ondergetekende van de gegevens of informatie te controleren. Zie XML-handtekeningvalidatie. Voor meer informatie over de AIR 1.5-versie raadpleegt u de Adobe AIR 1.5 Release-notities (http://www.adobe.com/go/learn_air_relnotes_nl).
9
Hoofdstuk 4: AIR-bronnen zoeken Raadpleeg de volgende bronnen voor meer informatie over het ontwikkelen van Adobe® AIR™-toepassingen: Bron
Artikelen, voorbeelden en presentaties door Adobe en community-specialisten kunt u vinden in Adobe AIR Developer Connection op http://www.adobe.com/devnet/air/. Hier kunt u ook Adobe AIR en verwante software downloaden. Een sectie speciaal voor Flash-ontwikkelaars kunt u vinden op http://www.adobe.com/devnet/air/flash/. Bezoek de Adobe-ondersteuningssite op http://www.adobe.com/support/ om problemen met uw product op te lossen en alles te leren over gratis en betaalde technische ondersteuningsmogelijkheden. Volg de koppeling Training voor toegang tot boeken van Adobe Press, uiteenlopende opleidingsbronnen, certificeringsprogramma's voor Adobesoftware en nog veel meer.
10
Hoofdstuk 5: Uw eerste AIR-applicatie maken met Flash CS3 of CS4 Voor een snelle, praktische demonstratie van de werking van Adobe® AIR™ volgt u de aanwijzingen in dit onderwerp om een eenvoudige “Hello World” AIR-toepassing te maken en te comprimeren met Adobe® Flash® CS3 Professional. Download en installeer de Adobe AIR-update voor Flash CS3 mocht u dit nog niet hebben gedaan. Voor meer informatie over de installatie van Adobe AIR voor Flash CS3, kunt u “Installatie van Flash CS3 voor Adobe AIR” op pagina 3 raadplegen. Als u Adobe® Flash® CS4 Professional gebruikt, is ondersteuning voor Adobe AIR al ingebouwd, zodat u niets hoeft te installeren om aan de slag te gaan.
De Hello World-toepassing in Flash maken Een Adobe AIR-toepassing in Flash maken, is vergelijkbaar met het maken van iedere andere FLA-toepassing. In dit geval begint u echter met het maken van een Flash-bestand (Adobe AIR) vanuit het welkomscherm en u eindigt met het aanmaken van de toepassings- en installer-instellingen, en het installeren van uw AIR-toepassing. De volgende procedure leidt u door het aanmaakproces van een eenvoudige Hello World-toepassing met behulp van Flash CS3 of Flash CS4. De Hello World-toepassing aanmaken 1 Start Flash. 2 In het welkomscherm klikt u op Flash-bestand (Adobe AIR) om een leeg FLA-bestand aan te maken met Adobe
AIR-publicatie-instellingen. 3 Klik op OK om te reageren op het overzichtsdialoogvenster, Ontwerpomgeving voor Adobe AIR met Flash CS3.
Het duurt de eerste keer een paar minuten voordat dit dialoogvenster verschijnt. (Dit dialoogvenster wordt niet weergegeven in Flash CS4.) 4 Selecteer Tekstgereedschap in het venster Gereedschappen en maak een statisch tekstveld (standaard) in het
midden van de stage. Maak het breed genoeg zodat het 15 -20 tekens kan bevatten. 5 Typ de tekst “Hello World” in het tekstveld. 6 Sla het bestand op met een naam (bijvoorbeeld, helloAIR).
De toepassing testen 1 Druk op Ctrl + Enter of selecteer Control ->Test Movie om de toepassing te testen in Adobe AIR. 2 Om de functie Debug Movie te gebruiken, voegt u eerst de ActionScript-code toe aan de toepassing. U kunt dit snel
proberen door als volgt een trace statement toe te voegen: trace("Running AIR application using Debug Movie");
3 Druk op Ctrl + Shift + Enter, of selecteer Control->Debug Movie om de toepassing met Debug Movie uit te voeren.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 11 Uw eerste AIR-applicatie maken met Flash CS3 of CS4
4 Selecteer Commands > AIR - toepassingen en Installer-instellingen om het dialoogvenster AIR - Toepassing &
Installer-instellingen te openen. In Flash CS4 kunt u dit dialoogvenster openen door Bestand > AIR-instellingen te kiezen.
5 Onderteken het Adobe AIR-pakket met een zelfondertekend digitaal certificaat: a Klik op de knop Instellen… zodat de prompt Digitale handtekening het dialoogvenster Digitale handtekening
kan openen. b Klik op de knop Maken... om het dialoogvenster Zelfondertekend digitaal certificaat maken te openen c Vul de volgende velden in: Naam uitgever, Afdeling organisatie, Naam organisatie, E-mail, Land, Wachtwoord,
en Wachtwoord bevestigen. d Geef het soort certificaat op. Het soort certificaat houdt verband met het niveau van beveiliging: 1024-RSA
gebruikt een 1024-bit-code (minder veilig), en 2048-RSA gebruikt een 2048-bit-code (veiliger). e Sla de gegevens op in een certificaatbestand via Opslaan als, of door te klikken op de knop Bladeren... om naar
een maplocatie te gaan. (Bijvoorbeeld, C:/Temp/mycert.pfx). Klik als u klaar bent op OK. f
Flash leidt u terug naar het dialoogvenster Digitale handtekening. Het pad en de bestandsnaam van het zelfondertekende certificaat dat u hebt gemaakt, verschijnt in het tekstvak Certificaat. Indien dit niet het geval is, voert u het pad en de bestandsnaam in of klikt u op de knop Bladeren om het te zoeken en te selecteren.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 12 Uw eerste AIR-applicatie maken met Flash CS3 of CS4
g Typ hetzelfde wachtwoord als in stap c in het tekstveld Wachtwoord van het dialoogvenster Digitale
handtekening en klik op OK. Voor meer informatie over het ondertekenen van uw Adobe AIR-toepassingen raadpleegt u “Uw toepassing ondertekenen” op pagina 21. 6 Om het toepassings- en installerbestand aan te maken, klikt u op de knop AIR-bestand publiceren. U moet Test
Movie of Debug Movie uitvoeren om het SWF-bestand en de .xml-bestanden van de toepassing aan te maken voordat u het AIR-bestand aanmaakt. 7 Om de toepassing te installeren, dubbelklikt u op het AIR-bestand (toepassing.air) in dezelfde map waarin u uw
toepassing hebt opgeslagen. 8 Klik op de knop Installeren in het dialoogvenster Toepassing installeren. 9 Controleer de installatievoorkeuren en de locatie-instellingen en zorg dat het vakje ‘Toepassing opstarten na
installatie’ is aangevinkt. Klik vervolgens op Doorgaan. 10 Als het bericht Installatie voltooid verschijnt, klikt u op Afsluiten.
De toepassing Hello World ziet er als volgt uit:
Een FLA-toepassing converteren naar een Adobe AIRtoepassing U kunt een bestaand FLA-bestand ook converteren naar een AIR-toepassing. Voor meer informatie raadpleegt u “Adobe AIR-publicatie-instellingen installeren” op pagina 13. Als u Flash CS4 gebruikt, zie dan Publishing for Adobe AIRin Using Flash voor meer informatie.
13
Hoofdstuk 6: Adobe AIR-update voor Flash CS3 Professional De Adobe® AIR™-update voor Adobe® Flash® CS3 Professional vult de ontwerpomgeving aan waardoor u Adobe AIRtoepassingen met Flash kunt aanmaken, debuggen en comprimeren. De procedure voor het aanmaken van een Adobe AIR-toepassing bestaat uit het creëren van een Adobe AIR FLA-bestand, het installeren van de juiste publicatieinstellingen, het ontwikkelen van de toepassing, en het aanmaken van de toepassings- en installer-bestanden zodat u met de bestanden kunt werken. Als u Adobe® Flash® CS4 Professional gebruikt, kunt u naar Publishing for Adobe AIRin Using Flash gaan voor meer informatie over AIR-toepassingen. Voor informatie over de Adobe AIR ActionScript®3.0 API's die u kunt gebruiken in uw toepassing, raadpleegt u op de verwijzing ActionScript 3.0 Taal en Componenten. Voor een lijst met Adobe AIR ActionScript API's raadpleegt u “Functionaliteit die specifiek is voor Adobe AIR” op pagina 55. Opmerking: Om gebruik te maken van klassen in het air.net-pakket, sleept u eerst het ServiceMonitorShim -component vanuit het venster Componenten naar het venster Bibliotheek en voegt u vervolgens de volgende import-verklaring toe aan uw ActionScript 3.0-code: import air.net.*;
Een Adobe AIR-bestand aanmaken U kunt Flash-bestanddocumenten (Adobe AIR) aanmaken met behulp van het Flash-welkomscherm of een Flashbestand aanmaken (ActionScript 3.0) en dit converteren naar een Adobe AIR-bestand via het dialoogvenster Publicatie-instellingen. U kunt echter geen Adobe AIR-bestand aanmaken met het dialoogvenster Nieuw document (Bestand > Nieuw). Voor informatie over het converteren van een FLA-bestand naar een Adobe AIR-bestand, raadpleegt u “Adobe AIR-publicatie-instellingen installeren” op pagina 13. 1 Start Flash of, indien Flash reeds opgestart is, sluit u alle openstaande documenten om terug te keren naar het
welkomscherm. Opmerking: Als u het Flash-welkomscherm hebt uitgeschakeld, kunt u het opnieuw weergeven door Bewerken > Voorkeuren selecteren en Welkomscherm kiezen in het pop-upmenu On Launch van de rubriek Algemeen. 2 In het welkomscherm klikt u op Flash-bestand (Adobe AIR).
Er verschijnt een waarschuwingsbericht waarin wordt gemeld hoe u de Adobe AIR-toepassingsinstellingen en de Help-documentatie kunt openen. U kunt dit waarschuwingsbericht in het vervolg overslaan door het selectievakje Niet meer weergeven in te schakelen, maar er is geen manier om het daarna opnieuw te laten weergeven.
Adobe AIR-publicatie-instellingen installeren Gebruik de Flash-publicatie-instellingen om de instellingen voor een AIR-bestand te onderzoeken en te wijzigen en om een Flash-bestandsdocument (ActionScript 3.0) naar een Flash-bestandsdocument (Adobe AIR) te converteren.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 14 Adobe AIR-update voor Flash CS3 Professional
Adobe AIR-publicatie-instellingen weergeven 1 Open vanuit het Flash-welkomscherm een Flash-bestandsdocument (Adobe AIR). 2 Selecteer Bestand > Publicatie-instellingen en klik op het tabblad Flash om de Adobe AIR-publicatie-instellingen
weer te geven. Adobe AIR 1.0 wordt automatisch geselecteerd in het menu Versie wanneer u een Adobe AIR-document opent. De versie van ActionScript wordt automatisch ingesteld op ActionScript 3.0. De instelling Lokale afspeelbeveiliging is gedimd, omdat deze irrelevant is voor een AIR SWF-bestand. Als u een Flash FLA-bestand heeft geopend, kunt u dit converteren naar een Flash AIR-bestand door de publicatieinstellingen te wijzigen. Een Flash FLA-bestand converteren naar een Flash AIR-bestand met behulp van het dialoogvenster Publicatieinstellingen 1 Ga als volgt te werk:
• Open een bestaand FLA-bestand. • Gebruik het welkomscherm of selecteer Bestand > Nieuw om een FLA-bestand aan te maken. 2 Selecteer Bestand > Publicatie-instellingen. 3 Op het tabblad Flash selecteert u in het pop-upmenu Versie Adobe AIR 1.0.
De versie ActionScript is uitgeschakeld omdat ActionScript 3.0 de enige optie is voor een AIR-bestand. De resterende standaardopties zijn gelijk voor zowel een FLA-bestand als een Adobe AIR-bestand. 4 Klik op de knop Publiceren, en klik vervolgens op OK om het dialoogvenster Publicatie-instellingen af te sluiten.
De Property inspector geeft nu aan dat Adobe AIR 1 de Player target is als het gereedschap Selectie is geselecteerd. Opmerking: Wanneer u het Adobe AIR 1.0-profiel kiest, voegt Flash automatisch de locatie van het AIR playerglobal.swc-bestand toe aan de Classpath-omgevingsvariabele. Het AIR playerglobal.swc-bestand biedt u de mogelijkheid om de ActionScript AIR API's te gebruiken. Als u overschakelt van Adobe AIR 1 naar Adobe® Flash® Player 9 wordt Flash echter niet automatisch in het standaardprofiel ingesteld, of wordt de Classpath-instelling niet gewijzigd om de playerglobal.swc voor Flash Player 9 te gebruiken. Als u de publicatie-instellingen van Adobe AIR 1 naar Flash Player 9 wijzigt, moet u het publicatieprofiel instellen als standaard. Voor meer informatie over het dialoogvenster Publicatie-instellingen, raadpleegt u Flash gebruiken op www.adobe.com/go/learn_fl_using. Een Flash FLA-bestand converteren naar een Flash AIR-toepassing met behulp van het menu Opdrachten 1 Open uw Flash FLA-bestand. 2 Als u een nieuw Flash-bestand (ActionScript 3.0) opent, moet u het opslaan. Als u het niet opslaat, verschijnt er een
waarschuwing bij de volgende stap. 3 Selecteer Opdrachten > AIR - Toepassings- en Installer-instellingen.
Er verschijnt een waarschuwingsbericht waarin u wordt gevraagd of u het bestand wilt converteren naar Adobe AIR-publicatie-instellingen. 4 Klik op OK om het FLA-bestand te converteren naar Adobe AIR-publicatie-instellingen. Het dialoogvenster AIR -
Toepassings- en Installer-instellingen wordt weergegeven. Voor informatie over het dialoogvenster AIR - Toepassings- en Installer-instellingen raadpleegt u “AIRtoepassings- en installerbestanden aanmaken” op pagina 16.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 15 Adobe AIR-update voor Flash CS3 Professional
U kunt gebruikmaken van de opdrachten Film testen, Film debuggen, en AIR-bestand aanmaken op het geconverteerde AIR FLA-bestand.
Voorbeeld van een Adobe AIR-toepassing U kunt een voorbeeld bekijken van een Flash AIR SWF-bestand zoals het zal worden weergegeven in het AIRtoepassingsvenster. Een voorbeeld is nuttig wanneer u wilt zien hoe de zichtbare aspecten van de toepassing eruitzien zonder de toepassing te comprimeren en te installeren. 1 Zorg dat u de publicatie-instellingen hebt ingesteld voor een Adobe AIR-toepassing. Voor meer informatie
raadpleegt u “Adobe AIR-publicatie-instellingen installeren” op pagina 13. 2 Selecteer Beheer > Film testen of druk op Control+Enter.
Als u de toepassingsinstellingen niet hebt ingesteld via het dialoogvenster AIR - Toepassings- en Installerinstellingen genereert Flash voor u een descriptor-bestand in de standaardtoepassing (swfname-app.xml) in dezelfde map als de map waarin het SWF-bestand is geschreven. Als u de toepassingsinstellingen hebt ingesteld via het dialoogvenster AIR - Toepassings- en Installer-instellingen, geeft het descriptor-bestand van de toepassing die instellingen weer.
Het debuggen van een Adobe AIR-toepassing Het Adobe AIR SWF-bestand kan op dezelfde wijze worden gedebugged als een Flash Player 9 ActionScript 3.0 SWFbestand, behalve voor debuggen op afstand. 1 Zorg dat u de Adobe AIR-publicatie-instellingen hebt ingesteld. 2 Voeg de ActionScript-code toe aan het venster Acties (Window > Acties). Voor testing kunt u gewoon een trace()
statement zoals deze in het venster Acties toevoegen op het eerste frame van de Tijdslijn: trace("My application is running");
3 Selecteer Debuggen > Film debuggen of druk op Control+Shift+Enter.
Flash opent de ActionScript-debugger en exporteert het SWF-bestand met de debug-gegevens. Als u de toepassingsinstellingen niet hebt ingesteld via het dialoogvenster AIR - Toepassings- en Installerinstellingen genereert Flash voor u een descriptor-bestand in de standaardtoepassing (swfname-app.xml) in dezelfde map als de map waarin het SWF-bestand is geschreven. Als u de toepassingsinstellingen hebt ingesteld via het dialoogvenster AIR - Toepassings- en Installer-instellingen, geeft het descriptor-bestand van de toepassing die instellingen weer. Wanneer u Debuggen > Film debuggen selecteert of u drukt op Control+Shift+Enter om uw toepassing te debuggen, geeft Flash een waarschuwing weer als uw toepassing geen ActionScript-code heeft ingevoegd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 16 Adobe AIR-update voor Flash CS3 Professional
AIR-toepassings- en installerbestanden aanmaken Nadat u uw toepassing hebt voltooid, maakt u de AIR-toepassing en de installer-bestanden aan om deze te gebruiken. Adobe AIR voegt twee nieuwe menu's toe aan het Flash-opdrachtenmenu: AIR - Toepassings- en Installer-instellingen en AIR - AIR-bestand aanmaken. Nadat u de AIR-toepassing en installer-instellingen hebt aangemaakt, kunt u gebruikmaken van het item AIR-AIR-bestand aanmaken om het AIR-bestand (.air) opnieuw aan te maken met de bestaande instellingen. De Adobe AIR-toepassings- en installer-betanden aanmaken 1 In Flash opent u de pagina's of groep van pagina's die uw Adobe AIR-toepassing vormen. 2 Sla het Adobe AIR FLA-bestand op voordat u het dialoogvenster AIR - Toepassings- en Installer-instellingen opent. 3 Selecteer Opdrachten > AIR - Toepassings- en Installer-instellingen. 4 Vul het dialoogvenster AIR - Toepassings- en Installer-instellingen in, en klik vervolgens op AIR-bestand
publiceren. Als u klikt op de knop AIR-bestand publiceren worden de volgende bestanden gecomprimeerd: het FLA-bestand, het SWF-bestand, het descriptor-bestand van de toepassing, de bestanden van het toepassingspictogram, en de bestanden die worden weergegeven in het tekstvak Toegevoegde bestanden. Als u nog geen digitaal certificaat hebt aangemaakt, geeft Flash het dialoogvenster Digitale handtekening weer wanneer u op de knop AIR-bestand publiceren, klikt. Het dialoogvenster AIR - Toepassings en Installer-instellingen bestaat uit twee onderdelen: Toepassingsinstellingen en Installer-instellingen. Zie de volgende secties voor meer informatie over deze instellingen.
Toepassingsinstellingen De sectie toepassingsinstellingen van het dialoogvenster AIR - Toepassings- en Installer-instellingen heeft de volgende opties: Bestandsnaam De naam van het hoofdbestand van de toepassing. Standaardinstellingen voor de naam van het SWF-
bestand. Naam De naam die wordt gebruikt door de installer voor het genereren van de bestandsnaam van de toepassing en de
toepassingsmap. De naam mag enkel geldige tekens voor bestandsnamen of namen van mappen bevatten. Standaardinstellingen voor de naam van het SWF-bestand. Versie Optioneel. Geeft het versienummer op voor uw toepassing. Standaardinstelling is leeg. Id Identificeert uw toepassing met een unieke id. U kunt de standaard-id wijzigen als u dit wenst. Gebruik geen spaties of speciale tekens in de id. De enige geldige tekens zijn 0-9, a-z, A-Z, . (punt), en - (koppelteken), van 1 tot 212 tekens lang. Is standaard ingesteld op com.adobe.voorbeeld.toepassing_naam. Beschrijving Optioneel. Hiermee kunt u een beschrijving invoeren van de toepassing die wordt weergegeven wanneer de gebruiker de toepassing installeert. Standaardinstelling is leeg. Copyright Optioneel. Hiermee kunt u een copyright-melding invoeren die wordt weergegeven wanneer de gebruiker
de toepassing installeert. Vensterstijl Geeft aan welke vensterstijl (of chroom) u moet gebruiken voor de gebruikersinterface wanneer de gebruikers de toepassing uitvoeren op hun computer. U kunt Systeemchroom opgeven. Dit verwijst naar de visuele stijl die wordt gebruikt door het besturingssysteem. U kunt ook Aangepaste chroom (ondoorzichtig) of Aangepaste chroom (transparant) opgeven. Om uw toepassing zonder de systeemchroom weer te geven, selecteert u Geen. Systeemchroom omringt de toepassing met het standaard vensterbeheer van het besturingssysteem. Aangepaste
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 17 Adobe AIR-update voor Flash CS3 Professional
chroom (ondoorzichtig) elimineert de chroom van het standaardsysteem en laat u een eigen chroom creëren voor de toepassing. (U bouwt de aangepaste chroom rechtstreeks in het FLA-bestand.) Aangepaste chroom (transparant) is als Aangepaste chroom (ondoorzichtig), behalve dat het transparante capaciteiten toevoegt aan de randen van de pagina. Deze capaciteiten laten toepassingsvensters toe die niet vierkant of rechthoekig zijn. Pictogram Optioneel. Hiermee kunt u een pictogram voor de toepassing specificeren. Het pictogram wordt weergegeven nadat u de toepassing hebt geïinstalleerd en uitgevoerd in Adobe AIR. U kunt vier verschillende groottes opgeven voor het pictogram (128, 48, 32, en 16 pixels) om de verschillende weergaven waarin het pictogram verschijnt mogelijk te maken. Bijvoorbeeld, het pictogram kan worden weergegeven in de bestandsbrowser als thumbnail, gedetailleerd en naast elkaar. Het kan ook als bureaubladpictogram worden weergegeven, en in de titel van het AIRtoepassingsvenster, alsook op andere plaatsen.
De pictogramafbeelding is standaard ingesteld als een voorbeeld van een AIR-toepassingspictogram als er geen andere pictogrambestanden zijn opgegeven. Om een pictogram op te geven, klikt u op de knop Pictogramafbeeldingen selecteren in het To specify an icon, click the Select Icon Images button in het dialoogvenster AIR - Toepassings- en Installer-instellingen. In het dialoogvenster van de pictogramafbeeldingen dat wordt weergegeven, klikt u op de map voor elke pictogramgrootte en selecteert u het pictogrambestand dat moet worden gebruikt. De bestanden moeten in PNG-formaat (Portable Network Graphics) zijn. Volgende illustraties geven het dialoogvenster weer van de pictogramafbeeldingen met de standaard Adobe AIRtoepassingspictogrammen.
Verschillende groottes van de pictogramafbeeldingen van de toepassing opgeven
Als u een afbeelding opgeeft, moet het de exacte grootte hebben (128x128, 48x48, 32x32, of 16x16). Als u geen afbeelding opgeeft voor een bepaalde pictogramgrootte, past Adobe AIR een van de meegeleverde afbeeldingen aan om de ontbrekende pictogramafbeelding aan te maken.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 18 Adobe AIR-update voor Flash CS3 Professional
Geavanceerde instellingen Met de knop Instellingen in het dialoogvenster AIR - Toepassings- en Installer-instellingen kunt u geavanceerde instellingen opgeven voor het descriptor-bestand van de toepassing. Wanneer u op de knop Instellingen klikt, wordt het dialoogvenster Geavanceerde instellingen weergegeven. Met het dialoogvenster Geavanceerde instellingen kunt u geassocieerde bestandtypes opgeven die de toepassing moet behandelen. Bijvoorbeeld, als u wilt dat uw toepassing de hoofdtoepassing wordt voor het behandelen van HTMLbestanden, moet u dit opgeven in het tekstvak Geassocieerde bestandstypes. U kunt ook instellingen opgeven voor de volgende aspecten van de toepassing:
• De grootte en plaatsing van het initiële venster • De map waarin de toepassing is geïnstalleerd • De map met het Programmamenu waarin de toepassing moet worden geplaatst Het dialoogvenster heeft de volgende opties: Geassocieerde bestandstypes Hiermee kunt u de geassocieerde bestandstypes opgeven die de AIR-toepassing
behandelt. Klik op de knop Plus (+) om een nieuw bestandstype toe te voegen aan het tekstvak. Wanneer u op de Plusknop drukt wordt het dialoogvenster Instellingen van bestandstype weergegeven. Wanneer u klikt op de knop Min () wordt een item dat is geselecteerd in het tekstvak verwijderd. Wanneer u klikt op de knop Potlood wordt het dialoogvenster Instellingen van bestandstype weergegeven en kunt u een item dat u hebt geselecteerd in het tekstvak bewerken. De knoppen Min (-) en Potlood zijn standaard uitgeschakeld. Door een item te selecteren in het tekstvak kunt u de knoppen Min (-) en Potlood inschakelen waardoor u het item kunt verwijderen of bewerken. De standaardwaarde in het tekstvak is Geen. Raadpleeg “Instellingen bestandstypen” op pagina 19 voor meer informatie over de instellingen van de bestandstypen voor geassocieerde bestanden. Initiële vensterinstellingen Hiermee kunt u de instellingen voor grootte en plaatsing van het initiële
toepassingsvenster opgeven.
• Breedte: Geeft de initiële breedte aan van het venster in pixels. De waarde is standaard leeg. • Hoogte: Geeft de initiële hoogte aan van het venster in pixels. De waarde is standaard leeg. • X: Geeft de initiële horizontale positie aan van het venster in pixels. De waarde is standaard leeg. • Y: Geeft de initiële verticale positie aan van het venster in pixels. De waarde is standaard leeg. • Maximumbreedte en maximunhoogte: Geven de maximumgrootte aan van het venster in pixels. Deze waarden zijn standaard leeg.
• Minimumbreedte en minimumhoogte: Geven de minimumgrootte aan van het venster in pixels. Deze waarden zijn standaard leeg.
• Vergrootbaar: Hiermee kunt u aangeven of de gebruiker het venster kan vergroten. Deze optie is standaard (of echt) geselecteerd.
• Verkleinbaar: Hiermee kunt u aangeven of de gebruiker het venster kan verkleinen. Deze optie is standaard (of echt) geselecteerd.
• Afmetingen wijzigen: Hiermee kunt u aangeven of de gebruiker de afmetingen van het venster kan wijzigen. Als deze optie niet is geselecteerd, zijn Maximumbreedte, Maximumhoogte, Minimumbreedte, en Minimumhoogte uitgeschakeld. Deze optie is standaard (of echt) geselecteerd.
• Zichtbaar: Hiermee geeft u aan of het toepassingsvenster initieel zichtbaar is. De optie is standaard (of echt) geselecteerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 19 Adobe AIR-update voor Flash CS3 Professional
Andere instellingen Hiermee geeft u de volgende bijkomende gegevens aan in verband met de installatie:
• Installatiemap: Geeft de map aan waarin de toepassing is geïnstalleerd. • Map met programmamenu: Geeft de naam aan van de map met het programmamenu voor de toepassing. • Aangepaste update UI: Geeft aan wat er gebeurt wanneer een gebruiker een AIR-bestand opent voor een toepassing die reeds is geïnstalleerd. Standaard geeft AIR een dialoogvenster weer waarmee de gebruiker de geïnstalleerde versie kan bijwerken met de versie in het AIR-bestand. Als u niet wilt dat de gebruiker een dergelijke beslissing neemt en dat de toepassing het volledige beheer heeft over zijn updates, dan selecteert u deze optie. Wanneer u deze optie selecteert wordt het standaardgedrag overschreven en krijgt de toepassing het beheer over zijn eigen updates. Raadpleeg “AIR-toepassingen updaten” op pagina 336 voor meer informatie over het programmatisch updaten van een AIR-toepassing.
Instellingen bestandstypen Flash geeft het dialoogvenster Instellingen van bestandstype weer als u klikt op de knop Plus (+) of de knop Potlood in het dialoogvenster met geavanceerde instellingen zodat geassocieerde bestandstypes van de toepassing kunnen worden toegevoegd of bewerkt. De enige twee verplichte velden in dit dialoogvenster zijn Naam en Extensie. Als u klikt op OK en een van beide velden is leeg, geeft Flash een dialoogvenster met een foutmelding weer. U kunt volgende instellingen opgeven voor een geassocieerd bestandstype: Naam De naam van het bestandstype (bijvoorbeeld, Hypertext Markup Language, Tekstbestand, of Voorbeeld). Extensie De extensie van de bestandsnaam (bijvoorbeeld, html, txt, of xmpl), tot 39 alfanumerieke basistekens, (A-Zaz0-9), en zonder een voorafgaande periode. Beschrijving Optioneel. Een beschrijving van het bestandstype (bijvoorbeeld, Adobe videobestand). inhoudstype Optioneel. Specificeert het MIME-type voor het bestand. Instellingen van het bestandstype-pictogram Optioneel. Hiermee kunt u een pictogram opgeven dat is gekoppeld aan
het bestandstype. U kunt vier verschillende groottes opgeven voor het pictogram (128x128, 48x48, 32x32, en 16x16 pixels) om de verschillende weergaven waarin het pictogram verschijnt mogelijk te maken. Bijvoorbeeld, het pictogram kan worden weergegeven in de bestandsbrowser als thumbnail, gedetailleerd en naast elkaar. Als u een afbeelding opgeeft, moet het de grootte hebben die u specificeert. Als u geen bestand opgeeft voor een bepaalde grootte gebruikt AIR de afbeelding van vergelijkbare grootte en past het de afmetingen aan wat is opgegeven aan. Om een pictogram op te geven, klikt u ofwel op de map voor de pictogramgrootte en selecteert u een pictogrambestand dat u wilt gebruiken, of u voert het pad en de bestandsnaam in voor het pictogrambestand in het tekstvak naast de prompt. Het pictogrambestand moet in PNG-formaat zijn. Nadat een nieuw bestandstype is aangemaakt, wordt dit weergegeven in het lijstvak Bestandstype in het dialoogvenster van de geavanceerde instellingen.
Instellingen van descriptor-bestand van toepassing De toepassinginstellingen die u opgeeft worden opgeslagen in het bestand toepassing_naam-app.xml. U hebt echter de keuze om in Flash aan te geven dat u een aangepast descriptor-bestand van de toepassing wilt gebruiken. Een aangepast descriptor-bestand van de toepassing gebruiken Hiermee kunt u bladeren naar een aangepast descriptor-bestand van de toepassing. Als u Aangepast descriptor-bestand van de toepassing gebruiken selecteert, wordt in het dialoogvenster de sectie met toepassingsinstellingen uitgeschakeld. Om de locatie op te geven van het aangepast descriptor-bestand van de toepassing, voert u het ofwel in in onderstaand tekstveld Aangepast descriptorbestand van de toepassing gebruiken, of klikt u op het mappictogram en gaat u naar de locatie. Raadpleeg “Een
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 20 Adobe AIR-update voor Flash CS3 Professional
aangepast descriptor-bestand van de toepassing aanmaken” op pagina 21 voor meer informatie over het descriptorbestand van de toepassing.
Installer-instellingen Het tweede deel van het dialoogvenster AIR - Toepassings- en Installer-instellingen bevat instellingen die betrekking hebben op de installatie van de toepassing. Digitale handtekening Alle Adobe AIR-toepassingen moeten worden ondertekend om te kunnen worden geïnstalleerd in een ander systeem. Raadpleeg “Uw toepassing ondertekenen” op pagina 21 voor meer informatie over het toewijzen van een digitale handtekening aan een Flash Adobe AIR-toepassing. Bestemming Geeft aan waar het AIR-bestand moet worden opgeslagen. De standaardlocatie is de directory waarin u
het FLA-bestand hebt opgeslagen. Klik op het pictogram van de map om een andere locatie te selecteren. De standaardpakketnaam is de naam van de toepassing met de bestandsnaamextensie .air. Bijgevoegde bestanden/mappen Geeft aan welke bijkomende bestanden en mappen bij uw toepassing moeten
worden gevoegd. Klik op de knop Plus (+) om bestanden toe te voegen en op de knop van de map om mappen toe te voegen. Om een bestand of map te verwijderen uit uw lijst selecteert u het bestand of de map en klikt u op de knop Min (-). Standaard worden het descriptor-bestand van de toepassing en het hoofd SWF-bestand automatisch toegevoegd aan de pakketlijst. De pakketlijst toont deze bestanden zelfs wanneer u het Adobe AIR FLA-bestand nog niet hebt gepubliceerd. De pakketlijst geeft de bestanden en mappen weer in een vlakke structuur. Bestanden in een map worden niet weergegeven, en volledige padnamen naar bestanden worden weergegeven maar kunnen indien nodig worden ingekort. Pictogrambestanden zijn niet opgenomen in de lijst. Wanneer Flash de bestanden comprimeert, worden de pictogrambestanden naar een tijdelijke map gekopieerd die gekoppeld is aan de locatie van het SWF-bestand. Flash wist de map nadat het comprimeren is voltooid.
Aanmaak van toepassings- en installer-bestanden mislukt De toepassings- en installer-bestanden worden in volgende gevallen niet aangemaakt:
• De toepassings-id-string heeft een onjuiste lengte of bevat ongeldige tekens. De toepassings-id-string mag 1 tot 212 tekens hebben en mag volgende tekens omvatten: 0-9, a-z, A-Z, . (punt), - (koppelteken).
• Bestanden in de installer-lijst bestaan niet. • De groottes van de aangepaste pictogrambestanden zijn niet correct. • De AIR-bestemmingsmap heeft geen schrijfrechten. • U hebt de toepassing niet getekend of u hebt niet opgegeven dat het een Adobe AIRI-toepassing betreft die later zal worden ondertekend.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 21 Adobe AIR-update voor Flash CS3 Professional
Een aangepast descriptor-bestand van de toepassing aanmaken Het descriptor-bestand van de toepassing is een XML-bestand dat u kunt bewerken met een tekstbewerker. Om een aangepast descriptor-bestand van de toepassing aan te maken, bewerkt u de waarden om aan te geven welke waarden u wenst. De standaardwaarden worden hier weergegeven:
• id = com.adobe.voorbeeld.swfname • fileName = swfname • name = swfname • versie = 1.0 • beschrijving = leeg • copyright = leeg • initialWindow • titel= naam • inhoud = swfname.swf • systemChrome = standaard, type = normaal • transparant = fout • zichtbaar = juist • pictogram • image128x128 = icons/AIRApp_128.png • image48x48 = icons/AIRApp_48.png • image32x32 = icons/AIRApp_32.png • image16x16 = icons/AIRApp_16.png • customUpdateUI = fout • allowBrowserInvocation = fout Raadpleeg “Eigenschappen van AIR-toepassingen instellen” op pagina 45 voor meer informatie over het descriptor-bestand van de toepassing.
Uw toepassing ondertekenen Alle Adobe AIR-toepassingen moeten worden ondertekend om te kunnen worden geïnstalleerd in een ander systeem. Flash biedt echter de mogelijkheid om niet ondertekende Adobe AIR-installer-bestanden aan te maken zodat de toepassing later kan worden ondertekend. Deze niet ondertekende Adobe AIR-installer-bestanden worden een AIRIpakket genoemd. Deze mogelijkheid wordt gebruikt in gevallen waarbij het certificaat zich op een ander toestel bevindt, of wanneer ondertekenen niet samen met de toepassingsontwikkeling wordt behandeld.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 22 Adobe AIR-update voor Flash CS3 Professional
Onderteken een Adobe AIR-toepassing met een vooraf aangekocht digitaal certificaat van een basis certificaatautoriteit 1 Klik op de knop Digitale handtekening instellen in het dialoogvenster AIR - Toepassings en Installer-instellingen. Het dialoogvenster Digitale handtekening wordt geopend. Dit dialoogvenster heeft twee radioknoppen waarmee u uw Adobe AIR-toepassing kunt ondertekenen met een digitaal certificaat of waarmee u een AIRI-pakket kunt voorbereiden. Als u uw AIR-toepassing ondertekent, kunt u ofwel een digitaal certificaat gebruiken dat werd toegewezen door een basiscertificaatautoriteit, of u kunt een zelfondertekend certificaat aanmaken. Een zelfondertekend certificaat is eenvoudig te maken, maar is niet zo veilig als een certificaat dat werd toegekend door een basiscertificaatautoriteit.
Dialoogvenster voor digitale handtekening voor het ondertekenen van een AIR-toepassing
2 Selecteer een certificaatbestand in het pop-upmenu of klik op de knop Bladeren om een certificaatbestand te
zoeken. 3 Selecteer het certificaat. 4 Voer een wachtwoord in. 5 Klik op OK.
Raadpleeg “AIR-bestanden digitaal ondertekenen” op pagina 328 voor meer informatie over het ondertekenen van uw AIR-toepassing. Een zelfondertekend digitaal certificaat maken 1 Klik op de knop Aanmaken. Het dialoogvenster Zelfondertekend digitaal certificaat maken, wordt geopend. 2 Vul volgende velden in: Naam uitgever, Afdeling organisatie, Naam organisatie, Land, Wachtwoord, en
Wachtwoord bevestigen. 3 Geef het soort certificaat op.
Het soort certificaat houdt verband met het niveau van beveiliging van het certificaat: 1024-RSA gebruikt een 1024bit-code (minder veilig), en 2048-RSA gebruikt een 2048-bit-code (veiliger). 4 Sla de gegevens op in een certificaatbestand via Opslaan als, of door te klikken op de knop Bladeren om naar een
maplocatie te gaan. 5 Klik op OK. 6 In het dialoogvenster Digitale handtekening voert u het wachtwoord in dat u hebt toegekend in de tweede stap van
deze procedure en klikt u op OK.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 23 Adobe AIR-update voor Flash CS3 Professional
Nadat u het digitale certificaat hebt ingesteld, wordt de knop Instellen veranderd in de knop Wijzigen. Om ervoor te zorgen dat Flash het wachtwoord dat u voor deze sessie heeft gebruikt onthoudt, klikt u op Wachtwoord onthouden voor deze sessie. Als de optie Tijdstempel niet geselecteerd is wanneer u op OK klikt, waarschuwt een dialoogvenster u dat de toepassing niet zal worden geïinstalleerd wanneer het digitale certificaat is verlopen. Als u op Ja klikt als antwoord op de waarschuwing, dan wordt de tijdstempel uitgeschakeld. Als u op Nee klikt, wordt de optie Tijdstempel automatisch geselecteerd en ingeschakeld. Raadpleeg “AIR-bestanden digitaal ondertekenen” op pagina 328 voor meer informatie over het maken van een zelfondertekend certificaat. U kunt ook een AIR Intermediate-toepassing (AIRI) aanmaken zonder een digitale handtekening. Een gebruiker kan de toepassing echter niet op een bureaublad installeren zolang u geen digitale handtekening hebt toegevoegd. Een AIRI-pakket voorbereiden dat later zal worden ondertekend ❖ In het dialoogvenster Digitale handtekening selecteert u Een AIRI-pakket voorbereiden dat later zal worden ondertekend, en vervolgens klikt u op OK. De status van de digitale handtekening wordt gewijzigd om aan te geven dat u ervoor hebt gekozen een AIRI-pakket voor te bereiden dat later zal worden ondertekend; en de knop Instellen verandert in de knop Wijzigen.
24
Hoofdstuk 7: Beveiliging in AIR In dit onderwerp worden beveiligingsproblemen besproken die u in acht moet nemen bij het ontwikkelen van een AIR-toepassing.
Basisbeginselen van beveiliging in AIR AIR-toepassingen worden met dezelfde gebruikersrechten als native toepassingen uitgevoerd. Over het algemeen bieden deze toegangsrechten brede toegang tot functies van het besturingssysteem, zoals het lezen en schrijven van bestanden, het starten van toepassingen, het tekenen op het scherm en het communiceren met het netwerk. Beperkingen van het besturingssysteem die gelden voor native toepassingen, zoals gebruikersspecifieke rechten, gelden ook voor AIR-toepassingen. Het beveiligingsmodel van Adobe® AIR™ is weliswaar een evolutie van het beveiligingsmodel van Adobe® Flash® Player maar het beveiligingscontract verschilt van het contract dat op inhoud in een browser wordt toegepast. Dit contract biedt ontwikkelaars een veilige manier om te beschikken over een bredere functionaliteit voor interessante ervaringen, met een vrijheid die niet geschikt is voor browsertoepassingen. AIR-toepassingen worden geschreven in gecompileerde bytecode (SWF-inhoud) of met geïnterpreteerde scripts (JavaScript, HTML), zodat de runtime geheugenbeheer biedt. Dit beperkt de kwetsbaarheid van AIR-toepassingen voor geheugenbeheerproblemen zoals buffer overflow en gegevensbeschadiging. Hieronder ziet u een aantal van de meest voorkomende problemen bij desktoptoepassingen die in native code zijn geschreven.
Installatie en updates AIR-toepassingen worden gedistribueerd via AIR-installatiebestanden met de extensie air. Wanneer Adobe AIR wordt geïnstalleerd en een AIR-installatiebestand wordt geopend, beheert de runtime de installatiemethode. Opmerking: Ontwikkelaars kunnen een versie, toepassingsnaam en uitgeversbron opgeven maar de initiële workflow zelf van de toepassingsinstallatie kan niet worden gewijzigd. Deze beperking is nuttig voor de gebruiker omdat hierdoor alle AIR-toepassingen dezelfde veilige, gestroomlijnde en consistente installatiemethode hebben, die door de runtime wordt beheerd. Als een toepassing moet worden aangepast, kan dit plaatsvinden wanneer de toepassing de eerste keer wordt gestart.
Installatielocatie van runtime Voor AIR-toepassingen moet eerst de runtime op de computer van de gebruiker worden geïnstalleerd, zoals voor SWF-bestanden eerst de Flash Player plug-in voor de browser moet worden geïnstalleerd. De runtime wordt op de volgende locatie op de computer van de gebruiker geïnstalleerd:
• Mac OS: /Library/Frameworks/ • Windows: C:\Program • Linux: /opt/Adobe
Files\Common Files\Adobe AIR
AIR/
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 25 Beveiliging in AIR
Als een gebruiker in Mac OS een recentere versie van een toepassing wil installeren, moet de gebruiker over voldoende toegangsrechten beschikken om te installeren in de toepassingsmap. In Windows en Linux moet de gebruiker over beheerdersrechten beschikken. De runtime kan op twee manieren worden geïnstalleerd: met behulp van de naadloze installatiefunctie (installatie rechtstreeks vanuit een webbrowser) of via een handmatige installatie. Zie “AIR-toepassingen distribueren, installeren en uitvoeren” op pagina 319voor meer informatie.
Naadloze installatie (runtime en toepassing) De naadloze installatiefunctie biedt ontwikkelaars een gestroomlijnde installatiemethode voor gebruikers die Adobe AIR nog niet hebben geïnstalleerd. Bij de naadloze installatiemethode maakt de ontwikkelaar een SWF-bestand dat de te installeren toepassing opgeeft. Wanneer de gebruiker op het SWF-bestand klikt om de toepassing te installeren, probeert het SWF-bestand de runtime te detecteren. Als de runtime niet kan worden gedetecteerd, wordt deze geïnstalleerd en onmiddellijk gestart met de installatiemethode voor de toepassing van de ontwikkelaar.
Handmatige installatie De gebruiker kan echter ook de runtime handmatig downloaden en installeren vooraleer een AIR-bestand te openen. In dat geval beschikt de ontwikkelaar over verschillende manieren om een AIR-bestand te distribueren (bijvoorbeeld via e-mail of een HTML-koppeling op een website). Nadat het AIR-bestand is geopend, begint de runtime de toepassing te installeren. Zie “AIR-toepassingen distribueren, installeren en uitvoeren” op pagina 319voor meer informatie over deze methode.
Installatieflow van toepassing Het beveiligingsmodel van AIR biedt de gebruiker de keuze om een AIR-toepassing al dan niet te installeren. De installatiemethode van AIR biedt meerdere voordelen ten opzichte van native installatietechnologieën voor toepassingen, wat het maken van dit vertrouwensbesluit vergemakkelijkt voor de gebruiker:
• De runtime biedt een consistente installatiemethode in alle besturingssystemen, zelfs als een AIR-toepassing via een koppeling in een webbrowser wordt geïnstalleerd. De meeste native installatiemethoden voor toepassingen zijn afhankelijk van de browser of een andere toepassing voor het leveren van beveiligingsinformatie en in sommige gevallen wordt zelfs helemaal geen beveiligingsinformatie geleverd.
• De AIR-installatiemethode voor toepassingen identificeert de bron van de toepassing en informatie over de toegangsrechten van de toepassing (mits de gebruiker de installatie laat plaatsvinden).
• De runtime beheert de installatiemethode van een AIR-toepassing. Een AIR-toepassing heeft geen controle over de installatiemethode die door de runtime wordt gebruikt. De gebruiker wordt doorgaans niet aangeraden desktoptoepassingen te installeren die afkomstig zijn van een nietvertrouwde bron of een bron die niet kan worden gecontroleerd. De bewijslast op het gebied van veiligheid bij native toepassingen geldt ook voor AIR-toepassing en andere installeerbare toepassingen.
Doellocatie van toepassing De installatiedirectory kan worden ingesteld met een van de volgende twee opties: 1 De gebruiker kiest de doellocatie tijdens de installatie. De toepassing wordt geïnstalleerd op de locatie die door de
gebruiker is opgegeven.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 26 Beveiliging in AIR
2 Als de gebruiker de standaard installatielocatie niet wijzigt, wordt de toepassing geïnstalleerd volgens het
standaardpad dat door de runtime wordt bepaald:
• Mac OS: ~/Applications/ • Windows XP en oudere versies: C:\Program
Files\
• Windows Vista: ~/Apps/ • Linux: /opt/ Als de ontwikkelaar in het descriptorbestand van de toepassing een waarde opgeeft voor installFolder, wordt de toepassing geïnstalleerd in een subpad van deze directory.
Bestandssysteem van AIR Tijdens de installatie van een AIR-toepassing worden alle bestanden die de ontwikkelaar in het installatiebestand van de AIR-toepassing heeft opgenomen, gekopieerd naar de lokale computer van de gebruiker. De geïnstalleerde toepassing bestaat uit:
• Windows: een directory met alle bestanden die in het installatiebestand van de AIR-toepassing zijn opgenomen. Tijdens de installatie van de AIR-toepassing maakt de runtime ook een EXE-bestand.
• Linux: Een map met alle bestanden die in het AIR-installatiebestand zijn opgenomen. De runtime maakt ook een BIN-bestand tijdens de installatie van de AIR-toepassing.
• Mac OS: een APP-bestand met de volledige inhoud van het installatiebestand van de AIR-toepassing. Dit kan worden geïnspecteerd met de opdracht Toon pakketinhoud in Finder. Tijdens de installatie van de AIR-toepassing maakt de runtime dit APP-bestand. AIR-toepassingen worden als volgt gestart:
• Windows: voer het bestand met de extensie .exe in de installatiemap of een snelkoppeling naar dit bestand uit (bijvoorbeeld in het menu Start of op het bureaublad).
• Linux: Het BIN-bestand starten in de installatiemap, de toepassing kiezen in het menu Toepassingen of uitvoeren vanuit een alias of koppeling op het bureaublad.
• Mac OS: voer het bestand met de extensie .app of een alias van dit bestand uit. Het bestandssysteem van de toepassing bevat ook subdirectory's betreffende de functie van de toepassing. Bijvoorbeeld: informatie die naar een gecodeerde lokale opslaglocatie wordt geschreven, wordt opgeslagen in een subdirectory in een directory met de naam van de toepassingsidentificatie.
Opslag van AIR-toepassing AIR-toepassingen hebben de vereiste rechten om te schrijven naar een willekeurige locatie op de vaste schijf van de gebruiker. Ontwikkelaars wordt echter aangeraden om het pad app-storage:/ voor lokale opslag van hun toepassing te gebruiken. Bestanden die vanuit een toepassing naar app-storage:/ worden geschreven, bevinden zich op een standaardlocatie die afhankelijk is van het besturingssysteem van de gebruiker:
• In Mac OS: de opslagdirectory van een toepassing is //Local
Store/, waarbij de
voorkeursmap van de gebruiker is, meestal: /Users/<user>/Library/Preferences
• In Windows: de opslagdirectory van een toepassing is \\Local
Store\, waarbij de CSIDL_APPDATA 'speciale map' van de gebruiker is, meestal: C:\Documents and Settings\< gebruiker>\Application Data
• In Linux: //Local
Store/, waarbij /home/< gebruiker>/.appdata is
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 27 Beveiliging in AIR
U hebt toegang tot de opslagdirectory voor toepassingen via de eigenschap air.File.applicationStorageDirectory. U kunt de inhoud ervan bekijken via de methode resolvePath() van de klasse File. Zie “Werken met het bestandssysteem” op pagina 109 voor meer informatie.
Adobe AIR updaten Wanneer de gebruiker een AIR-toepassing installeert waarvoor een recentere runtime is vereist, installeert de runtime automatisch de vereiste update. Voor het updaten van de runtime moet de gebruiker over beheerdersrechten voor de computer beschikken.
AIR-toepassingen updaten De ontwikkeling en distributie van software-updates is een van de grootste beveiligingsproblemen bij toepassingen in native code. De API van AIR biedt een mechanisme om dit risico te beperken: bij het starten kan de methode Updater.update() worden opgeroepen om een AIR-bestand te zoeken in een externe locatie. Als een update wordt gevonden, wordt het AIR-bestand gedownload en geïnstalleerd, en wordt de toepassing opnieuw gestart. Ontwikkelaars kunnen deze klasse niet alleen voor nieuwe functionaliteit gebruiken maar ook voor het bieden van oplossingen voor mogelijke beveiligingsproblemen. Opmerking: Ontwikkelaars kunnen de versie van een toepassing opgeven door de eigenschap version van het descriptorbestand van de toepassing in te stellen. AIR interpreteert de tekenreeks voor de versie helemaal niet. Met andere woorden, versie '3.0' wordt niet als recenter dan versie '2.0' beschouwd. De ontwikkelaar moet zorgen voor een correct versiebeheer. Zie “Eigenschappen definiëren in het descriptorbestand van de toepassing” op pagina 46voor meer informatie.
AIR-toepassingen verwijderen AIR-toepassingen worden als volgt verwijderd:
• In Windows: via het onderdeel Software van het Configuratiescherm. • In Mac OS: door het bestand met de extensie .app uit de installatiedirectory te verwijderen. Bij het verwijderen van een AIR-toepassing worden alle bestanden uit de toepassingsmap verwijderd. Eventuele bestanden die de toepassing buiten de toepassingsmap heeft gemaakt, worden echter niet verwijderd. Bij het verwijderen van een AIR-toepassing worden eventuele wijzigingen die de AIR-toepassing heeft aangebracht in bestanden buiten de toepassingsmap, niet ongedaan gemaakt.
Adobe AIR verwijderen AIR wordt als volgt verwijderd:
• In Windows: door het onderdeel Software van het Configuratiescherm te openen, Adobe AIR te selecteren en op de knop Verwijderen te klikken.
• In Mac OS: door de toepassing Adobe AIR Uninstaller in de directory Applications uit te voeren.
Windows-registerinstellingen voor beheerders In Windows kunnen beheerders een computer zo configureren dat de installatie van AIR-toepassingen en het uitvoeren van runtime-updates (niet) is toegestaan. Deze instellingen staan in het Windows-register onder de sleutel HKLM\Software\Policies\Adobe\AIR. De instellingen zijn onder andere:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 28 Beveiliging in AIR
Registerinstelling
Beschrijving
AppInstallDisabled
Geeft aan of het installeren en verwijderen van AIR-toepassingen is toegestaan. Zet op 0 voor 'toegestaan' of op 1 voor 'niet toegestaan'.
UntrustedAppInstallDisabled
Geeft aan of de installatie van niet-vertrouwde AIR-toepassingen (toepassingen die geen vertrouwd certificaat bevatten) is toegestaan (zie “AIR-bestanden digitaal ondertekenen” op pagina 328). Zet op 0 voor 'toegestaan' of op 1 voor 'niet toegestaan'.
UpdateDisabled
Geeft aan of het updaten van de runtime is toegestaan, als achtergrondtaak of als deel van een expliciete installatie. Zet op 0 voor 'toegestaan' of op 1 voor 'niet toegestaan'.
Sandboxen AIR biedt een uitgebreide beveiligingsarchitectuur die rechten definieert voor elk bestand van een AIR-toepassing, zowel intern als extern. De rechten worden aan bestanden toegekend op basis van hun oorsprong en zijn verdeeld in logische beveiligingsgroepen die sandboxen worden genoemd.
Informatie over AIR-toepassingssandboxen Het runtime-beveiligingsmodel van sandboxen bestaat uit het beveiligingsmodel van Flash Player, waaraan de toepassingssandbox is toegevoegd. Voor bestanden die zich niet in de toepassingssandbox bevinden, gelden beveiligingsbeperkingen vergelijkbaar met de beperkingen uit het beveiligingsmodel van Flash Player. De runtime gebruikt deze beveiligingssandboxen om het gegevensbereik te definiëren waartoe code toegang heeft en de bewerkingen die door code mogen worden uitgevoerd. De lokale veiligheid blijft gegarandeerd doordat de bestanden in elke sandbox gescheiden zijn van de bestanden van andere sandboxen. Bijvoorbeeld: een SWF-bestand dat vanaf een externe internet-URL is geladen in een AIR-toepassing, wordt in een externe sandbox geplaatst en heeft standaard niet de vereiste toegangsrechten om scriptcode te schrijven in bestanden in de toepassingsmap, die zijn toegewezen aan de toepassingssandbox. De volgende tabel beschrijft de verschillende sandboxtypen: Sandbox
Beschrijving
toepassing
Het bestand bevindt zich in de toepassingsmap en heeft alle AIR-toegangsrechten.
extern
Het bestand is afkomstig van een internet-URL en werkt met domeingebaseerde sandboxregels vergelijkbaar met de regels die gelden voor externe bestanden in Flash Player. (Er zijn aparte externe sandboxen voor elk netwerkdomein, zoals http://www.voorbeeld.com en https://foo.voorbeeld.org.)
lokaal-vertrouwd
Het bestand is een lokaal bestand en de gebruiker heeft het als vertrouwd gemarkeerd via Instellingsbeheer of met een Flash Player-vertrouwensconfiguratiebestand. Het bestand kan zowel van lokale gegevensbronnen lezen als met internet communiceren maar heeft niet alle AIRtoegangsrechten.
lokaal-met-netwerk
Het bestand is een lokaal SWF-bestand dat met een netwerktoewijzing is gepubliceerd maar niet expliciet door de gebruiker wordt vertrouwd. Het bestand kan met internet communiceren maar kan niet van lokale gegevensbronnen lezen. Deze sandbox is alleen beschikbaar voor SWF-inhoud.
lokaal-met-bestandssysteem
Het bestand is een lokaal scriptbestand dat niet met een netwerktoewijzing is gepubliceerd en niet expliciet door de gebruiker wordt vertrouwd. Dit geldt onder andere voor niet-vertrouwde JavaScriptbestanden. Het bestand kan van lokale gegevensbronnen lezen maar kan niet met internet communiceren.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 29 Beveiliging in AIR
Dit onderwerp is hoofdzakelijk gebaseerd op de toepassingssandbox en zijn relatie met andere sandboxen in de AIRtoepassing. Ontwikkelaars die inhoud gebruiken die is toegewezen aan andere sandboxen, wordt aangeraden aanvullende documentatie te lezen over het beveiligingsmodel van Flash Player. Raadpleeg het hoofdstuk "Flash Player-beveiliging" in de documentatie ActionScript 3.0 programmeren (http://www.adobe.com/go/flashcs4_prog_as3_security_nl) en het white paper Flash Player 9 Security (http://www.adobe.com/go/fp9_0_security) of het white paper Flash Player 10 Security (http://www.adobe.com/go/fp10_0_security_nl).
Toepassingssandbox Bij de installatie van een toepassing worden alle bestanden in het AIR-installatiebestand geïnstalleerd in een toepassingsmap op de computer van de gebruiker. Ontwikkelaars kunnen in de programmacode naar deze map verwijzen via het URL-schema app:/ (zie “URL-schema's van AIR gebruiken in URL's” op pagina 314). Alle bestanden in de toepassingsmapstructuur worden bij het starten van de toepassing aan de toepassingssandbox toegewezen. De inhoud van de toepassingssandbox heeft alle toegangsrechten die beschikbaar zijn voor een AIRtoepassing, zoals interactie met het lokale bestandssysteem. Vele AIR-toepassingen gebruiken alleen deze lokaal geïnstalleerde bestanden om de toepassing uit te voeren. AIRtoepassingen zijn echter niet beperkt tot de bestanden in de toepassingsmap; ze kunnen een willekeurig type bestand van een willekeurige bron laden. Dit geldt onder andere voor lokale bestanden op de computer van de gebruiker en bestanden op beschikbare externe bronnen, zoals op een lokaal netwerk of internet. Het type van de bestanden heeft geen invloed op de beveiligingsbeperkingen: geladen HTML-bestanden hebben dezelfde beveiligingsrechten als geladen SWF-bestanden van dezelfde bron. De inhoud van de toepassingsbeveiligingssandbox heeft toegang tot AIR API's die niet kunnen worden gebruikt door de inhoud van andere sandboxen. Voorbeeld: de eigenschap air.NativeApplication.nativeApplication.applicationDescriptor, die de inhoud van het descriptorbestand van de toepassing weergeeft, is beperkt tot de inhoud van de toepassingsbeveiligingssandbox. Een ander voorbeeld van een beperkte API is de klasse FileStream, die methoden voor het lezen van en schrijven naar het lokale bestandssysteem bevat. ActionScript API's die alleen beschikbaar zijn voor de inhoud van de toepassingsbeveiligingssandbox, zijn in de ActionScript 3.0 Language Reference for Adobe AIR gemarkeerd met het AIR-logo. Als deze API's in andere sandboxen worden gebruikt, genereert de runtime een SecurityError-fout. Bij HTML-inhoud (in een HTMLLoader-object) zijn alle AIR JavaScript API's (de API's die beschikbaar zijn via de eigenschap window.runtime, of via het object air bij het gebruik van het bestand AIRAliases.js) beschikbaar voor inhoud van de toepassingsbeveiligingssandbox. De HTML-inhoud van andere sandboxen heeft geen toegang tot de eigenschap window.runtime, zodat deze inhoud geen toegang heeft tot de AIR API's.
Beperkingen van JavaScript en HTML Voor de HTML-inhoud van de toepassingsbeveiligingssandbox zijn er beperkingen betreffende het gebruik van API's die tekenreeksen dynamisch in programmacode kunnen omzetten nadat de code is geladen. Hierdoor wordt voorkomen dat de toepassing onbedoeld code van niet-toepassingsbronnen (zoals mogelijk onveilige netwerkdomeinen) opneemt (en uitvoert). Een voorbeeld hiervan is het gebruik van de functie eval(). Zie “Codebeperkingen voor de inhoud van verschillende sandboxen” op pagina 33voor meer informatie.
Beperkingen betreffende img-tags in de inhoud van ActionScript-tekstvelden Om mogelijke phishingaanvallen te blokkeren worden img -tags in de HTML-inhoud van ActionScript TextFieldobjecten genegeerd in de SWF-inhoud van de toepassingsbeveiligingssandbox.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 30 Beveiliging in AIR
Beperkingen betreffende asfunction De inhoud van de toepassingssandbox kan geen gebruik maken van het protocol asfunction in de HTML-inhoud van ActionScript 2.0-tekstvelden.
Geen toegang tot niet-vluchtige cross-domain cache De SWF-inhoud van de toepassingssandbox kan geen gebruik maken van de cross-domain cache, een nieuwe functie vanaf Flash Player 9 Update 3. Met deze functie kan Flash Player de inhoud van componenten van het Adobe-platform opslaan in een niet-vluchtige cache en vervolgens op aanvraag opnieuw gebruiken in geladen SWF-inhoud (zodat de inhoud niet meerdere keren opnieuw hoeft te worden geladen).
Rechten van inhoud van niet-toepassingssandboxen Bestanden die vanaf een netwerk- of internetlocatie zijn geladen, worden toegewezen aan de externe remote sandbox. Bestanden die vanaf een locatie buiten de toepassingsmap zijn geladen, worden toegewezen aan de lokaalmet-bestandssysteem, lokaal-met-netwerk of lokaal-vertrouwde sandbox, afhankelijk van de manier waarop het bestand is aangemaakt en of de gebruiker het bestand als vertrouwd heeft gemarkeerd via de Global Settings Manager van Flash Player. Zie http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html voor meer informatie.
Beperkingen van JavaScript en HTML In tegenstelling tot de inhoud van de toepassingsbeveiligingssandbox kan JavaScript-inhoud van een niettoepassingsbeveiligingssandbox wel de functie eval() oproepen om op elk gewenst moment dynamisch gegenereerde code uit te voeren. Er gelden echter beperkingen voor JavaScript in een niettoepassingsbeveiligingssandbox. Onder andere:
• JavaScript-code in een niet-toepassingssandbox heeft geen toegang tot het object window.runtime, zodat deze code geen AIR API's kan uitvoeren.
• De inhoud van een niet-toepassingsbeveiligingssandbox kan standaard geen XMLHttpRequest-oproepen gebruiken om gegevens te laden van andere domeinen dan het domein waarvan de aanvraag afkomstig is. Toepassingscode kan niet-toepassingsinhoud hiervoor echter toestemming geven door een kenmerk allowCrossdomainXHR in te stellen in het containerframe of iframe. Zie “Scripting tussen de inhoud van verschillende domeinen” op pagina 36voor meer informatie.
• Er zijn beperkingen betreffende het oproepen van de JavaScript-methode window.open(). Zie “Beperkingen betreffende het oproepen van de JavaScript-methode window.open()” op pagina 36voor meer informatie. Zie “Codebeperkingen voor de inhoud van verschillende sandboxen” op pagina 33voor meer informatie.
Beperkingen betreffende het laden van CSS-, frame-, iframe- en img-elementen De HTML-inhoud van externe (netwerk-) beveiligingssandboxen kan alleen inhoud van het type CSS, frame, iframe of img vanaf externe domeinen (netwerk-URL's) laden. De HTML-inhoud van lokaal-met-bestandssysteem, lokaal-met-netwerk of lokaal-vertrouwde sandboxen kan alleen inhoud van het type CSS, frame, iframe of img uit lokale sandboxen (niet van toepassings- of netwerk-URL's) laden.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 31 Beveiliging in AIR
Beveiliging in HTML De runtime past regels toe en biedt mechanismen voor het verhelpen van mogelijke beveiligingsproblemen in HTML en JavaScript. Hierbij worden altijd dezelfde regels toegepast, ongeacht of uw toepassing hoofdzakelijk in JavaScript is geschreven of dat u de HTML- en JavaScript-inhoud in een SWF-toepassing laadt. De inhoud van de toepassingssandbox en de inhoud van de niet-toepassingsbeveiligingssandbox (zie “Sandboxen” op pagina 28) hebben verschillende rechten. Wanneer inhoud in een iframe of frame wordt geladen, biedt de runtime een veilig sandboxbridge-mechanisme, waardoor de inhoud van het frame of iframe veilig kan communiceren met de inhoud van de toepassingsbeveiligingssandbox. In dit onderwerp wordt de AIR HTML-beveiligingsarchitectuur besproken, evenals het gebruik van iframes, frames en de sandboxbridge voor het configureren van uw toepassing. Zie “JavaScript-beveiligingsfouten voorkomen” op pagina 240voor meer informatie.
Overzicht van het configureren van uw HTML-toepassing Frames en iframes bieden een handige structuur voor het indelen van HTML-inhoud in AIR. Met frames kunt u zowel gegevens persistent houden als veilig werken met externe inhoud. Aangezien HTML in AIR zijn normale, op pagina's gebaseerde indeling behoudt, wordt de HTML-omgeving volledig vernieuwd als het bovenste frame van de HTML-inhoud naar een andere pagina 'navigeert'. U kunt frames en iframes gebruiken om gegevenspersistentie in AIR te behouden, ongeveer op dezelfde manier als voor een webtoepassing in een browser. Als u de belangrijkste toepassingsobjecten in het bovenste frame plaatst, persisteren ze tot u het frame naar een nieuwe pagina laat navigeren. Gebruik subframes of -iframes om de overgangsdelen van de toepassing te laden en weer te geven. (Er zijn verschillende manieren om voor gegevenspersistentie te zorgen als aanvulling op of in plaats van frames. Bijvoorbeeld cookies, lokale gedeelde objecten, lokale bestandsopslag, gecodeerde bestandsopslag en lokale databaseopslag.) Aangezien HTML in AIR ook de normale vage grens tussen uitvoerbare code en gegevens heeft, plaatst AIR inhoud in het bovenste frame van de HTML-omgeving in de toepassingssandbox. Na de gebeurtenis load waarbij de pagina wordt geladen, beperkt AIR alle bewerkingen zoals eval() waarbij een tekenreeks kan worden geconverteerd naar een uitvoerbaar object. Deze beperking wordt altijd toegepast, zelfs als een toepassing geen externe inhoud laadt. Als HTML-inhoud deze beperkte bewerkingen mag uitvoeren, moet u frames of iframes gebruiken om de inhoud in een niet-toepassingssandbox te plaatsen. (Soms moet inhoud in een onderliggend sandboxframe worden uitgevoerd wanneer wordt gewerkt met JavaScript-toepassingsraamwerken die zijn gebaseerd op de functie eval().) Zie “Codebeperkingen voor de inhoud van verschillende sandboxen” op pagina 33voor de volledige lijst van JavaScriptbeperkingen in de toepassingssandbox. Aangezien HTML in AIR de mogelijkheid behoudt om externe, mogelijk onveilige inhoud te laden, past AIR een 'beleid van zelfde oorsprong' toe om de voorkomen dat de inhoud van een bepaald domein in contact komt met de inhoud van een ander domein. Als u contact tussen de inhoud van de toepassing en de inhoud van een ander domein wilt toestaan, kunt u een bridge creëren die fungeert als interface tussen een hoofd- en een subframe.
Relatie tussen hoofd- en subsandbox creëren AIR voegt de kenmerken sandboxRoot en documentRoot toe aan de HTML frame- en iframe-elementen. Met deze kenmerken kunt u de toepassingsinhoud behandelen alsof deze van een ander domein afkomstig is:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 32 Beveiliging in AIR
Attribuut
Beschrijving
sandboxRoot
De URL waarmee de sandbox en het domein worden bepaald waarin de frameinhoud wordt geplaatst. Het URL-schema file:, http: of https: moet worden gebruikt.
documentRoot
De URL waarvan de frame-inhoud moet worden geladen. Het URL-schema file:, app: of app-storage: moet worden gebruikt.
In het volgende voorbeeld wordt de inhoud van de sandboxsubdirectory van de toepassing zo geconfigureerd dat deze wordt uitgevoerd in de externe sandbox en het domein www.example.com: <iframe src="ui.html" sandboxRoot="http://www.example.com/local/" documentRoot="app:/sandbox/">
Bridge tussen hoofd- en een subframes in verschillende sandboxen of domeinen instellen AIR voegt de eigenschappen childSandboxBridge en parentSandboxBridge toe aan het window-object van een willekeurig subframe. Met deze eigenschappen kunt u bridges definiëren als interfaces tussen een hoofd- en een subframe. Elke bridge gaat in één richting: childSandboxBridge - met de eigenschap childSandboxBridge kan het subframe een interface toegankelijk maken voor de inhoud van het hoofdframe. Als u een interface toegankelijk wilt maken, stelt u de eigenschap childSandbox in op een functie of object in het subframe. Vervolgens hebt u toegang tot het object of de functie vanuit de inhoud van het hoofdframe. In het volgende voorbeeld ziet u hoe een script dat in een subframe wordt uitgevoerd, een object dat een functie en een eigenschap bevat, toegankelijk kan maken voor het hoofdframe: var interface = {}; interface.calculatePrice = function(){ return .45 + 1.20; } interface.storeID = "abc" window.childSandboxBridge = interface;
Als deze onderliggende inhoud zich bevindt in een iframe waaraan de id"child" is toegewezen, hebt u vanuit de bovenliggende inhoud toegang tot de interface door de eigenschap childSandboxBridge van het frame te lezen: var childInterface = document.getElementById("child").childSandboxBridge; air.trace(childInterface.calculatePrice()); //traces "1.65" air.trace(childInterface.storeID)); //traces "abc" parentSandboxBridge - met de eigenschap parentSandboxBridge kan het bovenliggende frame een interface toegankelijk maken voor de inhoud van het subframe. Als u een interface toegankelijk wilt maken, stelt u de eigenschap parentSandbox van het onderliggende frame in op een functie of object in het bovenliggende frame. Vervolgens hebt u toegang tot het object of de functie vanuit de inhoud van het onderliggende frame. In het volgende voorbeeld ziet u hoe een script dat in het bovenliggende frame wordt uitgevoerd, een object dat de functie Save bevat, toegankelijk kan maken voor een onderliggend frame: var interface = {}; interface.save = function(text){ var saveFile = air.File("app-storage:/save.txt"); //write text to file } document.getElementById("child").parentSandboxBridge = interface;
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 33 Beveiliging in AIR
Via deze interface kan de inhoud van het onderliggende frame bijvoorbeeld tekst opslaan in een bestand met de naam save.txt. De inhoud heeft echter geen andere toegang tot het bestandssysteem. Normaliter moet de toepassingsinhoud de kleinst mogelijke interface toegankelijk maken voor andere sandboxen. De onderliggende inhoud kan bijvoorbeeld de functie Save als volgt oproepen: var textToSave = "A string."; window.parentSandboxBridge.save(textToSave);
Als onderliggende inhoud een eigenschap van het object parentSandboxBridge probeert in te stellen, genereert de runtime een SecurityError-fout. Als bovenliggende inhoud een eigenschap van het object childSandboxBridge probeert in te stellen, genereert de runtime een SecurityError-fout.
Codebeperkingen voor de inhoud van verschillende sandboxen Zoals in de inleiding tot dit onderwerp, “Beveiliging in HTML” op pagina 31, is besproken, past de runtime regels toe en biedt deze mechanismen voor het verhelpen van mogelijke beveiligingsproblemen in HTML en JavaScript. De desbetreffende beperkingen staan in dit onderwerp. Als code deze beperkte API's probeert op te roepen, geeft de runtime de foutmelding weer dat er in de runtime van Adobe AIR een beveiligingsfout betreffende JavaScript-code in de toepassingsbeveiligingssandbox is opgetreden. Zie “JavaScript-beveiligingsfouten voorkomen” op pagina 240voor meer informatie.
Beperkingen betreffende het gebruik van de JavaScript-functie eval() en soortgelijke technieken Voor de HTML-inhoud van de toepassingsbeveiligingssandbox zijn er beperkingen betreffende het gebruik van API's die tekenreeksen dynamisch in programmacode kunnen omzetten nadat de code is geladen (nadat de gebeurtenis onload van het element body is verzonden en de handlerfunctie onload is voltooid). Hierdoor wordt voorkomen dat de toepassing onbedoeld code van niet-toepassingsbronnen (zoals mogelijk onveilige netwerkdomeinen) opneemt (en uitvoert). Als uw toepassing bijvoorbeeld tekenreeksgegevens van een externe bron gebruikt om naar de eigenschap innerHTML van een DOM-element te schrijven, bevat de tekenreeks mogelijk (JavaScript-) programmacode die onveilige bewerkingen kan uitvoeren. Tijdens het laden van de inhoud is er echter geen risico dat externe tekenreeksen in het DOM-element worden ingevoegd. Eén beperking betreft het gebruik van de JavaScript-functie eval(). Nadat code in de toepassingssandbox is geladen en de gebeurtenishandler onload is verwerkt, kunt u de functie eval() slechts met bepaalde beperkingen gebruiken. De volgende regels gelden voor het gebruik van de functie eval()nadat code is geladen uit de toepassingsbeveiligingssandbox:
• Expressies met literalen zijn toegestaan. Bijvoorbeeld: eval("null"); eval("3 + .14"); eval("'foo'");
• Objectliteralen zijn toegestaan, zoals in de volgende situatie: { prop1: val1, prop2: val2 }
• Setter/getters met objectliteralen zijn niet toegestaan, zoals in de volgende situatie: { get prop1() { ... }, set prop1(v) { ... } }
• Arrayliteralen zijn toegestaan, zoals in de volgende situatie: [ val1, val2, val3 ]
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 34 Beveiliging in AIR
• Expressies met het lezen van eigenschappen zijn niet toegestaan, zoals in de volgende situatie: a.b.c
• Het oproepen van functies is niet toegestaan. • Functiedefinities zijn niet toegestaan. • Het instellen van eigenschappen is niet toegestaan. • Functieliteralen zijn niet toegestaan. Tijdens het laden van de code, vóór de gebeurtenis onload, en tijdens de uitvoering van de gebeurtenishandlerfunctie onload gelden deze beperkingen echter niet voor de inhoud van de toepassingsbeveiligingssandbox. Bij de volgende code bijvoorbeeld treedt een fout op nadat code is geladen: eval("alert(44)"); eval("myFunction(44)"); eval("NativeApplication.applicationID");
Dynamisch gegenereerde code, zoals bij het oproepen van de functie eval(), zou een veiligheidsrisico zijn als deze toegang kreeg tot de toepassingssandbox. Een toepassing kan bijvoorbeeld onbedoeld een tekenreeks uitvoeren die is geladen vanaf een netwerkdomein en schadelijke code bevat. De code kan bijvoorbeeld bestanden op de computer van de gebruiker verwijderen of wijzigen. Of de inhoud van een lokaal bestand doorsturen naar een niet-vertrouwd netwerkdomein. Dynamische code kan op de volgende manieren worden gegenereerd:
• door het oproepen van de functie eval(); • door eigenschappen van het type innerHTML of DOM-functies te gebruiken om scripttags in te voegen die een script buiten de toepassingsmap laden;
• door eigenschappen van het type innerHTML of DOM-functies te gebruiken om scripttags in te voegen die inline code bevatten (in plaats van een script te laden via het kenmerk src);
• door het kenmerk src voor script tags zo in te stellen dat een JavaScript-bestand wordt geladen dat zich buiten de toepassingsmap bevindt;
• door het URL-schema javascript te gebruiken (zoals in href="javascript:alert('Test')"); • door de functie setInterval() of setTimeout() te gebruiken, waarbij de eerste parameter (die de functie asynchroon laat uitvoeren) een (te evalueren) tekenreeks en geen functienaam is (zoals in setTimeout('x = 4', 1000));
• door document.write() of document.writeln() op te roepen. Code in de toepassingsbeveiligingssandbox kan tijdens het laden van inhoud alleen deze methoden gebruiken. Deze beperkingen blokkeren het gebruik van eval() met JSON-objectliteralen niet. Hierdoor kan de inhoud van uw toepassing met de JSON JavaScript-bibliotheek werken. U kunt echter geen overbelaste JSON-code (met gebeurtenishandlers) gebruiken. Voor andere Ajax-frameworks en JavaScript-codebibliotheken moet u controleren of de code in het framework of de bibliotheek binnen deze beperkingen betreffende dynamisch gegenereerde code werkt. Als dat niet het geval is, neemt u alle inhoud die gebruikmaakt van het framework of de bibliotheek op in een niet-toepassingsbeveiligingssandbox. Zie “Rechten van inhoud van niet-toepassingssandboxen” op pagina 30en “Scripting tussen toepassings- en niettoepassingsinhoud” op pagina 41voor meer informatie. Adobe houdt een lijst bij van Ajax-frameworks waarvan bekend is dat ze de toepassingsbeveiligingssandbox ondersteunen. Ga hiervoor naar http://www.adobe.com/products/air/develop/ajax/features/.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 35 Beveiliging in AIR
In tegenstelling tot de inhoud van de toepassingsbeveiligingssandbox kan JavaScript-inhoud van een niettoepassingsbeveiligingssandbox wel de functie eval() oproepen om op elk gewenst moment dynamisch gegenereerde code uit te voeren.
Beperkingen betreffende de toegang tot AIR API's (voor niet-toepassingssandboxen) JavaScript-code in een niet-toepassingssandbox heeft geen toegang tot het object window.runtime, zodat deze code geen AIR API's kan uitvoeren. Als de inhoud van een niet-toepassingsbeveiligingssandbox de volgende code oproept, treedt een TypeError-fout op: try { window.runtime.flash.system.NativeApplication.nativeApplication.exit(); } catch (e) { alert(e); }
Het fouttype is TypeError (niet-gedefinieerde waarde) omdat de inhoud van de niet-toepassingssandbox het object window.runtime niet herkent en het als een niet-gedefinieerde waarde beschouwt. Als u runtime-functionaliteit toegankelijk wilt maken voor de inhoud van een niet-toepassingssandbox, gebruikt u een scriptbridge. Zie “Scripting tussen toepassings- en niet-toepassingsinhoud” op pagina 41voor meer informatie.
Beperkingen betreffende het gebruik van XMLHttpRequest-oproepen De HTML-inhoud van een toepassingsbeveiligingssandbox kan geen synchrone XMLHttpRequest-methoden gebruiken om gegevens van buiten de toepassingssandbox te laden tijdens het laden van de HTML-inhoud en tijdens de gebeurtenis onLoad. De HTML-inhoud van niet-toepassingsbeveiligingssandboxen kan standaard geen JavaScript XMLHttpRequestobject gebruiken om gegevens te laden van andere domeinen dan het domein waarvan de aanvraag afkomstig is. Een tag van het type frame of iframe kan een kenmerk van het type allowcrosscomainxhr bevatten. Als u dit kenmerk instelt op een waarde die niet leeg is, kan de inhoud van het frame of iframe het Javascript XMLHttpRequest-object gebruiken om gegevens te laden van andere domeinen dan het domein van de code waarvan de aanvraag afkomstig is: <iframe id="UI" src="http://example.com/ui.html" sandboxRoot="http://example.com/" allowcrossDomainxhr="true" documentRoot="app:/">
Zie “Scripting tussen de inhoud van verschillende domeinen” op pagina 36voor meer informatie.
Beperkingen betreffende het laden van CSS-, frame-, iframe- en img-elementen (voor de inhoud van niet-toepassingssandboxen) De HTML-inhoud van externe (netwerk-) beveiligingssandboxen kan alleen inhoud van het type CSS, frame, iframe of img uit externe sandboxen (netwerk-URL's) laden. De HTML-inhoud van lokaal-met-bestandssysteem, lokaal-met-netwerk of lokaal-vertrouwde sandboxen kan alleen inhoud van het type CSS, frame, iframe of img uit lokale sandboxen (niet van toepassings- of externe sandboxen) laden.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 36 Beveiliging in AIR
Beperkingen betreffende het oproepen van de JavaScript-methode window.open() Als een venster dat door het oproepen van de JavaScript-methode window.open() is gemaakt, de inhoud van een niet-toepassingsbeveiligingssandbox weergeeft, begint de titel van het venster met de titel van het hoofdvenster (vanwaaruit het nieuwe venster is geopend), gevolgd door een dubbele punt. U kunt geen code gebruiken om dat deel van de venstertitel buiten het scherm te verplaatsen. De inhoud van niet-toepassingsbeveiligingssandboxen kan de JavaScript-methode window.open() alleen oproepen als reactie op een gebeurtenis die is gestart door een klik met de muisknop of een druk op een toets van het toetsenbord. Hierdoor wordt voorkomen dat niet-toepassingsinhoud vensters creëert die voor bedrog kunnen worden gebruikt (bijvoorbeeld voor phishingaanvallen). Ook kan de gebeurtenishandler voor de muis- of toetsenbordgebeurtenis de methode window.open() niet zo instellen dat deze na een vertraging wordt uitgevoerd (bijvoorbeeld door de functie setTimeout() op te roepen). De inhoud van externe (netwerk-) sandboxen kan de methode window.open() alleen gebruiken om de inhoud van externe netwerksandboxen te openen. Deze inhoud kan de methode window.open() niet gebruiken om de inhoud van de toepassingssandbox of van lokale sandboxen te openen. De inhoud van lokaal-met-bestandssysteem, lokaal-met-netwerk of lokaal-vertrouwde sandboxen (zie “Sandboxen” op pagina 28) kan de methode window.open() alleen gebruiken om de inhoud van lokale sandboxen te openen. Deze inhoud kan window.open() niet gebruiken om de inhoud van de toepassingssandbox of van externe sandboxen te openen.
Fouten bij het oproepen van beperkte code Als u code oproept die niet in een sandbox kan worden gebruikt vanwege deze beveiligingsbeperkingen, geeft de runtime de foutmelding weer dat er in de runtime van Adobe AIR een beveiligingsfout betreffende JavaScript-code in de toepassingsbeveiligingssandbox is opgetreden. Zie “JavaScript-beveiligingsfouten voorkomen” op pagina 240voor meer informatie.
Sandboxbescherming bij het laden van HTML-inhoud uit een tekenreeks Met de methode loadString() van de klasse HTMLLoader kunt u HTML-inhoud bij de uitvoering maken. De gegevens die u gebruikt als HTML-inhoud kunnen echter beschadigd zijn als de gegevens worden geladen uit een onbeveiligde internetbron. Om deze reden wordt HTML die is gemaakt met behulp van de methode loadString(), niet in de toepassingssandbox geplaatst en heeft deze HTML geen toegang tot API's van AIR. U kunt echter wel de eigenschap placeLoadStringContentInApplicationSandbox van een HTMLLoader-object instellen op true, zodat HTML die is gemaakt met de methode loadString(), in de toepassingssandbox wordt geplaatst. Zie “HTMLinhoud laden vanuit een tekenreeks” op pagina 238 voor meer informatie.
Scripting tussen de inhoud van verschillende domeinen Bij de installatie van AIR-toepassingen worden hieraan speciale rechten toegewezen. Het is van groot belang dat deze rechten niet aan andere inhoud worden doorgegeven, zoals externe bestanden en lokale bestanden die geen deel uitmaken van de toepassing.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 37 Beveiliging in AIR
Informatie over de AIR-sandboxbridge Inhoud van andere domeinen kan normaal gesproken geen scripts in andere domeinen oproepen. Om AIRtoepassingen te beschermen tegen onbedoelde lekkage van informatie of besturingselementen waarvoor speciale toegangsrechten gelden, gelden de volgende beperkingen voor de inhoud van de beveiligingssandbox application (inhoud die met de toepassing is geïnstalleerd):
• Code in de toepassingsbeveiligingssandbox mag geen toegang bieden tot andere sandboxen door de methode Security.allowDomain() op te roepen. Het oproepen van deze methode vanuit de toepassingsbeveiligingssandbox veroorzaakt een fout.
• Het importeren van niet-toepassingsinhoud in de toepassingssandbox door de eigenschap LoaderContext.securityDomain of LoaderContext.applicationDomain te activeren, wordt verhinderd.
Er zijn echter situaties waarin de AIR-hoofdtoepassing inhoud van een extern domein nodig heeft voor gecontroleerde toegang tot scripts in de AIR-hoofdtoepassing, of omgekeerd. Hiervoor biedt de runtime het mechanisme sandboxbridge, dat als gateway tussen beide sandboxen fungeert. Een sandboxbridge kan expliciete interactie tussen externe en toepassingsbeveiligingssandboxen bieden. De sandboxbridge maakt twee objecten toegankelijk, waartoe zowel geladen als ladende scripts toegang hebben:
• Het object parentSandboxBridge staat ladende inhoud toe om eigenschappen en functies toegankelijk te maken voor scripts in de geladen inhoud.
• Het object childSandboxBridge staat geladen inhoud toe om eigenschappen en functies toegankelijk te maken voor scripts in de ladende inhoud. Objecten die via de sandboxbridge toegankelijk worden gemaakt, worden doorgegeven op basis van waarde en niet op basis van referentie. Alle gegevens zijn geserialiseerd. Dit betekent dat de objecten die door de ene kant van de bridge toegankelijk zijn gemaakt, niet door de andere kant kunnen worden ingesteld, en dat alle toegankelijke objecten geen specifiek type hebben. Bovendien kunt u alleen eenvoudige objecten en functies toegankelijk maken, geen complexe objecten. Als onderliggende inhoud een eigenschap van het object parentSandboxBridge probeert in te stellen, genereert de runtime een SecurityError-fout. Evenzo genereert de runtime een SecurityError-fout als bovenliggende inhoud een eigenschap van het object childSandboxBridge probeert in te stellen.
Voorbeeld van sandboxbridge (SWF) Dit voorbeeld is gebaseerd op een AIR-toepassing voor een muziekwinkel. De toepassing wil externe SWF-bestanden toestaan om de prijs van albums toegankelijk te maken maar wil niet dat het externe SWF-bestand aangeeft of de prijs een opruimingsprijs is. Hiervoor biedt de klasse StoreAPI een methode die de prijs opvraagt maar de opruimingsprijs verbergt. Vervolgens wordt een instantie van deze StoreAPI-klasse toegewezen aan de eigenschap parentSandboxBridge van het LoaderInfo-object van het Loader-object dat het externe SWF-bestand laadt. Dit is de code voor de AIR-muziekwinkel:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 38 Beveiliging in AIR
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="Music Store" creationComplete="initApp()"> <mx:Script> import flash.display.Loader; import flash.net.URLRequest; private var child:Loader; private var isSale:Boolean = false; private function initApp():void { var request:URLRequest = new URLRequest("http://[www.yourdomain.com]/PriceQuoter.swf") child = new Loader(); child.contentLoaderInfo.parentSandboxBridge = new StoreAPI(this); child.load(request); container.addChild(child); } public function getRegularAlbumPrice():String { return "$11.99"; } public function getSaleAlbumPrice():String { return "$9.99"; } public function getAlbumPrice():String { if(isSale) { return getSaleAlbumPrice(); } else { return getRegularAlbumPrice(); } } <mx:UIComponent id="container" />
Het StoreAPI-object roept de hoofdtoepassing op om de normale albumprijs op te vragen maar geeft “Not available” (Niet beschikbaar) weer wanneer de methode getSaleAlbumPrice() wordt opgeroepen. De volgende code definieert de klasse StoreAPI:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 39 Beveiliging in AIR
public class StoreAPI { private static var musicStore:Object; public function StoreAPI(musicStore:Object) { this.musicStore = musicStore; } public function getRegularAlbumPrice():String { return musicStore.getRegularAlbumPrice(); } public function getSaleAlbumPrice():String { return "Not available"; } public function getAlbumPrice():String { return musicStore.getRegularAlbumPrice(); } }
De volgende code is een voorbeeld van het SWF-bestand PriceQuoter (Prijsofferte), dat de verkoopprijs van de winkel weergeeft maar de opruimingsprijs niet kan weergeven: package { import flash.display.Sprite; import flash.system.Security; import flash.text.*; public class PriceQuoter extends Sprite { private var storeRequester:Object; public function PriceQuoter() { trace("Initializing child SWF"); trace("Child sandbox: " + Security.sandboxType); storeRequester = loaderInfo.parentSandboxBridge; var tf:TextField = new TextField(); tf.autoSize = TextFieldAutoSize.LEFT; addChild(tf); tf.appendText("Store price of album is: " + storeRequester.getAlbumPrice()); tf.appendText("\n"); tf.appendText("Sale price of album is: " + storeRequester.getSaleAlbumPrice()); } } }
Voorbeeld van sandboxbridge (HTML) Bij HTML-inhoud worden de eigenschappen parentSandboxBridge en childSandboxBridge toegevoegd aan het JavaScript window-object van een subdocument. Zie “Sandboxbridge-interface instellen” op pagina 254voor een voorbeeld van hoe u bridgefuncties definieert in HTML-inhoud.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 40 Beveiliging in AIR
API-toegankelijkheid beperken Bij het toegankelijk maken van sandboxbridges is het belangrijk dat u API's toegankelijk maakt die van een hoog niveau zijn en de mate beperken waarin ze kunnen worden misbruikt. Vergeet niet dat de inhoud die uw bridgeimplementatie oproept, door een kwaadwillige persoon kan zijn gewijzigd (bijvoorbeeld via een code-injectie). Dit betekent bijvoorbeeld dat een methode readFile(path:String) (die de inhoud van een willekeurig bestand leest) die via een bridge toegankelijk wordt gemaakt, kan worden misbruikt. Het is aan te raden een API readApplicationSetting() toegankelijk te maken die geen specifiek pad volgt en een specifiek bestand leest. De meer semantische methode beperkt de schade die een toepassing kan aanbrengen als een deel ervan door een kwaadwillige persoon is gewijzigd.
Zie ook “Cross-scripting van inhoud in verschillende beveiligingssandboxen” op pagina 253 “Toepassingssandbox” op pagina 29 “Rechten van inhoud van niet-toepassingssandboxen” op pagina 30
Naar schijf schrijven Toepassingen die in een webbrowser worden uitgevoerd, hebben slechts beperkte interactie met het lokale bestandssysteem van de gebruiker. Webbrowsers passen beveiligingsmaatregelen toe die zorgen dat de computer van de gebruiker niet in gevaar kan worden gebracht door het laden van webinhoud. Bijvoorbeeld: SWF-bestanden die via Flash Player in een browser worden uitgevoerd, kunnen niet rechtstreeks interageren met bestanden die al op de computer van de gebruiker staan. Gedeelde objecten en cookies kunnen naar de computer van de gebruiker worden geschreven voor het bijhouden van gebruikersvoorkeuren en andere gegevens, maar meer niet. Aangezien AIRtoepassingen in het besturingssysteem worden geïnstalleerd, gebruiken ze een ander beveiligingscontract, dat onder andere de mogelijkheid biedt om te lezen van en te schrijven naar het lokale bestandssysteem. Deze vrijheid gaat gepaard met een grote verantwoordelijkheid voor de ontwikkelaars. Toevallige kwetsbaarheden van toepassingen brengen niet alleen de functionaliteit van de toepassing in gevaar, maar ook de integriteit van de computer van de gebruiker. Daarom wordt ontwikkelaars aangeraden “Aanbevolen beveiligingsprocedures voor ontwikkelaars” op pagina 42te lezen. AIR-ontwikkelaars kunnen bestanden in het lokale bestandssysteem via verschillende URL-schemaconventies lezen/schrijven: URL-schema
Beschrijving
app:/
Een alias voor de toepassingsmap. Bestanden die via dit pad worden benaderd, worden toegewezen aan de toepassingssandbox en beschikken over alle toegangsrechten die door de runtime worden verleend.
app-storage:/
Een alias voor de lokale opslagdirectory, gestandaardiseerd door de runtime. Bestanden die via dit pad worden benaderd, worden toegewezen aan een niet-toepassingssandbox.
file:///
Een alias die de hoofddirectory van de vaste schijf van de gebruiker vertegenwoordigt. Aan een bestand dat via dit pad wordt benaderd, wordt een toepassingssandbox toegewezen als het bestand in de toepassingsmap bestaat. Als dat niet het geval is, wordt een niet-toepassingssandbox toegewezen.
Opmerking: AIR-toepassingen kunnen geen inhoud wijzigen via het URL-schema app:. Bovendien is de toepassingsmap mogelijk alleen-lezen, afhankelijk van de beheerdersinstellingen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 41 Beveiliging in AIR
Als er geen beheerdersrechten voor de computer van de gebruiker vereist zijn, mogen AIR-toepassingen naar een willekeurige locatie op de vaste schijf van de gebruiker schrijven. Ontwikkelaars wordt aangeraden het pad appstorage:/ te gebruiken voor lokale opslag betreffende hun toepassing. Bestanden die vanuit een toepassing naar app-storage:/ worden geschreven, worden in een standaardlocatie geplaatst:
• In Mac OS: de opslagdirectory van een toepassing is //Local
Store/, waarbij de voorkeursmap van de gebruiker is. Dit is doorgaans /Users//Library/Preferences.
• In Windows: de opslagdirectory van een toepassing is \\Local
Store\, waarbij de CSIDL_APPDATA 'speciale map' van de gebruiker is. Dit is doorgaans C:\Documents and Settings\\Application Data.
• In Linux: //Local
Store/, waarbij /home/< gebruiker>/.appdata is
Als een toepassing is ontworpen om te interageren met bestaande bestanden in het bestandssysteem van de gebruiker, moet u “Aanbevolen beveiligingsprocedures voor ontwikkelaars” op pagina 42lezen.
Veilig werken met niet-vertrouwde inhoud Inhoud die niet aan de toepassingssandbox is toegewezen, kan uw toepassing aanvullende scriptfunctionaliteit bieden, maar alleen als wordt voldaan aan de beveiligingscriteria van de runtime. In dit onderwerp wordt het AIRbeveiligingscontract met niet-toepassingsinhoud besproken.
Security.allowDomain() AIR-toepassingen beperken de toegang van scripts voor niet-toepassingsinhoud in hogere mate dan de Flash Player plug-in voor de browser de toegang van scripts voor niet-vertrouwde inhoud. Bijvoorbeeld: wanneer in Flash Player in de browser een SWF-bestand dat is toegewezen aan de lokaal-vertrouwde sandbox de methode System.allowDomain() aanroept, wordt scripttoegang verleend voor een willekeurig SWF-bestand dat vanaf het opgegeven domein wordt geladen. Deze benadering is niet toegestaan voor toepassingsinhoud in AIR-toepassingen omdat hierdoor onredelijke toegang tot het niet-toepassingsbestand in het bestandssysteem van de gebruiker zou worden verleend. Externe bestanden hebben nooit rechtstreekse toegang tot de toepassingssandbox, ongeacht de aanwezigheid van oproepen van de methode Security.allowDomain().
Scripting tussen toepassings- en niet-toepassingsinhoud Voor AIR-toepassingen die scripts gebruiken tussen toepassings- en niet-toepassingsinhoud, gelden complexere beveiligingsmaatregelen. Bestanden die zich niet in de toepassingssandbox bevinden, hebben alleen via een sandboxbridge toegang tot de eigenschappen en methoden van bestanden in de toepassingssandbox. Een sandboxbridge is een gateway tussen toepassings- en niet-toepassingsinhoud, en maakt expliciete interactie tussen de twee bestanden mogelijk. Wanneer een sandboxbridges correct wordt gebruikt, biedt deze een extra beveiligingslaag door te zorgen dat niet-toepassingsinhoud geen toegang heeft tot objectverwijzingen die deel uitmaken van toepassingsinhoud. Het voordeel van sandboxbridges wordt het best met een voorbeeld geïllustreerd. Dit voorbeeld is gebaseerd op een AIR-toepassing voor een muziekwinkel. De winkel wil adverteerders die hun eigen SWF-bestanden willen maken, een API bieden waarmee de toepassing van de winkel vervolgens kan communiceren. De winkel wil adverteerders methoden bieden waarmee ze artiesten en cd's in de winkel kunnen opzoeken, maar wil om veiligheidsredenen ook bepaalde methoden en eigenschappen onbereikbaar maken voor de SWF-bestanden van de adverteerders.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 42 Beveiliging in AIR
Een sandboxbridge kan hiervoor zorgen. Inhoud die extern in een AIR-toepassing wordt geladen tijdens het gebruik van de runtime, heeft standaard geen toegang tot methoden of eigenschappen in de hoofdtoepassing. Met een aangepaste sandboxbridge-implementatie kan een ontwikkelaar services voor de externe inhoud bieden zonder deze methoden of eigenschappen toegankelijk te maken. De sandboxbridge is als een pad tussen vertrouwde en nietvertrouwde inhoud dat communicatie tussen de ladende en de geladen inhoud mogelijk maakt zonder objectverwijzingen toegankelijk te maken. Zie “Scripting tussen de inhoud van verschillende domeinen” op pagina 36voor meer informatie over hoe u sandboxbridges veilig gebruikt.
Bescherming tegen dynamisch gegenereerde, onveilige SWF-inhoud De methode Loader.loadBytes() biedt een toepassing de mogelijkheid om SWF-inhoud te genereren op basis van een bytearray. Injectieaanvallen op gegevens die van externe bronnen worden geladen, kunnen echter ernstige schade toebrengen bij het laden van inhoud. Dit geldt met name bij het laden van gegevens in de toepassingssandbox, waar de gegenereerde SWF-inhoud toegang heeft tot de volledige set van AIR API's. Er zijn echter ook situaties waarin het gebruik van de methode loadBytes() zonder het genereren van SWFprogrammacode vereist is. U kunt de methode loadBytes() gebruiken om grafische gegevens te genereren, bijvoorbeeld om de beeldweergavetiming te besturen. Er zijn ook situaties waarin wel programmacode mag worden gegenereerd, zoals bij het dynamisch genereren van SWF-inhoud voor het afspelen van audio. In AIR staat de methode loadBytes() u standaard niet toe om SWF-inhoud te laden; u mag alleen grafische inhoud laden. In AIR heeft de eigenschap loaderContext van de methode loadBytes() een eigenschap allowLoadBytesCodeExecution, die u op true kunt instellen om de toepassing expliciet toe te staan loadBytes() te gebruiken om SWF-programmacode te laden. In de volgende code wordt getoond hoe u deze functie gebruikt: var loader:Loader = new Loader(); var loaderContext:LoaderContext = new LoaderContext(); loaderContext.allowLoadBytesCodeExecution = true; loader.loadBytes(bytes, loaderContext);
Als u loadBytes() oproept om SWF-inhoud te laden en de eigenschap allowLoadBytesCodeExecution van het LoaderContext-object is ingesteld op false (dit is de standaardinstelling), genereert het Loader-object een SecurityError-fout. Opmerking: In een toekomstige versie van Adobe AIR wordt deze API mogelijk aangepast. In dat geval moet u mogelijk de inhoud die gebruikmaakt van de eigenschap allowLoadBytesCodeExecution van de klasse LoaderContext, opnieuw compileren.
Aanbevolen beveiligingsprocedures voor ontwikkelaars AIR-toepassingen zijn weliswaar gebaseerd op webtechnologieën maar ontwikkelaars mogen niet vergeten dat ze niet in de beveiligingssandbox van de browser werken. Dit betekent dat het mogelijk is om AIR-toepassingen te ontwikkelen die bedoeld of onbedoeld schade kunnen toebrengen aan het systeem. AIR probeert dit risico tot het minimum te beperken maar er zijn altijd wel manieren om kwetsbaarheden te genereren. In dit onderwerp worden belangrijke potentiële kwetsbaarheden besproken.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 43 Beveiliging in AIR
Risico bij het importeren van bestanden in de toepassingsbeveiligingssandbox Bestanden in de toepassingsmap zijn toegewezen aan de toepassingssandbox en beschikken over alle toegangsrechten van de runtime. Toepassingen die naar het lokale bestandssysteem schrijven, wordt aangeraden naar app-storage:/ te schrijven. Aangezien deze directory apart van de toepassingsbestanden op de computer van de gebruiker is geplaatst, zijn de bestanden niet toegewezen aan de toepassingssandbox en vormen ze een kleiner veiligheidsrisico. Ontwikkelaars wordt aangeraden het volgende in acht te nemen:
• Neem alleen indien nodig een bestand op in een AIR-bestand (in de geïnstalleerde toepassing). • Neem alleen een scriptbestand op in een AIR-bestand (in de geïnstalleerde toepassing) als het gedrag ervan volledig begrepen en vertrouwd wordt.
• Schrijf niet naar de toepassingsmap en wijzig de inhoud ervan niet. De runtime genereert een SecurityError-fout om te zorgen dat toepassingen geen bestanden en mappen via het URL-schema app:/ kunnen wijzigen of ernaar schrijven.
• Gebruik geen gegevens van een netwerkbron als parameters voor AIR API-methoden die tot de uitvoering van code kunnen leiden. Dit geldt onder andere voor het gebruik van de methode Loader.loadBytes() en de JavaScriptfunctie eval().
Risico bij het gebruiken van een externe bron voor het bepalen van paden Een AIR-toepassing kan in gevaar worden gebracht door het gebruik van externe gegevens of inhoud. Daarom moet extra worden opgelet bij het gebruik van gegevens van het netwerk of het bestandssysteem. De verantwoordelijkheid voor het geven van vertrouwen ligt uiteindelijk bij de ontwikkelaars en de netwerkverbindingen die ze maken, maar het laden van externe gegevens is altijd gevaarlijk en wordt het best niet gebruikt voor gegevensinvoer bij bewerkingen met vertrouwelijke gegevens. Ontwikkelaars wordt het volgende afgeraden:
• gegevens van een netwerkbron gebruiken om een bestandsnaam te bepalen; • gegevens van een netwerkbron gebruiken om een URL te definiëren die door de toepassing wordt gebruikt om persoonlijke informatie te verzenden.
Risico bij het gebruiken, opslaan of verzenden van onveilige gebruikersgegevens Het opslaan van gebruikersgegevens in het lokale bestandssysteem van de gebruiker brengt altijd het risico met zich mee dat deze gegevens door een kwaadwillige persoon zijn gewijzigd. Ontwikkelaars worden geadviseerd om rekening te houden met het volgende:
• Als gebruikersgegevens lokaal moeten worden opgeslagen, moeten ze worden gecodeerd bij het schrijven naar het lokale bestandssysteem. Via de klasse EncryptedLocalStore biedt de runtime unieke gecodeerde opslag voor elke geïnstalleerde toepassing. Zie “Gecodeerde gegevens opslaan” op pagina 220voor meer informatie.
• Verzend gebruikersgegevens niet ongecodeerd naar een netwerkbron, tenzij de desbetreffende bron wordt vertrouwd.
• Stel nooit een standaardwachtwoord in bij het creëren van gebruikersgegevens. Laat de gebruiker zijn of haar eigen wachtwoord instellen. Gebruikers die de standaardinstellingen niet wijzigen, stellen hun referenties bloot aan een hacker die het standaardwachtwoord kent.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 44 Beveiliging in AIR
Risico van een downgradeaanval Tijdens de installatie van een toepassing controleert de runtime of de toepassing momenteel niet is geïnstalleerd. Als de toepassing al is geïnstalleerd, vergelijkt de runtime het versienummer met dat van de geïnstalleerde versie. Als beide versies niet hetzelfde nummer hebben, kan de gebruiker desgewenst de bestaande installatie upgraden. De runtime garandeert echter niet dat de nieuwe versie recenter is dan de geïnstalleerde versie, alleen dat het een andere versie is. Een aanvaller kan de gebruiker een oudere versie sturen om gebruik te maken van deze kwetsbaarheid. Daarom wordt de ontwikkelaar aangeraden een versiecontrole uit te voeren bij het starten van de toepassing. Het is een goed idee om toepassingen het netwerk te laten doorzoeken op eventuele updates. Op die manier wordt onmiddellijk een verouderde versie gedetecteerd, zelfs als een aanvaller erin geslaagd is de gebruiker een oude versie te laten installeren. Ook het gebruik van een duidelijk versieschema voor uw toepassing maakt het moeilijk om gebruikers onbedoeld een oudere versie te laten installeren. Zie “Eigenschappen definiëren in het descriptorbestand van de toepassing” op pagina 46voor meer informatie over het bieden van verschillende versies van een toepassing.
Codeondertekening Alle AIR-installatiebestanden moeten zijn voorzien van codeondertekening. Codeondertekening is een cryptografisch proces waarbij wordt bevestigd dat de opgegeven oorsprong van software correct is. U kunt AIR-toepassingen ondertekenen door een certificaat van een externe certificeringsinstantie (CI) te koppelen of door uw eigen certificaat te genereren. Een commercieel certificaat van een bekende CI wordt ten zeerste aanbevolen en biedt uw gebruikers de garantie dat ze uw toepassing installeren, en geen vervalste versie. U kunt zelfondertekende certificaten genereren via adt uit de SDK of met behulp van Flash, Flex Builder of een andere toepassing die adt gebruikt voor het genereren van certificaten. Zelfondertekende certificaten bieden echter geen enkele garantie dat de toepassing die wordt geïnstalleerd, authentiek is. Zie “AIR-bestanden digitaal ondertekenen” op pagina 328en “AIR-toepassingen maken met behulp van opdrachtregelprogramma's” op pagina 363voor meer informatie over het digitaal ondertekenen van AIRtoepassingen.
45
Hoofdstuk 8: Eigenschappen van AIRtoepassingen instellen Naast alle bestanden en andere elementen die deel uitmaken van een AIR-toepassing, heeft elke AIR-toepassing een descriptorbestand nodig. Het descriptorbestand van de toepassing is een XML-bestand dat de basiseigenschappen van de toepassing definieert. Als u AIR-toepassingen ontwikkelt met Adobe® AIR™ Update voor Adobe® Flash® CS3 Professional of Adobe® Flash® CS4 Professional, wordt het descriptorbestand automatisch gegenereerd wanneer u een AIR-project maakt. In het menu Opdrachten > AIR - Instellingen voor toepassing en installer vindt u een deelvenster om de descriptorinstellingen te wijzigen. U kunt het descriptorbestand van de toepassing ook handmatig aanpassen.
De structuur van het descriptorbestand van de toepassing Het descriptorbestand van de toepassing bevat eigenschappen die gelden voor de volledige toepassing, zoals naam, versie, copyright enzovoort. U kunt een willekeurige naam voor het descriptorbestand van de toepassing gebruiken. Wanneer u in Flash CS3 of Flash CS4 met de standaardinstellingen een AIR-bestand maakt, wordt de naam van het toepassingsdescriptbestand gewijzigd in application.xml en wordt het bestand in een speciale map in het AIRpakket geplaatst. Voorbeeld van een descriptorbestand van de toepassing: com.example.HelloWorld2.0Hello WorldExample Co. AIR Hello World <description> This is a example.C'est un exemple.Esto es un ejemplo.Copyright (c) 2006 Example Co.Hello World HelloWorld-debug.swf <systemChrome>none truetrue <minimizable>true <maximizable>false false <width>640 480 <minSize>320 240
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 46 Eigenschappen van AIR-toepassingen instellen
<maxSize>1280 960 Example Co/Hello World <programMenuFolder>Example Co icons/smallIcon.pngicons/mediumIcon.pngicons/bigIcon.pngicons/biggestIcon.png <customUpdateUI>true falseadobe.VideoFile <extension>avf <description>Adobe Video File application/vnd.adobe.video-fileicons/avfIcon_16.pngicons/avfIcon_32.pngicons/avfIcon_48.pngicons/avfIcon_128.png
Eigenschappen definiëren in het descriptorbestand van de toepassing Gebruik de XML-elementen en -kenmerken in de toepassingsdescriptor om de volgende typen eigenschappen voor uw AIR-toepassing te definiëren:
• Vereiste AIR-runtimeversie • Toepassingsidentiteit • Installatie- en programmamenumappen • Eerste inhoud en venstereigenschappen • Pictogrambestanden van de toepassing • Of uw toepassing een aangepaste update-UI heeft • Of uw toepassing kan worden aangeroepen door SWF-inhoud die in de browser van de gebruiker wordt uitgevoerd • Bestandstypekoppelingen
Indicatie van de vereiste AIR-versie Met de kenmerken van het hoofdelement van een toepassingsdescriptorbestand, application, wordt de vereiste AIRruntimeversie aangegeven:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 47 Eigenschappen van AIR-toepassingen instellen
xmlns De AIR-naamruimte, die u als de standaard XML-naamruimte moet definiëren. De naamruimte verandert bij elke grote release van AIR (maar niet bij kleine patches). Het laatste segment van de naamruimte, bijvoorbeeld "1.5", geeft de runtimeversie aan die de toepassing nodig heeft. U moet de naamruimte instellen op AIR 1.5 ("http://ns.adobe.com/air/application/1.5") als uw toepassing gebruikmaakt van nieuwe AIR 1.5-functies. Voor op SWF gebaseerde toepassingen, bepaalt de in de toepassingsdescriptor opgegeven AIR-runtimeversie de maximale SWF-versie die kan worden geladen als de eerste inhoud van de toepassing. Toepassingen waarin AIR 1.0 of AIR 1.1 wordt opgegeven, kunnen alleen SWF9-bestanden (Flash Player 9) gebruiken als eerste inhoud zelfs als de AIR 1.5-runtime wordt gebruikt. Toepassingen waarin AIR 1.5 wordt opgegeven, kunnen SWF9- of SWF10-bestanden (Flash Player 10) gebruiken als eerste inhoud. De SWF-versie bepaalt welke versie van de AIR- en Flash Player-API's beschikbaar zijn. Als een SWF9-bestand wordt gebruikt als de eerste inhoud van een AIR 1.5-toepassing, heeft die toepassing alleen toegang tot de AIR 1.1- en Flash Player 9-API's. Bovendien hebben gedragswijzigingen die zijn aangebracht in bestaande API's in AIR 1.5 of Flash Player 10 geen effect. (Belangrijke wijzigingen in API's met betrekking tot veiligheid zijn een uitzondering op dit principe en kunnen retro-actief worden toegepast op huidige en toekomstige patches van de runtime.) Voor op HTML gebaseerde toepassingen, bepaalt alleen de in de toepassingsdescriptor opgegeven runtimeversie welke versie van de AIR- en Flash Player-API's beschikbaar zijn voor de toepassing. Het HTML-, CSS- en JavaScript-gedrag wordt altijd bepaald door de versie van Webkit die wordt gebruikt in de geïnstalleerde AIR-runtime, en niet door de toepassingsdescriptor. Als een AIR-toepassing SWF-inhoud laadt, is de versie van de AIR- en Flash Player-API's die beschikbaar zijn voor die inhoud afhankelijk van hoe de inhoud wordt geladen. In de volgende tabel wordt aangegeven hoe de API-versie wordt bepaald op basis van de laadmethode: Hoe de inhoud wordt geladen
Hoe de API-versie wordt bepaald
Eerste inhoud, op SWF gebaseerde toepassing
SWF-versie van het geladen bestand
Eerste inhoud, op HTML gebaseerde toepassing Naamruimte van de toepassingsdescriptor SWF geladen door SWF-inhoud
Versie van de ladende inhoud
SWF-bibliotheek geladen door HTML-inhoud met <script>-tag
Naamruimte van de toepassingsdescriptor
SWF geladen door HTML-inhoud door AIR- of Flash Player-API's (zoals flash.display.Loader)
Naamruimte van de toepassingsdescriptor
SWF geladen door HTML-inhoud met
Bestanden neerzetten in niet-toepassingssandboxen in HMTL Inhoud die niet van de toepassing afkomstig is, heeft geen toegang tot File-objecten die worden gemaakt wanneer bestanden naar een AIR-toepassing worden gesleept. Het is ook niet mogelijk een van deze File-objecten aan inhoud van de toepassing door te geven via een sandboxbridge. (De objecteigenschappen moeten worden benaderd tijdens het serialiseren.) U kunt echter wel bestanden in uw toepassing neerzetten door te luisteren naar de nativeDragDropgebeurtenissen van AIR voor het HTMLLoader-object. Als een gebruiker een bestand neerzet in een frame dat inhoud bevat die niet van de toepassing afkomstig is, wordt de neerzetgebeurtenis gewoonlijk niet van het onderliggende naar het bovenliggende item doorgevoerd. Omdat de gebeurtenissen die door de HTMLLoader (die de container is voor alle HTML-inhoud in een AIR-toepassing) worden verzonden geen deel uitmaken van de HTML-gebeurtenissenstroom, kunt u de neerzetgebeurtenis echter nog steeds ontvangen in inhoud van de toepassing. Om de gebeurtenis voor het neerzetten van een bestand te ontvangen, voegt het bovenliggende document een gebeurtenislistener aan het HTMLLoader-object toe met de verwijzing die is geleverd door window.htmlLoader: window.htmlLoader.addEventListener("nativeDragDrop",function(event){ var filelist = event.clipboard.getData(air.ClipboardFormats.FILE_LIST_FORMAT); air.trace(filelist[0].url); });
In het volgende voorbeeld laadt een bovenliggend document een onderliggende pagina in een externe sandbox (http://localhost/). Het bovenliggende document luistert naar de gebeurtenis nativeDragDrop van het HTMLLoaderobject en haalt hier de bestands-URL uit op.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 152 Slepen en neerzetten
Drag-and-drop in a remote sandbox <script language="javascript" type="text/javascript" src="AIRAliases.js"> <script language="javascript"> window.htmlLoader.addEventListener("nativeDragDrop",function(event){ var filelist = event.clipboard.getData(air.ClipboardFormats.FILE_LIST_FORMAT); air.trace(filelist[0].url); }); <iframe src="child.html" sandboxRoot="http://localhost/" documentRoot="app:/" frameBorder="0" width="100%" height="100%">
Het onderliggende document moet een geldig neerzetdoel zijn. Hiervoor moet de methode preventDefault() van het Event-object in handlers van de HTML-gebeurtenissen dragenter en dragover worden voorkomen, anders kan de neerzetgebeurtenis niet plaatsvinden. Drag and drop target <script language="javascript" type="text/javascript"> function preventDefault(event){ event.preventDefault(); }
Drop Files Here
Zie “Programmeren in HTML en JavaScript” op pagina 238 voor meer informatie.
153
Hoofdstuk 16: kopiëren en plakken Gebruik de klassen in de klembord-API om informatie van en naar het systeemklembord te kopiëren. De volgende gegevensindelingen kunnen worden gebruikt om informatie van en naar een Adobe® AIR™-toepassing te kopiëren:
• Bitmaps • Bestanden • Tekst • Tekst met HTML-opmaak • RTF-gegevens • URL-tekenreeksen • Geserialiseerde objecten • Objectverwijzingen (alleen geldig binnen de brontoepassing) In Adobe Flash Player 10 is de functionaliteit voor knippen en plakken toegevoegd die werd geïntroduceerd in AIR 1.0. In dit hoofdstuk wordt de functionaliteit voor knippen en plakken beschreven die uniek is voor Adobe AIR. Voor details over deze gedeelde functionaliteit raadpleegt u het hoofdstuk Kopiëren en plakken (in het boek Adobe ActionScript 3.0 programmeren.
Aanvullende online informatie over kopiëren en plakken Meer informatie over kopiëren en plakken vindt u in deze bronnen: Snelstarthandleidingen (Adobe AIR Developer Connection) • Ondersteuning voor slepen en neerzetten en voor kopiëren en plakken Language Reference • Clipboard
• ClipboardFormats • ClipboardTransferMode Meer informatie • Kopiëren en plakken (in het boek Adobe ActionScript 3.0 programmeren)
• Adobe AIR Developer Connection for Flash (zoek naar 'AIR copy and paste')
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 154 kopiëren en plakken
HTML kopiëren en plakken De HTML-omgeving heeft een eigen set van gebeurtenissen en standaardgedrag voor kopiëren en plakken. Alleen code die in de toepassingssandbox wordt uitgevoerd, heeft rechtstreeks toegang tot het systeemklembord via het AIRobject Clipboard.generalClipboard. JavaScript-code in een niet-toepassingssandbox heeft toegang tot het klembord via het gebeurtenisobject dat is verzonden als reactie op een van de kopiëren-en-plakken-gebeurtenissen die zijn verzonden door een element in een HTML-document. Kopiëren-en-plakken-gebeurtenissen zijn onder andere: copy, cut en paste. Het object dat voor deze gebeurtenissen is verzonden, biedt toegang tot het klembord via de eigenschap clipboardData.
Standaardgedrag Als reactie op de kopieeropdracht worden de geselecteerde items standaard door AIR gekopieerd. Deze opdracht kan via een sneltoets of een snelmenu worden gegenereerd. In bewerkbare zones wordt tekst als reactie op de knipopdracht door AIR geknipt, of als reactie op de plakopdracht door AIR geplakt op de cursorpositie of de geselecteerde tekst. Als u een ander gedrag wenst, kan uw gebeurtenishandler de methode preventDefault() van het verzonden gebeurtenisobject oproepen.
Eigenschap clipboardData van gebeurtenisobject gebruiken Met de eigenschap clipboardData van het gebeurtenisobject dat als reactie op een van de kopieer- of plakgebeurtenissen is verzonden, kunt u klembordgegevens lezen en schrijven. Als u naar het klembord wilt schrijven bij het werken met een kopieer- of knipgebeurtenis, gebruikt u de methode setData() van het object clipboardData, waarbij u de te kopiëren gegevens en het MIME-type opgeeft: function customCopy(event){ event.clipboardData.setData("text/plain", "A copied string."); }
Als u toegang wilt tot de gegevens die worden geplakt, gebruikt u de methode getData() van het object clipboardData, waarbij u het MIME-type van de gegevensindeling opgeeft. De beschikbare indelingen worden weergegeven door de eigenschap types. function customPaste(event){ var pastedData = event.clipboardData("text/plain"); }
De methode getData() en de eigenschap types zijn alleen toegankelijk in het gebeurtenisobject dat is verzonden door de gebeurtenis paste. Het volgende voorbeeld geeft aan hoe u het standaardgedrag bij kopiëren en plakken in een HTML-pagina kunt wijzigen. De gebeurtenishandler copy maakt de gekopieerde tekst cursief en kopieert deze als HTML-tekst naar het klembord. De gebeurtenishandler cut kopieert de geselecteerde gegevens naar het klembord en verwijdert deze uit het document. De gebeurtenishandler paste voegt de inhoud van het klembord als HTML in en maakt de ingevoegde tekst vet.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 155 kopiëren en plakken
Copy and Paste <script language="javascript" type="text/javascript"> function onCopy(event){ var selection = window.getSelection(); event.clipboardData.setData("text/html","" + selection + ""); event.preventDefault(); } function onCut(event){ var selection = window.getSelection(); event.clipboardData.setData("text/html","" + selection + ""); var range = selection.getRangeAt(0); range.extractContents(); event.preventDefault(); } function onPaste(event){ var insertion = document.createElement("b"); insertion.innerHTML = event.clipboardData.getData("text/html"); var selection = window.getSelection(); var range = selection.getRangeAt(0); range.insertNode(insertion); event.preventDefault(); }
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
Menuopdrachten en toetsaanslagen voor kopiëren en plakken De kopiëren-en-plakken-functionaliteit wordt doorgaans geactiveerd door menuopdrachten en sneltoetsen. In OS X maakt het besturingssysteem automatisch een bewerkingsmenu met de opdrachten Kopiëren en Plakken. U moet echter listeners aan deze menuopdrachten toevoegen om uw eigen functies eraan te koppelen. In Windows kunt u een native bewerkingsmenu toevoegen aan elk venster dat de systeeminterface gebruikt. (U kunt ook niet-native menu's maken met Flex en ActionScript of - bij HTML-inhoud - DHTML gebruiken, maar dat valt niet binnen het kader van deze handleiding.) Als u de opdrachten Kopiëren en Plakken wilt laten activeren door sneltoetsen, kunt u toetsencombinaties aan de overeenkomstige opdrachten toewijzen in een native toepassing of venstermenu, of rechtstreeks op de toetsaanslagen wachten.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 156 kopiëren en plakken
Kopieer- of plakbewerking starten met een menuopdracht Als u een kopieer- of plakbewerking wilt laten activeren door een menuopdracht, moet u listeners voor de gebeurtenis select toevoegen aan de menu-items die uw handlerfuncties oproepen. Wanneer uw handlerfunctie wordt opgeroepen, kunt u het object waarvan moet worden gekopieerd of waarnaar moet worden geplakt, vinden met behulp van de eigenschap focus van de fase. Vervolgens kunt u de overeenkomstige methode voor het object met focus (of een algemene alternatieve methode als geen enkel object focus heeft) oproepen om de logica voor kopiëren, knippen of plakken uit te voeren. De volgende gebeurtenishandler copy controleert bijvoorbeeld of het object met focus het juiste type is (in dit geval de klasse Scrap) en roept vervolgens de methode doCopy() voor het object op. function copyCommand(event:Event):void{ if(NativeApplication.nativeApplication.activeWindow.stage.focus is Scrap){ Scrap(NativeApplication.nativeApplication.activeWindow.stage.focus).doCopy(); } else { NativeApplication.nativeApplication.copy(); } }
Als copyCommand() in het voorbeeld de klasse van het object met focus niet herkent, wordt de NativeApplicationmethode copy() opgeroepen. De NativeApplication-methode copy() verzendt een interne opdracht Kopiëren naar het object met focus. Als het object een ingebouwde klasse is die Kopiëren en plakken intern implementeert, voert het object de opdracht uit. De klassen Textfield en HTMLLoader zijn momenteel de enige dergelijke ingebouwde klassen. Andere interactieve objecten verzenden de copy-gebeurtenis. Er zijn soortgelijke opdrachten beschikbaar voor Knippen, Plakken, Alles selecteren en (alleen voor TextArea) Wissen, Ongedaan maken en Opnieuw. Bij HTML-inhoud kunt u het standaardgedrag voor kopiëren en plakken activeren met behulp van de NativeApplication-bewerkingsopdrachten. In het volgende voorbeeld wordt een bewerkingsmenu voor een bewerkbaar HTML-document gemaakt: In het vorige voorbeeld wordt het toepassingsmenu voor Mac OS X vervangen. U kunt echter ook het standaard bewerkingsmenu gebruiken door de bestaande menuopdrachten te zoeken en er gebeurtenislisteners aan toe te voegen. Als u een snelmenu gebruikt om een kopieer- of plakopdracht op te roepen, kunt u de eigenschap contextMenuOwner gebruiken van het ContextMenuEvent-object dat wordt verzonden bij het openen van het menu of het selecteren van een menuopdracht, om te bepalen welk object de juiste bestemming van de kopieer- of plakopdracht is.
Standaard menuopdrachten zoeken in Mac OS X U kunt het standaard bewerkingsmenu en de specifieke kopieer-, knip- en plakopdrachten in het toepassingsmenu voor Mac OS X zoeken door de menuhiërarchie te doorzoeken met behulp van de eigenschap label van de NativeMenuItem-objecten. Met de volgende functie neemt u bijvoorbeeld een naam en zoekt u de opdracht met het overeenkomstige label in het menu:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 157 kopiëren en plakken
private function findItemByName(menu:NativeMenu, name:String, recurse:Boolean = false):NativeMenuItem{ var searchItem:NativeMenuItem = null; for each (var item:NativeMenuItem in menu.items){ if(item.label == name){ searchItem = item; break; } if((item.submenu != null) && recurse){ searchItem = findItemByName(item.submenu, name); } } return searchItem; }
U kunt de parameter recurse instellen op true als u submenu's in de zoekactie wilt opnemen, of op false als u alleen de opdrachten van hetzelfde niveau wilt zoeken.
Kopieer- of plakopdracht starten met een toetsaanslag Als uw toepassing native venster- of toepassingsmenu's voor kopiëren en plakken gebruikt, kunt u toetsencombinaties aan de menuopdrachten toewijzen die als sneltoetsen reageren. Als uw toepassing native venster- of toepassingsmenu's voor kopiëren en plakken gebruikt, kunt u toetsencombinaties aan de menuopdrachten toewijzen die als sneltoetsen reageren. U kunt echter ook zelf naar de overeenkomstige toetsaanslagen luisteren, zoals in het volgende voorbeeld wordt geïllustreerd:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 158 kopiëren en plakken
private function init():void{ stage.addEventListener(KeyboardEvent.KEY_DOWN, keyListener); } private function keyListener(event:KeyboardEvent):void{ if(event.ctrlKey){ event.preventDefault(); switch(String.fromCharCode(event.charCode)){ case "c": NativeApplication.nativeApplication.copy(); break; case "x": NativeApplication.nativeApplication.cut(); break; case "v": NativeApplication.nativeApplication.paste(); break; case "a": NativeApplication.nativeApplication.selectAll(); break; case "z": NativeApplication.nativeApplication.undo(); break; case "y": NativeApplication.nativeApplication.redo(); break; } } }
Bij HTML-inhoud worden standaard de sneltoetsen voor kopieer- en plakopdrachten toegepast. Het is niet mogelijk om met een toetsgebeurtenislistener alle toetsaanslagen te detecteren die doorgaans voor kopiëren en plakken worden gebruikt. Als u het standaardgedrag wilt wijzigen, wordt u aangeraden naar de gebeurtenissen copy en paste zelf te luisteren.
159
Hoofdstuk 17: Werken met bytearrays Met de klasse ByteArray kunt u een binaire gegevensstroom, die in feite een array met bytes is, lezen en schrijven. Met deze klasse krijgt u toegang tot gegevens op het meest elementaire niveau. Omdat computergegevens bestaan uit bytes, of groepen van 8 bits, kunt u door het lezen van gegevens in bytes toegang krijgen tot gegevens waarvoor geen klassen en toegangsmethoden bestaan. Met de klasse ByteArray kunt u elke gegevensstroom, van een bitmap tot een gegevensstroom die via het netwerk wordt verzonden, parseren op byteniveau. Met de methode writeObject() kunt u een object in geserialiseerde AMF-indeling (Action Message Format) schrijven naar een bytearray, terwijl u met de methode readObject() een geserialiseerd object uit een bytearray kunt inlezen in een variabele van het oorspronkelijke gegevenstype. U kunt alle objecten serialiseren, behalve weergaveobjecten (objecten die op de weergavelijst kunnen worden geplaatst). U kunt geserialiseerde objecten ook opnieuw aan aangepaste klasse-instanties toewijzen als de aangepaste klasse beschikbaar is voor de runtime. Nadat een object naar AMF is geconverteerd, kunt u het verzenden via een netwerkverbinding of opslaan in een bestand. In de Adobe® AIR™-voorbeeldtoepassing die hier wordt beschreven, wordt een ZIP-bestand gelezen als voorbeeld van het verwerken van een bytestroom; de lijst met bestanden in het ZIP-bestand wordt uitgepakt en naar de desktop geschreven.
Bytearrays lezen en schrijven De klasse ByteArray is een onderdeel van het pakket flash.utils. Als u een ByteArray-object wilt maken in ActionScript 3.0, importeert u de klasse ByteArray en roept u de constructor op, zoals weergegeven in het volgende voorbeeld: import flash.utils.ByteArray; var stream:ByteArray = new ByteArray();
ByteArray, methoden Elke zinvolle gegevensstroom wordt geordend in een indeling waarin u de gewenste informatie kunt zoeken. Een record in een eenvoudig werknemersbestand kan bijvoorbeeld een id-nummer, een naam, een adres, een telefoonnummer enzovoort bevatten. Een MP3-geluidsbestand bevat een ID3-code met de titel, de auteur, het album, de publicatiedatum en het genre van het bestand dat wordt gedownload. Door deze indeling weet u in welke volgorde de gegevens in de gegevensstroom zijn opgenomen. U kunt de bytestroom daardoor op een intelligente manier lezen. De klasse ByteArray bevat diverse methoden waarmee u een gegevensstroom eenvoudiger kunt lezen of schrijven. Enkele van deze methoden zijn: readBytes() en writeBytes(), readInt() en writeInt(), readFloat() en writeFloat(), readObject() en writeObject(), en readUTFBytes() en writeUTFBytes(). Met deze methoden kunt u gegevens uit een gegevensstroom inlezen in variabelen van bepaalde gegevenstypen en vanuit bepaalde gegevenstypen rechtstreeks naar de binaire gegevensstroom schrijven. Met de volgende code wordt bijvoorbeeld een eenvoudige array met tekenreeksen en getallen met een drijvende komma gelezen en wordt elk element naar een bytearray geschreven. Door de indeling van de array kan de code de juiste ByteArray-methoden (writeUTFBytes() en writeFloat()) oproepen voor het schrijven van de gegevens. Door het herhaalde gegevenspatroon wordt het mogelijk de array in een lus te lezen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 160 Werken met bytearrays
// The following example reads a simple Array (groceries), made up of strings // and floating-point numbers, and writes it to a ByteArray. import flash.utils.ByteArray; // define the grocery list Array var groceries:Array = ["milk", 4.50, "soup", 1.79, "eggs", 3.19, "bread" , 2.35] // define the ByteArray var bytes:ByteArray = new ByteArray(); // for each item in the array for (var i:int = 0; i < groceries.length; i++) { bytes.writeUTFBytes(groceries[i++]); //write the string and position to the next item bytes.writeFloat(groceries[i]);// write the float trace("bytes.position is: " + bytes.position);//display the position in ByteArray } trace("bytes length is: " + bytes.length);// display the length
De eigenschap position In de eigenschap position wordt de huidige positie opgeslagen van de pointer die de index van de bytearray bepaalt tijdens het lezen of schrijven. De initiële waarde van de eigenschap position is 0 (nul), zoals wordt weergegeven in de volgende code: var bytes:ByteArray = new ByteArray(); trace("bytes.position is initially: " + bytes.position); // 0
Wanneer u een bytearray leest of er naar schrijft, wordt de eigenschap position bijgewerkt met de methode die u gebruikt, zodat wordt verwezen naar de locatie die volgt op de laatste byte die is gelezen of geschreven. Met de volgende code wordt bijvoorbeeld een tekenreeks naar een bytearray geschreven en verwijst de eigenschap position daarna naar de byte die volgt op de tekenreeks in de bytearray: var bytes:ByteArray = new ByteArray(); trace("bytes.position is initially: " + bytes.position); // 0 bytes.writeUTFBytes("Hello World!"); trace("bytes.position is now: " + bytes.position);// 12
Bij een leesbewerking wordt de eigenschap position verhoogd met het aantal gelezen bytes. var bytes:ByteArray = new ByteArray(); trace("bytes.position is initially: " + bytes.position); // 0 bytes.writeUTFBytes("Hello World!"); trace("bytes.position is now: " + bytes.position);// 12 bytes.position = 0; trace("The first 6 bytes are: " + (bytes.readUTFBytes(6)));//Hello trace("And the next 6 bytes are: " + (bytes.readUTFBytes(6)));// World!
U kunt de eigenschap position instellen op een specifieke locatie in de bytearray om vanaf dat punt te lezen of te schrijven.
De eigenschappen bytesAvailable en length De eigenschappen length en bytesAvailable geven aan hoe lang een bytearray is en hoeveel bytes er aanwezig zijn vanaf de huidige positie tot het einde. In het volgende voorbeeld ziet u hoe u deze eigenschappen kunt gebruiken. In het voorbeeld wordt een tekenreeks met tekst naar de bytearray geschreven en worden vervolgens alle bytes in de array een voor een gelezen totdat het teken ‘a’ of het einde (bytesAvailable <= 0) wordt aangetroffen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 161 Werken met bytearrays
var bytes:ByteArray = new ByteArray(); var text:String = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus etc."; bytes.writeUTFBytes(text); // write the text to the ByteArray trace("The length of the ByteArray is: " + bytes.length);// 70 bytes.position = 0; // reset position while (bytes.bytesAvailable > 0 && (bytes.readUTFBytes(1) != 'a')) { //read to letter a or end of bytes } if (bytes.position < bytes.bytesAvailable) { trace("Found the letter a; position is: " + bytes.position); // 23 trace("and the number of bytes available is: " + bytes.bytesAvailable);// 47 }
De eigenschap endian Getallen die uit meerdere bytes bestaan (getallen die in meer dan 1 byte geheugen worden opgeslagen), kunnen op verschillende manieren op computers worden opgeslagen. Een geheel getal kan bijvoorbeeld 4 bytes (32 bits) geheugen in beslag nemen. Op sommige computers wordt de meest significante byte van het getal eerst opgeslagen, op het laagste geheugenadres, en op andere wordt de minst significante byte eerst opgeslagen. Dit kenmerk van een computer (de bytevolgorde) wordt big endian (meest significante byte eerst) of little endian (minst significante byte eerst) genoemd. Het getal 0x31323334 wordt bijvoorbeeld als volgt opgeslagen bij de bytevolgorde big endian en little endian, waarbij a0 het laagste geheugenadres van de 4 bytes is en a3 het hoogste: Big Endian
Big Endian
Big Endian
Big Endian
a0
a1
a2
a3
31
32
33
34
Little Endian
Little Endian
Little Endian
Little Endian
a0
a1
a2
a3
34
33
32
31
Met de eigenschap endian van de klasse ByteArray kunt u deze bytevolgorde aangeven voor getallen die uit meerdere bytes bestaan. De geaccepteerde waarden voor deze eigenschap zijn "bigEndian" en "littleEndian" en in de klasse Endian zijn de constanten BIG_ENDIAN en LITTLE_ENDIAN gedefinieerd om deze tekenreeksen in te stellen voor de eigenschap endian.
De methoden compress() en uncompress() Met de methode compress() kunt u een bytearray comprimeren volgens een compressiealgoritme die u opgeeft als een parameter. Met de methode uncompress() kunt u een bytearray decomprimeren volgens een compressiealgoritme. Nadat u compress() en uncompress() hebt opgeroepen, wordt de lengte van de bytearray ingesteld op de nieuwe lengte en wordt de eigenschap position ingesteld op het einde. In de klasse CompressionAlgorithm zijn constanten gedefinieerd waarmee u de compressiealgoritme kunt opgeven. In AIR worden zowel de Deflate- als de ZLIB-algoritme ondersteund. De Deflate-compressiealgoritme wordt gebruikt in diverse compressie-indelingen, zoals ZLIB, GZIP en enkele ZIP-implementaties. De gecomprimeerde ZLIBgegevensindeling wordt beschreven in http://www.ietf.org/rfc/rfc1950.txt en de Deflate-compressiealgoritme wordt beschreven in http://www.ietf.org/rfc/rfc1951.txt.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 162 Werken met bytearrays
In het volgende voorbeeld wordt een bytearray met de naam bytes gecomprimeerd met de Deflate-algoritme: bytes.compress(CompressionAlgorithm.DEFLATE);
In het volgende voorbeeld wordt een gecomprimeerde bytearray gedecomprimeerd met de Deflate-algoritme: bytes.uncompress(CompressionAlgorithm.DEFLATE);
Objecten lezen en schrijven Met de methoden readObject() en writeObject() leest u een object in een bytearray en schrijft u een object naar een bytearray, gecodeerd in geserialiseerde AMF-indeling (Action Message Format). AMF is een berichtenprotocol dat door Adobe is gemaakt en wordt gebruikt door diverse ActionScript 3.0-klassen, zoals Netstream, NetConnection, NetStream, LocalConnection en Shared Objects. Een typemarkering van één byte bevat de beschrijving van het type van de gecodeerde gegevens die volgen. AMF gebruikt de volgende 13 gegevenstypen: value-type = undefined-marker | null-marker | false-marker | true-marker | integer-type | double-type | string-type | xml-doc-type | date-type | array-type | object-type | xml-type | byte-array-type
De gecodeerde gegevens volgen op de typemarkering, tenzij de markering één mogelijke waarde bevat, zoals null of true of false, zodat verder niets wordt gecodeerd. Er zijn twee versies van AMF: AMF0 en AMF3. AMF 0 ondersteunt het verzenden van complexe objecten via verwijzingen en staat eindpunten toe voor het herstellen van objectrelaties. AMF 3 is verbeterd ten opzichte van AMF 0 doordat naast objectverwijzingen ook objectkenmerken en tekenreeksen kunnen worden verzonden en nieuwe gegevenstypen worden ondersteund die in ActionScript 3.0 zijn geïntroduceerd. De eigenschap ByteArray.objectEcoding geeft aan welke versie van AMF wordt gebruikt om de objectgegevens te coderen. In de klasse flash.net.ObjectEncoding zijn constanten gedefinieerd waarmee de AMF-versie wordt opgegeven: ObjectEncoding.AMF0 en ObjectEncoding.AMF3. import flash.filesystem.*; import flash.utils.ByteArray; // Label component must be in Library import fl.controls.Label;
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 163 Werken met bytearrays
var bytes:ByteArray = new ByteArray(); var myLabel:Label = new Label(); myLabel.move(150, 150); myLabel.width = 200; addChild(myLabel); var myXML:XML = <menuName>burger <price>3.95 <menuName>fries <price>1.45 // Write XML object to ByteArray bytes.writeObject(myXML); bytes.position = 0;//reset position to beginning bytes.compress(CompressionAlgorithm.DEFLATE);// compress ByteArray outFile("order", bytes); myLabel.text = "Wrote order file to desktop!"; function outFile(fileName:String, data:ByteArray):void { var outFile:File = File.desktopDirectory; // dest folder is desktop outFile = outFile.resolvePath(fileName); // name of file to write var outStream:FileStream = new FileStream(); // open output file stream in WRITE mode outStream.open(outFile, FileMode.WRITE); // write out the file outStream.writeBytes(data, 0, data.length); // close it outStream.close(); }
Met de methode readObject() wordt een object in geserialiseerde AMF-indeling ingelezen vanuit een bytearray en opgeslagen in een object van het opgegeven type. In het volgende voorbeeld wordt het bestand order vanaf de desktop ingelezen in een bytearray (inBytes). Vervolgens wordt het bestand gedecomprimeerd en wordt readObject() opgeroepen om het op te slaan in het XML-object orderXML. In het voorbeeld wordt elk knooppunt in een lusconstructie for each() toegevoegd aan een tekstgebied voor weergave. In het voorbeeld wordt ook de waarde van de eigenschap objectEncoding weergegeven, evenals een header voor de inhoud van het bestand order. import flash.filesystem.*; import flash.utils.ByteArray; // TextArea component must be in Library import fl.controls.TextArea;
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 164 Werken met bytearrays
var inBytes:ByteArray = new ByteArray(); // define text area for displaying XML content var myTxt:TextArea = new TextArea(); myTxt.width = 550; myTxt.height = 400; addChild(myTxt); //display objectEncoding and file heading myTxt.text = "Object encoding is: " + inBytes.objectEncoding + "\n\n" + "order file: \n\n"; readFile("order", inBytes); inBytes.position = 0; // reset position to beginning inBytes.uncompress(CompressionAlgorithm.DEFLATE); inBytes.position = 0;//reset position to beginning // read XML Object var orderXML:XML = inBytes.readObject(); //for each node in orderXML for each(var child:XML in orderXML) { // append child node to text area myTxt.text += child + "\n"; } // read specified file into byte array function readFile(fileName:String, data:ByteArray) { var inFile:File = File.desktopDirectory; // source folder is desktop inFile = inFile.resolvePath(fileName); // name of file to read var inStream:FileStream = new FileStream(); inStream.open(inFile, FileMode.READ); inStream.readBytes(data, 0, data.length); inStream.close(); }
Voorbeeld van een bytearray: een ZIP-bestand lezen In dit voorbeeld ziet u hoe een eenvoudig ZIP-bestand wordt gelezen dat verschillende typen bestanden bevat. Hiervoor worden relevante gegevens uit de metagegevens van elk bestand opgehaald, waarbij elk bestand in een bytearray wordt gedecomprimeerd en naar de desktop wordt geschreven. De algemene structuur van een ZIP-bestand is gebaseerd op de specificatie van PKWARE Inc., die u kunt vinden op http://www.pkware.com/documents/casestudies/APPNOTE.TXT. Eerst staan er een bestandsheader en bestandsgegevens voor het eerste bestand in het ZIP-bestand, gevolgd door een combinatie van een bestandsheader en bestandsgegevens voor elk ander bestand. (De structuur van de bestandsheader wordt later beschreven.) Daarna bevat het ZIP-bestand eventueel een record met een gegevensdescriptor (gewoonlijk wanneer het ZIP-bestand in het geheugen is gemaakt in plaats van opgeslagen op een schijf). Hierna volgen diverse optionele elementen: decoderingsheader van archief, extra gegevensrecord voor archief, centrale mapstructuur, Zip64-einde van centrale maprecord, Zip64-einde van centrale maplocator en het einde van de centrale maprecord. De code in dit voorbeeld is alleen geschreven om ZIP-bestanden te parseren die geen mappen bevatten en er worden geen records met een gegevensdescriptor verwacht. Alle informatie na de laatste bestandsgegevens wordt genegeerd. De bestandsheader voor elk bestand heeft de volgende indeling:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 165 Werken met bytearrays
handtekening van bestandsheader
4 bytes
vereiste versie
2 bytes
algemene bitvlag
2 bytes
compressiemethode
2 bytes (8=DEFLATE; 0=UNCOMPRESSED)
tijd van laatste bestandswijziging
2 bytes
datum van laatste bestandswijziging
2 bytes
crc-32
4 bytes
gecomprimeerde grootte
4 bytes
ongecomprimeerde grootte
4 bytes
lengte van bestandsnaam
2 bytes
lengte van extra veld
2 bytes
bestandsnaam
variabele
extra veld
variabele
Na de bestandsheader volgen de werkelijke bestandsgegevens die gecomprimeerd of niet kunnen zijn, afhankelijk van de vlag voor de compressiemethode. De vlag is 0 (nul) als de bestandsgegevens niet zijn gecomprimeerd, 8 als de gegevens zijn gecomprimeerd met de Deflate-algoritme of een andere waarde voor andere compressiealgoritmen. De gebruikersinterface voor dit voorbeeld bestaat uit een label en een tekstgebied (taFiles). De toepassing schrijft de volgende informatie naar het tekstgebied voor elk bestand dat in het ZIP-bestand wordt aangetroffen: bestandsnaam, gecomprimeerde grootte en niet-gecomprimeerde grootte. Aan het begin van het programma worden de volgende taken uitgevoerd:
• De vereiste klassen worden geïmporteerd. import flash.filesystem.*; import flash.utils.ByteArray; import flash.events.Event;
• De gebruikersinterface wordt gedefinieerd. import fl.controls.*; //requires TextArea and Label components in the Library var taFiles = new TextArea(); var output = new Label(); taFiles.setSize(320, 150); taFiles.move(10, 30); output.move(10, 10); output.width = 150; output.text = "Contents of HelloAir.zip"; addChild(taFiles); addChild(output);
• De bytearray bytes wordt gedefinieerd. var bytes:ByteArray = new ByteArray();
• Er worden variabelen gedefinieerd voor het opslaan van metagegevens uit de bestandsheader.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 166 Werken met bytearrays
// var var var var var var var var
variables for reading fixed portion of file header fileName:String = new String(); flNameLength:uint; xfldLength:uint; offset:uint; compSize:uint; uncompSize:uint; compMethod:int; signature:int;
• De objecten File (zfile) en FileStream (zStream) worden gedefinieerd voor het ZIP-bestand en de locatie wordt opgegeven van het ZIP-bestand waaruit de bestanden worden opgehaald: een bestand met de naam “HelloAIR.zip” in de desktopmap. // File variables for accessing .zip file var zfile:File = File.desktopDirectory.resolvePath("HelloAIR.zip"); var zStream:FileStream = new FileStream();
Het programma begint met het openen van het ZIP-bestand in de leesmodus. zStream.open(zfile, FileMode.READ);
Vervolgens wordt de eigenschap endian van bytes op LITTLE_ENDIAN ingesteld om aan te geven dat de minst significante byte eerst wordt aangegeven in de bytevolgorde van numerieke velden. bytes.endian = Endian.LITTLE_ENDIAN;
Vervolgens wordt met de instructie while() een lus gestart die wordt uitgevoerd tot de huidige positie in de bestandsstroom groter is dan of gelijk is aan de grootte van het bestand. while (zStream.position < zfile.size) {
Met de eerste instructie in de lus worden de eerste 30 bytes van de bestandsstroom ingelezen in de bytearray bytes. De eerste 30 bytes bevatten het gedeelte van de eerste bestandsheader dat een vaste grootte heeft. // read fixed metadata portion of local file header zStream.readBytes(bytes, 0, 30);
Vervolgens wordt een geheel getal (signature) gelezen uit de eerste bytes van de header die uit 30 bytes bestaat. In de definitie van de ZIP-indeling is opgegeven dat de handtekening voor elke bestandsheader de hexadecimale waarde 0x04034b50 heeft; als de handtekening anders is, betekent dit dat het einde van het bestandsgedeelte van het ZIPbestand is bereikt en dat er geen bestanden meer zijn om uit te pakken. In dat geval wordt de while-lus onmiddellijk beëindigd en wordt niet gewacht tot het einde van de bytearray is bereikt. bytes.position = 0; signature = bytes.readInt(); // if no longer reading data files, quit if (signature != 0x04034b50) { break; }
In het volgende deel van de code wordt de headerbyte op positie 8 gelezen en wordt de waarde opgeslagen in de variabele compMethod. Deze byte bevat een waarde die aangeeft met welke compressiemethode dit bestand is gecomprimeerd. Er zijn diverse compressiemethoden toegestaan, maar in de praktijk gebruiken bijna alle ZIPbestanden de Deflate-compressiealgoritme. Als het huidige bestand is gecomprimeerd met Deflate-compressie, is compMethod 8; als het bestand niet is gecomprimeerd, is compMethod 0.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 167 Werken met bytearrays
Na de eerste 30 bytes volgt een gedeelte van de header met een variabele lengte dat de bestandsnaam en eventueel een extra veld bevat. In de variabele offset is de grootte van dit gedeelte opgeslagen. De grootte wordt berekend door de lengte van de bestandsnaam en de lengte van het extra veld op te tellen. Deze waarden worden ingelezen uit de header op positie 26 en 28. offset = 0;// stores length of variable portion of metadata bytes.position = 26; // offset to file name length flNameLength = bytes.readShort();// store file name offset += flNameLength; // add length of file name bytes.position = 28;// offset to extra field length xfldLength = bytes.readShort(); offset += xfldLength;// add length of extra field
Vervolgens wordt uit het gedeelte van de bestandsheader met variabele lengte het aantal bytes ingelezen dat is opgeslagen in de variabele offset. // read variable length bytes between fixed-length header and compressed file data zStream.readBytes(bytes, 30, offset);
De bestandsnaam wordt ingelezen vanuit het gedeelte van de header met variabele lengte en samen met de gecomprimeerde en niet-gecomprimeerde (oorspronkelijke) grootte van het bestand weergegeven in het tekstgebied. bytes.position = 30; fileName = bytes.readUTFBytes(flNameLength); // read file name taFiles.appendText(fileName + "\n"); // write file name to text area bytes.position = 18; compSize = bytes.readUnsignedInt(); // store size of compressed portion taFiles.appendText("\tCompressed size is: " + compSize + '\n'); bytes.position = 22; // offset to uncompressed size uncompSize = bytes.readUnsignedInt(); // store uncompressed size taFiles.appendText("\tUncompressed size is: " + uncompSize + '\n');
In het voorbeeld wordt de rest van het bestand vanuit de bestandsstroom ingelezen in bytes voor de lengte die is opgegeven door de gecomprimeerde grootte, waarbij de bestandsheader in de eerste 30 bytes wordt overschreven. De gecomprimeerde grootte is nauwkeurig, zelfs als het bestand niet is gecomprimeerd, omdat de gecomprimeerde grootte in dat geval gelijk is aan de niet-gecomprimeerde grootte van het bestand. // read compressed file to offset 0 of bytes; for uncompressed files // the compressed and uncompressed size is the same zStream.readBytes(bytes, 0, compSize);
Vervolgens wordt het gecomprimeerde bestand gedecomprimeerd en wordt de functie outfile() opgeroepen om het naar de uitvoerstroom te schrijven. De bestandsnaam en de bytearray die de bestandsgegevens bevat, worden doorgegeven aan outfile(). if (compMethod == 8) // if file is compressed, uncompress { bytes.uncompress(CompressionAlgorithm.DEFLATE); } outFile(fileName, bytes); // call outFile() to write out the file
De accolade-sluiten geeft het einde van de while-lus en van de toepassingscode aan, maar niet van de methode outFile(). De while-lus wordt opnieuw gestart en de volgende bytes in het ZIP-bestand worden verwerkt: er wordt een ander bestand uitgepakt of de verwerking van het ZIP-bestand wordt beëindigd als het laatste bestand is verwerkt. } // end of while loop
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 168 Werken met bytearrays
Met de functie outfile() wordt in de schrijfmodus op de desktop een uitvoerbestand geopend dat de naam krijgt die is opgegeven met de parameterfilename. Vervolgens wordt het gegevensbestand vanuit de parameter data naar de uitvoerstroom (outStream) geschreven en wordt het bestand gesloten. function outFile(fileName:String, data:ByteArray):void { var outFile:File = File.desktopDirectory; // destination folder is desktop outFile = outFile.resolvePath(fileName); // name of file to write var outStream:FileStream = new FileStream(); // open output file stream in WRITE mode outStream.open(outFile, FileMode.WRITE); // write out the file outStream.writeBytes(data, 0, data.length); // close it outStream.close(); }
169
Hoofdstuk 18: Werken met lokale SQLdatabases Adobe AIR biedt de mogelijkheid om lokale SQL-databases te maken en te gebruiken. De runtime bevat een SQLdatabase-engine met ondersteuning voor vele standaardfuncties van SQL via het open-source databasesysteem SQLite. U kunt een lokale SQL-database gebruiken om lokale, niet-vluchtige gegevens op te slaan, Deze kan bijvoorbeeld worden gebruikt voor toepassingsgegevens, gebruikersinstellingen voor de toepassing of gegevens van een ander type die u lokaal met de toepassing wilt opslaan.
Aanvullende online informatie over lokale SQLdatabases In deze bronnen vindt u meer informatie over het werken met lokale SQL-databases: Snelstarthandleidingen (Adobe AIR Developer Connection) • Asynchroon werken met een lokale SQL-database
• Synchroon werken met een lokale SQL-database • Een gecodeerde database gebruiken Language Reference • SQLCollationType
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 170 Werken met lokale SQL-databases
• SQLUpdateEvent • SQLViewSchema Adobe Developer Connection - Artikels en voorbeelden • Adobe AIR Developer Connection for Flash (zoek naar ‘AIR SQL’)
Informatie over lokale SQL-databases Adobe AIR bevat een op SQL gebaseerde engine voor relationele databases die binnen de runtime wordt uitgevoerd. De gegevens worden lokaal opgeslagen in databasebestanden op de computer waarop de AIR-toepassing wordt uitgevoerd (bijvoorbeeld de vaste schijf van de computer). Aangezien de database lokaal wordt uitgevoerd en de gegevensbestanden lokaal worden opgeslagen, kan een database altijd door een AIR-toepassing worden gebruikt, ongeacht of een netwerkverbinding aanwezig is. Dit betekent dat de lokale SQL-database-engine van de runtime een handige manier is om niet-vluchtige, lokale toepassingsgegevens op te slaan, met name als u ervaring hebt met SQLen relationele databases.
Toepassingen voor lokale SQL-databases De AIR-functies voor lokale SQL-databases kunnen worden gebruikt voor willekeurige toepassingen waarbij toepassingsgegevens moeten worden opgeslagen op de lokale computer van de gebruiker. Adobe AIR biedt verschillende manieren om gegevens lokaal op te slaan, waarbij elke manier andere voordelen heeft. Hieronder ziet u een aantal mogelijke toepassingen voor een lokale SQL-database in uw AIR-toepassing:
• Voor een op gegevens gebaseerde toepassing (bijvoorbeeld een adresboek) kunt u een database gebruiken om de hoofdtoepassingsgegevens op te slaan.
• Voor een op documenten gebaseerde toepassing (waarbij gebruikers documenten creëren om ze op te slaan en mogelijk te delen) kan elk document als een databasebestand worden opgeslagen op een door de gebruiker opgegeven locatie. (Houd er wel rekening mee dat als de database niet is gecodeerd, iedere AIR-toepassing in staat is het databasebestand te openen. Het is aan te raden mogelijk gevoelige documenten te coderen.)
• Voor een toepassing met netwerkverbindingen kunt u een database gebruiken om toepassingsgegevens op te slaan in een lokale cache, of om gegevens tijdelijk op te slaan wanneer er geen netwerkverbinding beschikbaar is. U kunt desgewenst een procedure creëren om de lokale database te synchroniseren met de netwerklocatie voor gegevensopslag.
• Voor alle toepassingen kunt u een database gebruiken om de toepassingsinstellingen van individuele gebruikers op te slaan, bijvoorbeeld gebruikersopties of toepassingsinformatie zoals venstergrootte en -positie.
Informatie over AIR-databases en databasebestanden Een individuele, lokale SQL-database van Adobe AIR wordt als één bestand opgeslagen in het bestandssysteem van de computer. De runtime bevat de SQL-database-engine die het creëren en indelen van databasebestanden, en het bewerken en ophalen van gegevens in een databasebestand beheert. De runtime geeft niet aan hoe of waar de databasegegevens worden opgeslagen in het bestandssysteem - elke database bestaat uit één bestand. U geeft de locatie voor het databasebestand in het bestandssysteem op. Eén AIR-toepassing kan een of meer databases (met andere woorden aparte databasebestanden) benaderen. Aangezien de runtime elke database als één bestand opslaat in het bestandssysteem, kunt u de locatie van uw database afstemmen op het ontwerp van uw toepassing en de
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 171 Werken met lokale SQL-databases
toegangsbeperkingen van het besturingssysteem. Iedere gebruiker kan een apart databasebestand voor zijn/haar specifieke gegevens hebben, of u kunt één databasebestand voor alle gebruikers van de toepassing op één computer plaatsen zodat de gegevens kunnen worden gedeeld. Aangezien de gegevens zich lokaal op één computer bevinden, worden de gegevens niet automatisch gedeeld met gebruikers op andere computers. De lokale SQL-database-engine biedt geen mogelijkheid om SQL-instructies uit te voeren in een externe of servergebaseerde database.
Informatie over relationele databases Een relationele database is een mechanisme voor het opslaan (en ophalen) van gegevens op een computer. De gegevens zijn verdeeld in tabellen: rijen geven records of items weer, en kolommen (worden ook soms “velden” genoemd) verdelen elke record in individuele waarden. Een adresboektoepassing kan bijvoorbeeld een tabel met de naam “vrienden” bevatten. Elke rij van de tabel is dan één vriend die in de database is opgeslagen. De kolommen van de tabel bevatten gegevens zoals voornaam, achternaam, geboortedatum enzovoort. Voor iedere vriendrij van de tabel slaat de database een aparte waarde voor elke kolom op. Relationele databases zijn ontworpen voor de opslag van complexe gegevens, waarbij een item is gekoppeld of gerelateerd aan items van een ander type. In een relationele database worden gegevens met een één-op-vele-relatie (waarbij één record kan zijn gekoppeld aan meerdere records van een ander type) doorgaans verdeeld over verschillende tabellen. Als u bijvoorbeeld uw adresboektoepassing wilt gebruiken om voor iedere vriend meerdere telefoonnummers op te slaan, is dat een één-op-vele-relatie. De tabel “vrienden” bevat in dat geval alle persoonlijke gegevens van iedere vriend. Een andere tabel, “telefoonnummers”, kan dan alle telefoonnummers van alle vrienden bevatten. In de database worden niet alleen de gegevens van vrienden en telefoonnummers opgeslagen. Elke tabel heeft ook een gegevensitem nodig om de relatie tussen de twee tabellen bij te houden, met andere woorden om individuele vriendrecords te koppelen aan de overeenkomstige telefoonnummers. Dit gegevensitem wordt een primaire sleutel genoemd, een unieke identificator die elke tabelrij verschillend maakt van alle overige rijen uit die tabel. De primaire sleutel kan een “natuurlijke sleutel” zijn, waarbij de sleutel een van de gegevensitems is die elke record uit een tabel op een natuurlijke manier uniek maken. Als u in de tabel “vrienden” bijvoorbeeld weet dat al uw vrienden een andere geboortedatum hebben, kunt u de kolom voor de geboortedatum instellen als primaire sleutel (een natuurlijke sleutel) voor de tabel “vrienden”. Als er geen natuurlijke sleutel is, maakt u een afzonderlijke kolom met een primaire sleutel, zoals "vriend-id" — een kunstmatige waarde die de toepassing gebruikt om de rijen van elkaar te onderscheiden. Met behulp van een primaire sleutel kunt u relaties tussen meerdere tabellen definiëren. Stel dat de tabel "vrienden" een kolom "vriend-id" heeft die voor elke rij een uniek getal (de vriend-id) bevat. De gerelateerde tabel “telefoonnummers” kan in twee kolommen worden verdeeld, één met de “id_vriend” van de vriend die het desbetreffende telefoonnummer heeft, en één met het daadwerkelijke telefoonnummer. Op die manier kunnen alle telefoonnummers, ongeacht het aantal telefoonnummers per vriend, worden opgeslagen in de tabel “telefoonnummers” en via de primaire sleutel “id_vriend” worden gekoppeld aan de overeenkomstige vriend. Wanneer de primaire sleutel van een tabel wordt gebruikt in een gerelateerde tabel om de relatie tussen de records aan te geven, wordt de waarde in de gerelateerde tabel een externe sleutel genoemd. In tegenstelling tot vele databases biedt de lokale database-engine van AIR niet de mogelijkheid om beperkingen voor externe sleutels in te stellen. Deze beperkingen controleren automatisch of een ingevoegde of bijgewerkte externe-sleutelwaarde overeenkomt met een rij in de tabel met de primaire sleutel. Relaties op basis van externe sleutels vormen echter een belangrijk onderdeel van de structuur van een relationele database, en u wordt aangeraden externe sleutels te gebruiken wanneer u relaties tussen de tabellen van uw database definieert.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 172 Werken met lokale SQL-databases
Informatie over SQL SQL (Structured Query Language) wordt bij relationele databases gebruikt om gegevens te bewerken en te zoeken. SQL is een beschrijvende en geen proceduretaal. Een SQL-instructie beschrijft de gegevensset die u zoekt maar geeft de computer geen instructies over hoe de gegevens moeten worden gezocht. De database-engine bepaalt hoe de gegevens worden gezocht. De taal SQL is gestandaardiseerd door het ANSI (American National Standards Institute). De lokale SQL-database van Adobe AIR ondersteunt het grootste deel van de standaard SQL-92. Zie de bijlage "SQL support in local databases" (SQL-ondersteuning in lokale databases) in ActionScript 3.0 Language and Components Reference voor een specifieke beschrijving van de SQL-onderdelen die worden ondersteund in Adobe AIR.
Informatie over klassen van SQL-databases Als u met lokale SQL-databases wilt werken in ActionScript 3.0, moet u instanties van deze klassen uit het pakket flash.data gebruiken: Klasse
Beschrijving
flash.data.SQLConnection
Biedt de mogelijkheid om databases (databasebestanden) te creëren en te openen, evenals methoden voor het uitvoeren van bewerkingen op databaseniveau en het besturen van databasetransacties.
flash.data.SQLStatement
Vertegenwoordigt één SQL-instructie (één query of opdracht) die op een database wordt uitgevoerd, inclusief het definiëren van de instructietekst en het instellen van parameterwaarden.
flash.data.SQLResult
Biedt een manier om informatie over of het resultaat van de uitvoering van een instructie op te vragen, zoals de resulterende rijen na een SELECT-instructie, het aantal rijen dat wordt beïnvloed door een UPDATE- of DELETE-instructie enzovoort.
Als u schema-informatie met een beschrijving van de structuur van een database wilt verkrijgen, moet u deze klassen uit het pakket flash.data gebruiken: Klasse
Beschrijving
flash.data.SQLSchemaResult
Fungeert als container voor databaseschemaresultaten die worden gegenereerd door het oproepen van de methode SQLConnection.loadSchema().
flash.data.SQLTableSchema
Biedt informatie over één tabel van een database.
flash.data.SQLViewSchema
Biedt informatie over één weergave van een database.
flash.data.SQLIndexSchema
Biedt informatie over één kolom van een tabel of één weergave van een database.
flash.data.SQLTriggerSchem a
Biedt informatie over één trigger van een database.
Andere klassen uit het pakket flash.data bieden constanten die worden gebruikt met de klassen SQLConnection en SQLColumnSchema: Klasse
Beschrijving
flash.data.SQLMode
Definieert een set van constanten voor de mogelijke waarden van de parameter openMode van de methoden SQLConnection.open() en SQLConnection.openAsync().
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 173 Werken met lokale SQL-databases
Klasse
Beschrijving
flash.data.SQLColumnNameStyle
Definieert een set van constanten voor de mogelijke waarden van de eigenschap SQLConnection.columnNameStyle.
flash.data.SQLTransactionLockType Definieert een set van constanten voor de mogelijke waarden van de optieparameter van de methode SQLConnection.begin(). flash.data.SQLCollationType
Definieert een set van constanten voor de mogelijke waarden van de eigenschap SQLColumnSchema.defaultCollationType en de parameter defaultCollationType van de constructor SQLColumnSchema().
Daarnaast vertegenwoordigen de volgende klassen uit het pakket flash.events de gebeurtenissen (en ondersteunende constanten) die u gebruikt: Klasse
Beschrijving
flash.data.SQLEvent
Definieert de gebeurtenissen die door een SQLConnection- of SQLStatement-instantie worden verzonden wanneer een of meer bewerkingen uit de instantie met succes zijn uitgevoerd. Voor elke bewerking is een gekoppelde gebeurtenistypeconstante gedefinieerd in de klasse SQLEvent.
flash.data.SQLErrorEvent
Definieert de gebeurtenis die door een SQLConnection- of SQLStatement-instantie wordt verzonden wanneer een of meer bewerkingen uit de instantie een fout opleveren.
flash.data.SQLUpdateEvent
Definieert de gebeurtenis die door een SQLConnection-instantie wordt verzonden wanneer tabelgegevens in een van de gekoppelde databases veranderen door de uitvoering van de SQL-instructie INSERT, UPDATE of DELETE.
Ten slotte bieden de volgende klassen uit het pakket flash.errors informatie over bewerkingsfouten in de database: Klasse
Beschrijving
flash.data.SQLError
Biedt informatie over een bewerkingsfout in de database, zoals de bewerking die is mislukt en de oorzaak van de fout.
flash.data.SQLErrorEvent
Definieert een set van constanten voor de mogelijke waarden van de eigenschap operation van de klasse SQLError, die de databasebewerking aangeeft waarbij de fout is opgetreden.
Informatie over synchrone en asynchrone uitvoeringsmodi Wanneer u code schrijft om met een lokale SQL-database te werken, selecteert u een van de twee beschikbare uitvoeringsmodi voor bewerkingen in de database: synchroon of asynchroon. De codevoorbeelden tonen op algemene manier hoe u elke bewerking op beide manieren kunt uitvoeren zodat u het voorbeeld kunt gebruiken dat het meest geschikt is voor uw behoeften. In asynchrone uitvoeringsmodus geeft u de runtime een instructie, waarna de runtime een gebeurtenis verzendt wanneer de desbetreffende bewerking is voltooid of mislukt. Eerst geeft u de database-engine de opdracht een bewerking uit te voeren. De database-engine werkt op de achtergrond terwijl de toepassing verderwerkt. Wanneer ten slotte de bewerking is voltooid (of mislukt), verzendt de database-engine een gebeurtenis. Uw code, geactiveerd door de gebeurtenis, voert indien nodig daarop volgende bewerkingen uit. Deze procedure heeft een groot voordeel: de runtime voert de databasebewerkingen op de achtergrond uit terwijl de hoofdtoepassingscode verder wordt uitgevoerd. Als de databasebewerking lange tijd duurt, blijft de toepassing verderwerken. En het belangrijkste is dat interactie met de gebruiker mogelijk blijft omdat het scherm niet bevriest. Het nadeel is dat asynchrone bewerkingscode soms complexer is om te schrijven. Dit is doorgaans het geval wanneer meerdere afhankelijke bewerkingen moeten worden verdeeld tussen verschillende gebeurtenislistenermethoden.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 174 Werken met lokale SQL-databases
Conceptueel is het eenvoudiger om bewerkingen als één sequentie van stappen (een set van synchrone bewerkingen) te beschrijven in plaats van als een set van bewerkingen verdeeld in meerdere gebeurtenislistenermethoden. Naast asynchrone databasebewerkingen is met Adobe AIR ook het synchroon uitvoeren van databasebewerkingen mogelijk. In de synchrone uitvoeringsmodus worden de bewerkingen niet op de achtergrond uitgevoerd. In plaats daarvan worden ze uitgevoerd volgens dezelfde uitvoeringssequentie als alle andere toepassingscode. U geeft de databaseengine de opdracht een bewerking uit te voeren. Vervolgens wordt de code op dat punt onderbroken terwijl de database-engine zijn werk doet. Nadat de bewerking is voltooid, gaat de uitvoering verder vanaf de volgende regel van uw code. U bepaalt op SQLConnection-niveau welke uitvoeringsmodus (synchroon of asynchroon) voor bewerkingen wordt gebruikt. Het is niet mogelijk om via één enkele databaseverbinding bepaalde bewerkingen of instructies synchroon en andere asynchroon uit te voeren. U bepaalt welke uitvoeringsmodus (synchroon of asynchroon) voor een SQLConnection wordt gebruikt door een SQLConnection-methode op te roepen om de database te openen. Als u SQLConnection.open() oproept, werkt de verbinding in synchrone uitvoeringsmodus. Roept u SQLConnection.openAsync() op, dan werkt de verbinding in asynchrone uitvoeringsmodus. Nadat een SQLConnection-instantie met een database is verbonden met behulp van open() of openAsync(), wordt deze in synchrone of asynchrone uitvoeringsmodus vergrendeld, tenzij u de verbinding met de database sluit en weer opent. Elke uitvoeringsmodus heeft specifieke voordelen. De meeste aspecten van beide modi zijn identiek. Er zijn echter bepaalde verschillen waarmee u het best rekening houdt terwijl u in een bepaalde modus werkt. Zie “Synchrone en asynchrone databasebewerkingen gebruiken” op pagina 195 voor meer informatie over deze onderwerpen en suggesties voor het werken in elke modus.
Databases creëren en wijzigen Voordat uw toepassing gegevens kan toevoegen of ophalen, moet er een database met gedefinieerde tabellen aanwezig zijn en moet de database toegankelijk zijn voor uw toepassing. Hieronder wordt beschreven hoe u een database creëert en de gegevensstructuur binnen een database definieert. Deze taken zijn weliswaar minder vaak nodig dan het invoegen en ophalen van gegevens maar zijn toch noodzakelijk voor de meeste toepassingen.
Database creëren Voordat u een databasebestand kunt creëren, moet u een SQLConnection-instantie creëren. Roep de methode open() op om de instantie in synchrone uitvoeringsmodus te openen, of roep de methode openAsync() op om de instantie in asynchrone uitvoeringsmodus te openen. De methoden open() en openAsync() worden gebruikt om een verbinding met een database te openen. Als u een File-instantie gebruikt die verwijst naar een niet-bestaande bestandslocatie voor de parameter reference (de eerste parameter), creëert de methode open() of openAsync() een databasebestand op die bestandslocatie en wordt een verbinding met de zojuist gecreëerde database geopend. Ongeacht of u de methode open() of de methode openAsync() aanroept om een database te maken, de naam van het databasebestand kan een willekeurige bestandsnaam zijn met een willekeurige bestandsnaamextensie. Als u de methode open() of openAsync() oproept met de instelling null voor de parameterreference, wordt een nieuwe database in het geheugen gecreëerd in plaats van een databasebestand op de vaste schijf. De volgende code illustreert het creëren van een databasebestand (een nieuwe database) via de asynchrone uitvoeringsmodus. In dit geval wordt het databasebestand opgeslagen in de opslagmap van de toepassing en krijgt het de bestandsnaam "DBSample.db":
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 175 Werken met lokale SQL-databases
import flash.data.SQLConnection; import flash.events.SQLErrorEvent; import flash.events.SQLEvent; import flash.filesystem.File; var conn:SQLConnection = new SQLConnection(); conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, errorHandler); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); conn.openAsync(dbFile); function openHandler(event:SQLEvent):void { trace("the database was created successfully"); } function errorHandler(event:SQLErrorEvent):void { trace("Error message:", event.error.message); trace("Details:", event.error.details); }
Als u bewerkingen synchroon wilt uitvoeren, roept u de methode open() op wanneer u een databaseverbinding opent met de SQLConnection-instantie. In het volgende voorbeeld ziet u hoe u een SQLConnection-instantie creëert en opent die de bewerkingen synchroon uitvoert: import flash.data.SQLConnection; import flash.errors.SQLError; import flash.filesystem.File; var conn:SQLConnection = new SQLConnection(); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); try { conn.open(dbFile); trace("the database was created successfully"); } catch (error:SQLError) { trace("Error message:", error.message); trace("Details:", error.details); }
Databasetabellen creëren Als u een tabel in een database wilt creëren, moet u een SQL-instructie op de desbetreffende database uitvoeren via dezelfde procedure als voor het uitvoeren van een SQL-instructie zoals SELECT, INSERT enzovoort. U creëert een tabel met behulp van de instructie CREATE TABLE, waarbij u kolomdefinities en beperkingen voor de nieuwe tabel opgeeft. Zie “Werken met SQL-instructies” op pagina 178 voor meer informatie over het uitvoeren van SQL-instructies. In het volgende voorbeeld ziet u hoe u een tabel met de naam “employees” in een bestaand databasebestand creëert via de asynchrone uitvoeringsmodus. Let op: deze code gaat ervan uit dat een SQLConnection-instantie met de naam conn al is gedefinieerd en met een database is verbonden.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 176 Werken met lokale SQL-databases
import flash.data.SQLConnection; import flash.data.SQLStatement; import flash.events.SQLErrorEvent; import flash.events.SQLEvent; // ... create and open the SQLConnection instance named conn ... var createStmt:SQLStatement = new SQLStatement(); createStmt.sqlConnection = conn; var sql:String = "CREATE TABLE IF NOT EXISTS employees (" + " empId INTEGER PRIMARY KEY AUTOINCREMENT, " + " firstName TEXT, " + " lastName TEXT, " + " salary NUMERIC CHECK (salary > 0)" + ")"; createStmt.text = sql; createStmt.addEventListener(SQLEvent.RESULT, createResult); createStmt.addEventListener(SQLErrorEvent.ERROR, createError); createStmt.execute(); function createResult(event:SQLEvent):void { trace("Table created"); } function createError(event:SQLErrorEvent):void { trace("Error message:", event.error.message); trace("Details:", event.error.details); }
In het volgende voorbeeld ziet u hoe u een tabel met de naam “employees” in een bestaand databasebestand creëert via de synchrone uitvoeringsmodus. Let op: deze code gaat ervan uit dat een SQLConnection-instantie met de naam conn al is gedefinieerd en met een database is verbonden. import flash.data.SQLConnection; import flash.data.SQLStatement; import flash.errors.SQLError; // ... create and open the SQLConnection instance named conn ... var createStmt:SQLStatement = new SQLStatement(); createStmt.sqlConnection = conn; var sql:String = "CREATE TABLE IF NOT EXISTS employees (" + " empId INTEGER PRIMARY KEY AUTOINCREMENT, " + " firstName TEXT, " + " lastName TEXT, " + " salary NUMERIC CHECK (salary > 0)" + ")"; createStmt.text = sql; try { createStmt.execute(); trace("Table created"); } catch (error:SQLError) { trace("Error message:", error.message); trace("Details:", error.details); }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 177 Werken met lokale SQL-databases
Werken met SQL-databasegegevens Bij het werken met lokale SQL-databases voert u regelmatig dezelfde taken uit, Tot deze taken behoren het tot stand brengen van een verbinding met een database, het toevoegen van gegevens aan tabellen, en het ophalen van gegevens uit tabellen in een database. Bij het uitvoeren van deze taken moet u een aantal aspecten in acht nemen, zoals het werken met gegevenstypen en het verhelpen van fouten. Daarnaast zijn er verschillende databasetaken die u niet zo vaak zult uitvoeren maar doorgaans wel voordat u de veel voorkomende taken kunt uitvoeren. U moet bijvoorbeeld een database creëren en de structuur van de tabellen in de database definiëren voordat u kunt verbinden met de database en gegevens uit tabellen kunt ophalen. Deze minder frequente, initiële setuptaken worden besproken in “Databases creëren en wijzigen” op pagina 174. U kunt kiezen om databasebewerkingen asynchroon uit te voeren, wat betekent dat de database-engine op de achtergrond wordt uitgevoerd en deze u meldt wanneer de bewerking is voltooid (of mislukt) door een gebeurtenis te verzenden. U kunt deze bewerkingen echter ook synchroon uitvoeren. In dat geval worden de databasebewerkingen na elkaar uitgevoerd en wacht de hele toepassing (ook het vernieuwen van het scherm) tot de bewerkingen zijn voltooid voordat andere code wordt uitgevoerd. In de voorbeelden in deze sectie ziet u hoe u de bewerkingen synchroon en asynchroon kunt laten uitvoeren. Zie “Synchrone en asynchrone databasebewerkingen gebruiken” op pagina 195 voor meer informatie over het werken in synchrone of asynchrone uitvoeringsmodus.
Verbinden met een database Voordat u databasebewerkingen kunt uitvoeren, moet u een verbinding met het databasebestand tot stand brengen. Er wordt een SQLConnection-instantie gebruikt om de verbinding met een of meer databases te vertegenwoordigen. De eerste database waarmee u via een SQLConnection-instantie verbinding maakt, wordt de “hoofd”database genoemd. Met deze database maakt u verbinding via de methode open() (voor de synchrone uitvoeringsmodus) of openAsync() (voor de asynchrone uitvoeringsmodus). Als u een database opent via de bewerking openAsync(), moet u de gebeurtenis open van de SQLConnectioninstantie registreren zodat u een melding ontvangt wanneer de bewerking openAsync() is voltooid. Deze registratie is nodig als u wilt dat de gebeurtenis error van de SQLConnection-instantie controleert of de bewerking is voltooid/mislukt. In het volgende voorbeeld ziet u hoe u een bestaand databasebestand opent voor asynchrone uitvoering. Het databasebestand heeft de naam “DBSample.db” en bevindt zich in de toepassingsopslagdirectory van de gebruiker.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 178 Werken met lokale SQL-databases
import flash.data.SQLConnection; import flash.data.SQLMode; import flash.events.SQLErrorEvent; import flash.events.SQLEvent; import flash.filesystem.File; var conn:SQLConnection = new SQLConnection(); conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, errorHandler); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); conn.openAsync(dbFile, SQLMode.UPDATE); function openHandler(event:SQLEvent):void { trace("the database opened successfully"); } function errorHandler(event:SQLErrorEvent):void { trace("Error message:", event.error.message); trace("Details:", event.error.details); }
In het volgende voorbeeld ziet u hoe u een bestaand databasebestand opent voor synchrone uitvoering. Het databasebestand heeft de naam “DBSample.db” en bevindt zich in de toepassingsopslagdirectory van de gebruiker. import flash.data.SQLConnection; import flash.data.SQLMode; import flash.errors.SQLError; import flash.filesystem.File; var conn:SQLConnection = new SQLConnection(); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); try { conn.open(dbFile, SQLMode.UPDATE); trace("the database opened successfully"); } catch (error:SQLError) { trace("Error message:", error.message); trace("Details:", error.details); }
Let op: bij het oproepen van de methode openAsync() in het asynchrone voorbeeld en het oproepen van de methode open() in het synchrone voorbeeld is het tweede argument de constante SQLMode.UPDATE. Als u SQLMode.UPDATE opgeeft voor de tweede parameter (openMode), treedt een fout op als het opgegeven bestand niet bestaat. Als u SQLMode.CREATE opgeeft voor de parameter openMode (of als u geen waarde opgeeft voor de parameter openMode), probeert de runtime een databasebestand te creëren als het opgegeven bestand niet bestaat. Als het bestand echter bestaat, wordt het geopend (vergelijkbaar met het gebruik van SQLMode.Update). U kunt ook SQLMode.READ opgeven voor de parameter openMode als u een bestaande database in alleen-lezen modus wilt openen. In dat geval kunnen gegevens uit de database worden opgehaald maar niet worden toegevoegd, verwijderd of gewijzigd.
Werken met SQL-instructies Een individuele SQL-instructie (een query of opdracht) wordt in de runtime vertegenwoordigd door een SQLStatement-object. Ga als volgt te werk om een SQL-instructie te creëren en uit te voeren:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 179 Werken met lokale SQL-databases
Creëer een SQLStatement-instantie. Het SQLStatement-object vertegenwoordigt de SQL-instructie in uw toepassing. var selectData:SQLStatement = new SQLStatement();
Geef de database op waarop u de query wilt toepassen. Hiervoor stelt u de eigenschap sqlConnection van het SQLStatement-object in op de SQLConnection-instantie die met de gewenste database is verbonden. // A SQLConnection named "conn" has been created previously selectData.sqlConnection = conn;
Geef de daadwerkelijke SQL-instructie op. Creëer de instructietekst als een tekenreeks (String) en wijs deze toe aan de eigenschap text van de SQLStatementinstantie. selectData.text = "SELECT col1, col2 FROM my_table WHERE col1 = :param1";
Definieer functies om het resultaat van de uitvoeringsbewerking (alleen asynchrone uitvoeringsmodus) te verwerken. Gebruik de methode addEventListener() om functies als listeners voor de gebeurtenissen result en error van de SQLStatement-instantie te registreren. // using listener methods and addEventListener(); selectData.addEventListener(SQLEvent.RESULT, resultHandler); selectData.addEventListener(SQLErrorEvent.ERROR, errorHandler); function resultHandler(event:SQLEvent):void { // do something after the statement execution succeeds } function errorHandler(event:SQLErrorEvent):void { // do something after the statement execution fails }
U kunt ook listenermethoden opgeven met behulp van een Responder-object. In dat geval creëert u de Responderinstantie en koppelt u de listenermethoden aan die instantie. // using a Responder (flash.net.Responder) var selectResponder = new Responder(onResult, onError); function onResult(result:SQLResult):void { // do something after the statement execution succeeds } function onError(error:SQLError):void { // do something after the statement execution fails }
Als de instructietekst parameterdefinities bevat, wijst u waarden toe aan de desbetreffende parameters. U wijst parameterwaarden toe via de associatieve-array-eigenschap parameters van de SQLStatement-instantie. selectData.parameters[":param1"] = 25;
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 180 Werken met lokale SQL-databases
Voer de SQL-instructie uit. Roep de methode execute() van de SQLStatement-instantie op. // using synchronous execution mode // or listener methods in asynchronous execution mode selectData.execute();
Als u een Responder in plaats van gebeurtenislisteners gebruikt in asynchrone uitvoeringsmodus, moet u ook de Responder-instantie opgeven voor de methode execute(). // using a Responder in asynchronous execution mode selectData.execute(-1, selectResponder);
Zie de volgende onderwerpen voor specifieke voorbeelden die deze procedurestappen illustreren: “Gegevens ophalen uit een database” op pagina 182 “Gegevens invoegen” op pagina 188 “Gegevens wijzigen of verwijderen” op pagina 190
Parameters gebruiken in instructies Met een SQL-instructieparameter kunt u een herbruikbare SQL-instructie creëren. Bij het gebruik van instructieparameters kunnen waarden binnen de instructie wijzigen (zoals waarden die worden toegevoegd met een instructie van het type INSERT) maar blijft de basistekst van de instructie ongewijzigd. Dat betekent dat het gebruik van parameters prestatievoordelen biedt en het coderen van een toepassing gemakkelijker maakt.
Instructieparameters Een toepassing gebruikt vaak dezelfde SQL-instructie meerdere keren, met slechts een kleine wijziging. Bijvoorbeeld: een voorraadbeheertoepassing waarmee een gebruiker nieuwe voorraaditems kan toevoegen aan de database. De toepassingscode die een voorraaditem toevoegt aan de database voert de SQL-instructie INSERT uit, waarmee de gegevens daadwerkelijk worden toegevoegd aan de database. Elke keer dat de instructie wordt uitgevoerd, is er echter een kleine wijziging. Met name de daadwerkelijke waarden die worden ingevoegd in de tabel, verschillen omdat ze specifiek zijn voor het voorraaditem dat wordt toegevoegd. Als een SQL-instructie meerdere keren maar met verschillende waarden wordt gebruikt, wordt u aangeraden een SQLinstructie te gebruiken die met parameters werkt en niet met literale waarden in de SQL-tekst. Een parameter is een placeholder in de instructietekst die door een daadwerkelijke waarde wordt vervangen elke keer dat de instructie wordt uitgevoerd. Als u parameters in een SQL-instructie wilt gebruiken, creëert u de SQLStatement-instantie op de gewone manier. Voor de daadwerkelijke SQL-instructie die aan de eigenschap text wordt toegewezen, gebruikt u parameterplaceholders in plaats van literale waarden. Vervolgens definieert u de waarde voor elke parameter door de waarde van een element in de eigenschap parameters van de SQLStatement-instantie in te stellen. Aangezien de eigenschap parameters een associatieve array is, stelt u een specifieke waarde in met de volgende syntaxis: statement.parameters[parameter_identifier] = value;
parameter_identifier is een tekenreeks als u een benoemde parameter gebruikt, of een index van gehele getallen als u een onbenoemde parameter gebruikt.
Benoemde parameters gebruiken Een parameter kan benoemd zijn. Een benoemde parameter heeft een specifieke naam die door de database wordt gebruikt om de parameterwaarde te koppelen aan de overeenkomstige placeholderlocatie in de instructietekst. De naam van een parameter bestaat uit het teken “:” of “@” gevolgd door een naam, zoals in de volgende voorbeelden wordt geïllustreerd:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 181 Werken met lokale SQL-databases
:itemName @firstName
De volgende code illustreert het gebruik van benoemde parameters: var sql:String = "INSERT INTO inventoryItems (name, productCode)" + "VALUES (:name, :productCode)"; var addItemStmt:SQLStatement = new SQLStatement(); addItemStmt.sqlConnection = conn; addItemStmt.text = sql; // set parameter values addItemStmt.parameters[":name"] = "Item name"; addItemStmt.parameters[":productCode"] = "12345"; addItemStmt.execute();
Onbenoemde parameters gebruiken Als alternatief voor het gebruik van benoemde parameters kunt u ook onbenoemde parameters gebruiken. Als u een onbenoemde parameter wilt gebruiken, geeft u een parameter in een SQL-instructie aan met een “?” (vraagteken). Aan elke parameter wordt een numerieke index toegewezen, afhankelijk van de volgorde van de parameters in de instructie, te beginnen bij index 0 voor de eerste parameter. In het volgende voorbeeld ziet u een variatie van het vorige voorbeeld, nu met onbenoemde parameters: var sql:String = "INSERT INTO inventoryItems (name, productCode)" + "VALUES (?, ?)"; var addItemStmt:SQLStatement = new SQLStatement(); addItemStmt.sqlConnection = conn; addItemStmt.text = sql; // set parameter values addItemStmt.parameters[0] = "Item name"; addItemStmt.parameters[1] = "12345"; addItemStmt.execute();
Voordelen van het gebruik van parameters Het gebruik van parameters in een SQL-instructie biedt verschillende voordelen: Betere prestaties Een SQLStatement-instantie die parameters gebruikt, kan efficiënter werken dan een instantie die
de SQL-tekst dynamisch genereert bij elke uitvoering. De prestatieverbetering is te danken aan het feit dat de instructie één keer wordt voorbereid en vervolgens meerdere keren met verschillende parameterwaarden kan worden uitgevoerd zonder dat de SQL-instructie opnieuw hoeft te worden gecompileerd. Type toewijzen aan expliciete gegevens Parameters worden gebruikt voor het omzetten van waarden in een toegewezen type als de daadwerkelijke waarden niet bekend zijn op het moment dat de SQL-instructie wordt geschreven. Het gebruik van parameters is de enige manier om de opslagklasse te garanderen van een waarde die in de database wordt opgenomen. Als geen parameters worden gebruikt, probeert de runtime alle waarden om te zetten van hun tekstvorm in een opslagklasse op basis van het type van de overeenkomstige kolom. Zie de sectie "Data type support" (Ondersteuning van gegevenstypen) in de bijlage "SQL support in local databases" (SQL-ondersteuning in lokale databases) in ActionScript 3.0 Language and Components Reference voor meer informatie over opslagklassen en het type van waarden in een kolom. Betere beveiliging Het gebruik van parameters helpt een schadelijke techniek die SQL-injectieaanval wordt genoemd, onmogelijk te maken. Bij een SQL-injectieaanval voert de gebruiker SQL-code in via een voor de gebruiker toegankelijke locatie (zoals een gegevensinvoerveld). Als toepassingscode een SQL-instructie genereert door gebruikersinvoer rechtstreeks samen te voegen tot SQL-tekst, wordt de door de gebruiker ingevoerde SQL-code
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 182 Werken met lokale SQL-databases
uitgevoerd op de database. De volgende code is een voorbeeld van het samenvoegen van gebruikersinvoer tot SQLtekst. Gebruik deze techniek niet: // assume the variables "username" and "password" // contain user-entered data var sql:String = "SELECT userId " + "FROM users " + "WHERE username = '" + username + "' " + " AND password = '" + password + "'"; var statement:SQLStatement = new SQLStatement(); statement.text = sql;
Door instructieparameters in plaats van door de gebruiker ingevoerde waarden samen te voegen tot de tekst voor een instructie, maakt u een SQL-injectieaanval onmogelijk. Er kan geen SQL-injectie plaatsvinden omdat de parameterwaarden expliciet als vervangen waarden worden verwerkt, en niet als waarden die een onderdeel van de literale instructietekst worden. Dit is het aanbevolen alternatief voor de bovenstaande code: // assume the variables "username" and "password" // contain user-entered data var sql:String = "SELECT userId " + "FROM users " + "WHERE username = :username " + " AND password = :password"; var statement:SQLStatement = new SQLStatement(); statement.text = sql; // set parameter values statement.parameters[":username"] = username; statement.parameters[":password"] = password;
Gegevens ophalen uit een database Het ophalen van gegevens uit een database bestaat uit twee stappen. Eerst voert u de SQL-instructie SELECT uit om de gegevensset te beschrijven die u uit de database wilt ophalen. Vervolgens benadert u de opgehaalde gegevens, en geeft u ze weer of bewerkt u ze, afhankelijk van de toepassing.
SELECT-instructies uitvoeren Voor het ophalen van bestaande gegevens uit een database gebruikt u een SQLStatement-instantie. Wijs de juiste SQLinstructie SELECT toe aan de eigenschap text van de instantie en roep vervolgens de methode execute() op. Zie voor meer informatie over de syntaxis van de instructie SELECT de bijlage "SQL support in local databases" (SQLondersteuning in lokale databases) in ActionScript 3.0 Language and Components Reference. Het volgende voorbeeld demonstreert de uitvoering van een SELECT-instructie om gegevens op te halen uit een tabel met de naam 'producten' met de asynchrone uitvoeringsmodus.: var selectStmt:SQLStatement = new SQLStatement(); // A SQLConnection named "conn" has been created previously selectStmt.sqlConnection = conn; selectStmt.text = "SELECT itemId, itemName, price FROM products"; // The resultHandler and errorHandler are listener methods are // described in a subsequent code listing selectStmt.addEventListener(SQLEvent.RESULT, resultHandler); selectStmt.addEventListener(SQLErrorEvent.ERROR, errorHandler); selectStmt.execute();
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 183 Werken met lokale SQL-databases
Het volgende voorbeeld demonstreert de uitvoering van een SELECT-instructie om gegevens op te halen uit een tabel met de naam 'producten' met de asynchrone uitvoeringsmodus.: var selectStmt:SQLStatement = new SQLStatement(); // A SQLConnection named "conn" has been created previously selectStmt.sqlConnection = conn; selectStmt.text = "SELECT itemId, itemName, price FROM products"; // This try..catch block is fleshed out in // a subsequent code listing try { selectStmt.execute(); // accessing the data is shown in a subsequent code listing } catch (error:SQLError) { // error handling is shown in a subsequent code listing }
Nadat in de asynchrone uitvoeringsmodus de uitvoering van de instructie is voltooid, verzendt de SQLStatementinstantie de gebeurtenis result (SQLEvent.RESULT) om aan te geven dat de instructie correct is uitgevoerd. Als u echter een Responder-object hebt opgegeven als argument bij de oproep execute(), wordt de resultaathandlerfunctie van het Responder-object opgeroepen. In de synchrone uitvoeringsmodus wordt de uitvoering onderbroken tot de bewerking execute() is voltooid. Daarna gaat de uitvoering verder vanaf de volgende coderegel.
Resultaatgegevens van SELECT-instructie benaderen Nadat de uitvoering van de instructie SELECT is voltooid, kunnen de opgehaalde gegevens worden benaderd. Elke gegevensrij in de resultaatset SELECT wordt een Object-instantie. Het desbetreffende object heeft eigenschappen waarvan de naam overeenkomt met de naam van de kolommen in de resultaatset. De eigenschappen bevatten de waarden uit de kolommen in de resultaatset. De instructie SELECT geeft bijvoorbeeld een resultaatset met drie kolommen op: “itemId”, “itemName” en “price”. Voor elke rij van de resultaatset wordt een Object-instantie gecreëerd met de eigenschapnamen itemId, itemName en price. Deze eigenschappen bevatten de waarden uit de overeenkomstige kolommen. De volgende code is een vervolg van de vorige code voor het ophalen van gegevens in de asynchrone uitvoeringsmodus. In de code ziet u hoe u de opgehaalde gegevens benadert met de gebeurtenislistenermethode voor resultaatsets.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 184 Werken met lokale SQL-databases
function resultHandler(event:SQLEvent):void { var result:SQLResult = selectStmt.getResult(); var numResults:int = result.data.length; for (var i:int = 0; i < numResults; i++) { var row:Object = result.data[i]; var output:String = "itemId: " + row.itemId; output += "; itemName: " + row.itemName; output += "; price: " + row.price; trace(output); } } function errorHandler(event:SQLErrorEvent):void { // Information about the error is available in the // event.error property, which is an instance of // the SQLError class. }
De volgende code is een uitbreiding van de vorige code voor het ophalen van gegevens in de synchrone uitvoeringsmodus. De code breidt het blok try..catch uit het vorige voorbeeld voor de synchrone uitvoeringsmodus uit om te illustreren hoe u de opgehaalde gegevens benadert. try { selectStmt.execute(); var result:SQLResult = selectStmt.getResult(); var numResults:int = result.data.length; for (var i:int = 0; i < numResults; i++) { var row:Object = result.data[i]; var output:String = "itemId: " + row.itemId; output += "; itemName: " + row.itemName; output += "; price: " + row.price; trace(output); } } catch (error:SQLError) { // Information about the error is available in the // error variable, which is an instance of // the SQLError class. }
Uit de vorige codevoorbeelden blijkt dat de resultaatobjecten zich bevinden in een array die beschikbaar is als de eigenschap data van een SQLResult-instantie. Als u de asynchrone uitvoeringsmodus met een gebeurtenislistener gebruikt, roept u de methode getResult() van de SQLStatement-instantie op om die SQLResult-instantie op te halen. Als u een Responder-argument hebt opgegeven bij de oproep execute(), wordt de SQLResult-instantie opgegeven als argument bij de resultaathandlerfunctie. In de synchrone uitvoeringsmodus roept u de methode getResult() van de SQLStatement-instantie op een willekeurig moment na het oproepen van de methode execute() op. In elk geval hebt u via de array-eigenschap data toegang tot de resultaatrijen nadat u het SQLResultobject hebt verkregen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 185 Werken met lokale SQL-databases
De volgende code definieert een SQLStatement-instantie waarvan de tekst een SELECT-instructie is. De instructie haalt rijen op die de waarden uit de kolommen firstNamelastName bevatten op alle rijen uit de tabel employees. Dit voorbeeld gebruikt de asynchrone uitvoeringsmodus. Nadat de uitvoering is voltooid, wordt de methode selectResult() opgeroepen en worden de resultaatrijen met gegevens benaderd met SQLStatement.getResult() en weergegeven via de methode trace(). Let op: deze code gaat ervan uit dat een SQLConnection-instantie met de naam conn al is gedefinieerd en met de database is verbonden. De code gaat er ook van uit dat de tabel “employees” al is gecreëerd en gegevens bevat. import flash.data.SQLConnection; import flash.data.SQLResult; import flash.data.SQLStatement; import flash.events.SQLErrorEvent; import flash.events.SQLEvent; // ... create and open the SQLConnection instance named conn ... // create the SQL statement var selectStmt:SQLStatement = new SQLStatement(); selectStmt.sqlConnection = conn; // define the SQL text var sql:String = "SELECT firstName, lastName " + "FROM employees"; selectStmt.text = sql; // register listeners for the result and error events selectStmt.addEventListener(SQLEvent.RESULT, selectResult); selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError); // execute the statement selectStmt.execute(); function selectResult(event:SQLEvent):void { // access the result data var result:SQLResult = selectStmt.getResult(); var numRows:int = result.data.length; for (var i:int = 0; i < numRows; i++) { var output:String = ""; for (var columnName:String in result.data[i]) { output += columnName + ": " + result.data[i][columnName] + "; "; } trace("row[" + i.toString() + "]\t", output); } } function selectError(event:SQLErrorEvent):void { trace("Error message:", event.error.message); trace("Details:", event.error.details); }
De volgende code illustreert dezelfde technieken als de vorige code maar in de synchrone uitvoeringsmodus. Het voorbeeld definieert een SQLStatement-instantie waarvan de tekst een SELECT-instructie is. De instructie haalt rijen op die de waarden uit de kolommen firstNamelastName bevatten op alle rijen uit de tabel employees. De resultaatrijen met gegevens worden benaderd met SQLStatement.getResult() en weergegeven via de methode trace(). Let op: deze code gaat ervan uit dat een SQLConnection-instantie met de naam conn al is gedefinieerd en met de database is verbonden. De code gaat er ook van uit dat de tabel “employees” al is gecreëerd en gegevens bevat.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 186 Werken met lokale SQL-databases
import flash.data.SQLConnection; import flash.data.SQLResult; import flash.data.SQLStatement; import flash.errors.SQLError; // ... create and open the SQLConnection instance named conn ... // create the SQL statement var selectStmt:SQLStatement = new SQLStatement(); selectStmt.sqlConnection = conn; // define the SQL text var sql:String = "SELECT firstName, lastName " + "FROM employees"; selectStmt.text = sql; try { // execute the statement selectStmt.execute(); // access the result data var result:SQLResult = selectStmt.getResult(); var numRows:int = result.data.length; for (var i:int = 0; i < numRows; i++) { var output:String = ""; for (var columnName:String in result.data[i]) { output += columnName + ": " + result.data[i][columnName] + "; "; } trace("row[" + i.toString() + "]\t", output); } } catch (error:SQLError) { trace("Error message:", error.message); trace("Details:", error.details); }
Het gegevenstype van SELECT-resultaatgegevens definiëren Elke rij die het resultaat is van een SELECT-instructie, wordt standaard gegenereerd als een Object-instantie met eigenschappen die zijn benoemd volgens de naam van de kolommen in de resultaatset en met de waarde van elke kolom als de waarde van de overeenkomstige eigenschap. Voordat u echter de SQL-instructie SELECT uitvoert, kunt u de eigenschap itemClass van de SQLStatement-instantie instellen op een klasse. Als u de eigenschap itemClass instelt, wordt elke rij die het resultaat is van de instructie SELECT gegenereerd als een instantie van de opgegeven klasse. De runtime wijst de waarden van resultaatkolommen aan eigenschapwaarden toe door de naam van de kolommen in de resultaatset van SELECT te baseren op de naam van de eigenschappen in de klasse itemClass. Elke klasse die is toegewezen als een itemClass-eigenschapwaarde, moet een constructor hebben waarvoor geen parameters nodig zijn. Bovendien moet de klasse één eigenschap hebben voor elke kolom die het resultaat is van de instructie SELECT. Als een kolom in de lijst SELECT geen gekoppelde eigenschapnaam in de klasse itemClass heeft, wordt dit als een fout beschouwd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 187 Werken met lokale SQL-databases
SELECT-resultaten in delen ophalen Bij de uitvoering van een SELECT-instructie worden standaard alle rijen van de resultaatset tegelijk opgehaald. Nadat de instructie is voltooid, verwerkt u doorgaans de opgehaalde gegevens, bijvoorbeeld door objecten te creëren of de gegevens op het scherm weer te geven. Als de instructie een groot aantal rijen genereert, kan het verwerken van alle gegevens tegelijk een grote belasting voor de computer zijn, waardoor de gebruikersinterface niet wordt vernieuwd. U kunt de zichtbare prestaties van uw toepassing verbeteren door te zorgen dat de runtime slechts een bepaald aantal resultaatrijen tegelijk weergeeft. Hierdoor worden de initiële resultaatgegevens sneller weergegeven. Op deze manier kunt u ook de resultaatrijen in sets verdelen zodat de gebruikersinterface wordt bijgewerkt telkens wanneer een set rijen is verwerkt. Let op: deze techniek is alleen nuttig in asynchrone uitvoeringsmodus. Als u de resultaten van SELECT in delen wilt ophalen, geeft u een waarde op voor de eerste parameter van de methode SQLStatement.execute() (de parameter prefetch). De parameter prefetch geeft het aantal rijen aan dat u wilt ophalen de eerste keer dat de instructie wordt uitgevoerd. Wanneer u de methode execute() van een SQLStatementinstantie aanroept, geeft u een prefetch-parameterwaarde op, waarna alleen dat aantal rijen wordt opgehaald: var stmt:SQLStatement = new SQLStatement(); stmt.sqlConnection = conn; stmt.text = "SELECT ..."; stmt.addEventListener(SQLEvent.RESULT, selectResult); stmt.execute(20); // only the first 20 rows (or fewer) are returned
De instructie verzendt de gebeurtenis result wanneer de eerste set resultaatrijen beschikbaar is. De resultaateigenschap data van de SQLResult-instantie bevat de gegevensrijen en de eigenschap complete ervan geeft aan of er nog op te halen resultaatrijen resteren. Als u de volgende set gegevensrijen wilt ophalen, roept u de methode next() van de SQLStatement-instantie op. Net als bij de methode execute() wordt de eerste parameter van de methode next() gebruikt om aan te geven hoeveel rijen moeten worden opgehaald de volgende keer dat de gebeurtenis result wordt verzonden. function selectResult(event:SQLEvent):void { var result:SQLResult = stmt.getResult(); if (result.data != null) { // ... loop through the rows or perform other processing ... if (!result.complete) { stmt.next(20); // retrieve the next 20 rows } else { stmt.removeEventListener(SQLEvent.RESULT, selectResult); } } }
De SQLStatement verzendt de gebeurtenis result elke keer dat de methode next() een volgende set resultaatrijen weergeeft. Dit betekent dat dezelfde listenerfunctie kan worden gebruikt om verder te gaan met het verwerken van resultaten (op basis van next()-oproepen) tot alle rijen zijn opgehaald. Zie de taalverwijzingsbeschrijvingen voor de methode SQLStatement.execute() (de parameterbeschrijving prefetch) en de methode SQLStatement.next().
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 188 Werken met lokale SQL-databases
Gegevens invoegen Voor het ophalen van gegevens uit een database moet de SQL-instructie INSERT worden uitgevoerd. Nadat de instructie is uitgevoerd, hebt u toegang tot de primaire sleutel voor de zojuist ingevoegde rij als de sleutel door de database is gegenereerd.
INSERT-instructies uitvoeren Als u gegevens wilt toevoegen aan een tabel in een database, moet u een SQLStatement-instantie creëren en uitvoeren waarvan de tekst de SQL-instructie INSERT is. In het volgende voorbeeld ziet u hoe u een SQLStatement-instantie gebruikt om een gegevensrij toe te voegen aan de bestaande tabel “employees”. Dit voorbeeld illustreert het invoegen van gegevens in asynchrone uitvoeringsmodus. Let op: deze code gaat ervan uit dat een SQLConnection-instantie met de naam conn al is gedefinieerd en met een database is verbonden. De code gaat er ook van uit dat de tabel “employees” al is gecreëerd. import flash.data.SQLConnection; import flash.data.SQLResult; import flash.data.SQLStatement; import flash.events.SQLErrorEvent; import flash.events.SQLEvent; // ... create and open the SQLConnection instance named conn ... // create the SQL statement var insertStmt:SQLStatement = new SQLStatement(); insertStmt.sqlConnection = conn; // define the SQL text var sql:String = "INSERT INTO employees (firstName, lastName, salary) " + "VALUES ('Bob', 'Smith', 8000)"; insertStmt.text = sql; // register listeners for the result and failure (status) events insertStmt.addEventListener(SQLEvent.RESULT, insertResult); insertStmt.addEventListener(SQLErrorEvent.ERROR, insertError); // execute the statement insertStmt.execute(); function insertResult(event:SQLEvent):void { trace("INSERT statement succeeded"); } function insertError(event:SQLErrorEvent):void { trace("Error message:", event.error.message); trace("Details:", event.error.details); }
In het volgende voorbeeld ziet u hoe u een gegevensrij toevoegt aan de bestaande tabel “employees” in synchrone uitvoeringsmodus. Let op: deze code gaat ervan uit dat een SQLConnection-instantie met de naam conn al is gedefinieerd en met een database is verbonden. De code gaat er ook van uit dat de tabel “employees” al is gecreëerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 189 Werken met lokale SQL-databases
import flash.data.SQLConnection; import flash.data.SQLResult; import flash.data.SQLStatement; import flash.errors.SQLError; // ... create and open the SQLConnection instance named conn ... // create the SQL statement var insertStmt:SQLStatement = new SQLStatement(); insertStmt.sqlConnection = conn; // define the SQL text var sql:String = "INSERT INTO employees (firstName, lastName, salary) " + "VALUES ('Bob', 'Smith', 8000)"; insertStmt.text = sql; try { // execute the statement insertStmt.execute(); trace("INSERT statement succeeded"); } catch (error:SQLError) { trace("Error message:", error.message); trace("Details:", error.details); }
De door de database gegenereerde primaire sleutel van een ingevoegde rij ophalen Vaak moet uw code na het invoegen van een gegevensrij in een tabel de door de database gegenereerde primaire sleutel of de rij-identificatiewaarde voor de zojuist ingevoegde rij weten. Nadat u een rij in één tabel hebt ingevoegd, wilt u bijvoorbeeld rijen toevoegen aan een gerelateerde tabel. In dat geval kunt u het best de waarde van de primaire sleutel als vreemde sleutel in de gerelateerde tabel invoegen. De primaire sleutel van de zojuist ingevoegde rij kan worden opgehaald via het SQLResult-object dat door het uitvoeren van de instructie is gegenereerd. Dit object wordt ook gebruikt om resultaatgegevens te benaderen nadat de instructie SELECT is uitgevoerd. Net als bij alle andere SQLinstructies creëert de runtime na het voltooien van de instructie INSERT een SQLResult-instantie. U benadert de SQLResult-instantie door de methode getResult() van het SQLStatement-object op te roepen als u een gebeurtenislistener of de synchrone uitvoeringsmodus gebruikt. Als u echter de asynchrone uitvoeringsmodus gebruikt en u een Responder-instantie opgeeft voor de oproep execute(), wordt de SQLResult-instantie opgegeven als argument bij de resultaathandlerfunctie. In elk geval heeft de SQLResult-instantie de eigenschap lastInsertRowID, die de rij-identificator van de laatst ingevoegde rij bevat als de uitgevoerde SQL-instructie de instructie INSERT is. In het volgende voorbeeld ziet u hoe u de primaire sleutel van een ingevoegde rij benadert in asynchrone uitvoeringsmodus: insertStmt.text = "INSERT INTO ..."; insertStmt.addEventListener(SQLEvent.RESULT, resultHandler); insertStmt.execute(); function resultHandler(event:SQLEvent):void { // get the primary key var result:SQLResult = insertStmt.getResult(); var primaryKey:Number = result.lastInsertRowID; // do something with the primary key }
In het volgende voorbeeld ziet u hoe u de primaire sleutel van een ingevoegde rij benadert in synchrone uitvoeringsmodus:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 190 Werken met lokale SQL-databases
insertStmt.text = "INSERT INTO ..."; try { insertStmt.execute(); // get the primary key var result:SQLResult = insertStmt.getResult(); var primaryKey:Number = result.lastInsertRowID; // do something with the primary key } catch (error:SQLError) { // respond to the error }
Let op: mogelijk heeft de rij-identificator de waarde van de kolom die in de tabeldefinitie is opgegeven als de kolom met de primaire sleutel. Hierbij geldt de volgende regel:
• Als voor de tabel een kolom met de primaire sleutel is gedefinieerd waarbij de kolomgegevens van het type INTEGER zijn, bevat de eigenschap lastInsertRowID de waarde die in de desbetreffende rij is ingevoegd (of de waarde die door de runtime is gegenereerd als het een kolom van het type AUTOINCREMENT betreft).
• Als voor de tabel meerdere kolommen met de primaire sleutel zijn gedefinieerd (een samengestelde sleutel) of één kolom met de primaire sleutel waarbij de kolomgegevens niet van het type INTEGER zijn, genereert de database een onzichtbare rij-identificatiewaarde voor de rij. Die gegenereerde waarde is de waarde van de eigenschap lastInsertRowID.
• De waarde is altijd de rij-identificator van de laatst ingevoegde rij. Als de instructie INSERT een trigger activeert waardoor vervolgens een rij wordt ingevoegd, bevat de eigenschap lastInsertRowID de rij-identificator van de rij die het laatst door de trigger is ingevoegd en niet van de rij die door de instructie INSERT is gecreëerd. Dit betekent dat als u een kolom met een expliciet gedefinieerde primaire sleutel wilt waarvan de waarde beschikbaar is na de opdracht INSERT via de eigenschap SQLResult.lastInsertRowID, u de kolom moet definiëren als een kolom van het type INTEGER PRIMARY KEY. Let op: zelfs als uw tabel geen expliciete kolom van het type INTEGER PRIMARY KEY bevat, is het perfect acceptabel om de door de database gegenereerde rij-identificator als primaire sleutel voor uw tabel te gebruiken voor het definiëren van relaties met gerelateerde tabellen. De waarde van de kolom met de rij-identificator is in alle SQL-instructies beschikbaar door het gebruik van een van de speciale kolomnamen: ROWID, _ROWID_ of OID. U kunt in een gerelateerde tabel een kolom met een vreemde sleutel creëren en de rijidentificatiewaarde gebruiken als waarde voor de kolom met de vreemde sleutel, zoals bij een expliciet gedefinieerde kolom van het type INTEGER PRIMARY KEY. Als u dus een willekeurige primaire sleutel gebruikt in plaats van een natuurlijke sleutel en u het niet erg vindt dat de runtime de waarde van de primaire sleutel voor u genereert, is er geen groot verschil tussen het gebruik van een kolom van het type INTEGER PRIMARY KEY of van de door het systeem gegenereerde rij-identificator als primaire sleutel van de tabel bij het definiëren van een relatie met vreemde sleutel tussen twee tabellen. Zie de secties "CREATE TABLE" en "Expressions" (Expressies) in de bijlage "SQL support in local databases" (SQLondersteuning in lokale databases) in ActionScript 3.0 Language and Components Reference voor meer informatie over primaire sleutels en gegenereerde rij-identificatoren.
Gegevens wijzigen of verwijderen Voor het uitvoeren van andere gegevensbewerkingen gebruikt u dezelfde procedure als voor het uitvoeren van de SQLinstructie SELECT of INSERT. Vervang gewoon de SQL-instructie in de eigenschap text van de SQLStatementinstantie:
• Als u bestaande gegevens in een tabel wilt wijzigen, gebruikt u de instructie UPDATE.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 191 Werken met lokale SQL-databases
• Als u een of meer gegevensrijen uit een tabel wilt verwijderen, gebruikt u de instructie DELETE. Zie de bijlage "SQL support in local databases" (SQL-ondersteuning in lokale databases) in ActionScript 3.0 Language and Components Reference voor een beschrijving van deze instructies.
Werken met meerdere databases Gebruik de methode SQLConnection.attach() om een verbinding met een andere database te openen voor een SQLConnection-instantie waarmee al een open database is verbonden. Geef de verbonden database een naam met behulp van de parameter “name” via het oproepen van de methode attach(). Wanneer u vervolgens instructies voor het bewerken van de desbetreffende database schrijft, kunt u die naam in een voorvoegsel gebruiken (met de syntaxis databasenaam.tabelnaam) om eventuele tabelnamen in uw SQL-instructies te definiëren, zodat de runtime weet dat de tabel zich in de opgegeven database bevindt. U kunt werken met één SQL-instructie die verwijst naar tabellen uit meerdere databases die zijn verbonden met dezelfde SQLConnection-instantie. Als een transactie voor de SQLConnection-instantie wordt gecreëerd, geldt de desbetreffende transactie voor alle SQL-instructies die met behulp van de SQLConnection-instantie worden uitgevoerd. Deze regel geldt altijd, ongeacht de database waarop de instructie wordt uitgevoerd. U kunt echter ook meerdere SQLConnection-instanties in een toepassing creëren, waarbij elke instantie is verbonden met een of meer databases. Als u echter meerdere verbindingen met dezelfde database gebruikt, mag u niet vergeten dat databasetransacties niet worden gedeeld over SQLConnection-instanties. Dit betekent dat als u via meerdere SQLConnection-instanties verbinding maakt met hetzelfde databasebestand, u er niet op mag vertrouwen dat de wijzigingen in de gegevens van beide verbindingen op de verwachte manier worden doorgevoerd. Als bijvoorbeeld twee UPDATE- of DELETE-instructies op dezelfde database maar via verschillende SQLConnection-instanties worden uitgevoerd en er een toepassingsfout optreedt na één bewerking, bevinden de databasegegevens zich mogelijk in een onomkeerbare tussenfase, waardoor de integriteit van de database (en dus ook van de toepassing) in gevaar kan komen.
Databasefouten verhelpen Over het algemeen verloopt het verhelpen van databasefouten zoals het verhelpen van andere runtimefouten. U wordt aangeraden code te schrijven die is voorbereid op het optreden van mogelijke fouten en deze kan verhelpen, in plaats van dit door de runtime te laten doen. Databasefouten worden doorgaans in drie categorieën verdeeld: verbindingsfouten, SQL-syntaxisfouten en beperkingsfouten.
Verbindingsfouten De meeste databasefouten zijn verbindingsfouten. Deze kunnen tijdens alle bewerkingen optreden. Er zijn weliswaar strategieën voor het voorkomen van verbindingsfouten maar er is slechts zelden een eenvoudige manier om zonder problemen van een verbindingsfout te herstellen als de database een belangrijk deel is van uw toepassing. De meeste verbindingsfouten worden veroorzaakt door de manier waarop de runtime interageert met het besturingssysteem, het bestandssysteem en het databasebestand. Er treedt bijvoorbeeld een verbindingsfout op als de gebruiker geen toestemming heeft om een databasebestand te creëren op een bepaalde locatie van het bestandssysteem. De volgende strategieën helpen verbindingsfouten te voorkomen: Gebruik gebruikersspecifieke databasebestanden Geef iedere gebruiker zijn of haar eigen databasebestand, in plaats van één databasebestand te gebruiken voor alle gebruikers die de toepassing op één computer gebruiken. Plaats het bestand in een directory die aan de account van de gebruiker is gekoppeld. Dit kan bijvoorbeeld de opslagdirectory van de toepassing, de documentenmap van de gebruiker of het bureaublad van de gebruiker zijn. Houd rekening met verschillende soorten gebruikers Test uw toepassing met verschillende soorten
gebruikersaccounts in verschillende besturingssystemen. Ga er niet van uit dat de gebruiker beheerdersrechten heeft
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 192 Werken met lokale SQL-databases
voor de computer. Ga er ook niet van uit dat de persoon die de toepassing heeft geïnstalleerd, de gebruiker is die de toepassing uitvoert. Houd rekening met verschillende bestandslocaties Als u een gebruiker toestaat de opslaglocatie van een
databasebestand te bepalen of het te openen bestand te selecteren, moet u rekening houden met de mogelijke bestandslocaties die de gebruikers kunnen selecteren. Bovendien kunt u het best de lijst van mogelijke opslaglocaties (of bronlocaties voor het openen) voor databasebestanden beperken. U kunt bijvoorbeeld gebruikers alleen toestaan bestanden te openen die zich binnen de opslaglocatie van hun gebruikersaccount bevinden. Als een verbindingsfout optreedt, is dit doorgaans bij de eerste poging om de database te creëren of te openen. Dit betekent dat de gebruiker geen enkele databasegerelateerde bewerking in de toepassing kan uitvoeren. Voor bepaalde soorten fouten, zoals alleen-lezen of toegangsrechtfouten, is een van de mogelijke hersteltechnieken het kopiëren van het databasebestand naar een andere locatie. De toepassing kan het databasebestand kopiëren naar een locatie waarvoor de gebruiker wel toegangsrechten heeft om bestanden te creëren en te wijzigen, en vervolgens die nieuwe locatie gebruiken.
Syntaxisfouten Een syntaxisfout treedt op als de toepassing een SQL-instructie probeert uit te voeren die niet goed is geformuleerd. Aangezien SQL-instructies voor lokale databases als tekenreeksen zijn gecreëerd, is het niet mogelijk om de SQLsyntaxis tijdens het compileren te controleren. Alle SQL-instructies moeten worden uitgevoerd om hun syntaxis te controleren. Pas de volgende strategieën toe om SQL-syntaxisfouten te voorkomen: Voer een grondige test uit van alle SQL-instructies Indien mogelijk moet u uw SQL-instructies tijdens de
ontwikkeling van uw toepassing apart testen voordat u ze als instructietekst in de toepassingscode codeert. Bovendien wordt u aangeraden een codetestfase in te plannen (zoals het testen per eenheid) om een set van tests te creëren die elke mogelijke optie en codevariatie testen. Gebruik instructieparameters en vermijd het samenvoegen (dynamisch genereren) van SQL Parameters gebruiken,
en dynamisch gegenereerde SQL-instructies vermijden, betekent dat dezelfde SQL-instructietekst wordt gebruikt elke keer dat een instructie wordt uitgevoerd. Hierdoor is het veel eenvoudiger om uw instructies te testen en de mogelijke variaties te beperken. Als u een SQL-instructie dynamisch moet genereren, moet u de dynamische delen van de instructie tot het minimum beperken. Ga ook zorgvuldig te werk bij het valideren van gegevensinvoer om te zorgen dat deze geen syntaxisfouten veroorzaakt. Een toepassing die van een syntaxisfout moet herstellen, heeft complexe logica nodig om een SQL-instructie te controleren en de syntaxis te corrigeren. Door de volgende richtlijnen voor het voorkomen van syntaxisfouten in acht te nemen, kan uw code mogelijke runtimebronnen van SQL-syntaxisfouten (zoals gebruikersinvoer in een instructie) identificeren. Zorg dat de gebruiker over richtlijnen beschikt als een syntaxisfout optreedt. Geef aan wat de gebruiker moet corrigeren om te zorgen dat de instructie correct wordt uitgevoerd.
Beperkingsfouten Beperkingsfouten treden op wanneer de instructie INSERT of UPDATE gegevens aan een kolom probeert toe te voegen. De fout treedt op als de nieuwe gegevens een van de vooraf gedefinieerde beperkingen voor de tabel of kolom schenden. U kunt onder andere de volgende beperkingen instellen: Beperking ‘uniek’ Geeft aan dat geen enkele rij van de tabel een al bestaande waarde mag bevatten binnen een
bepaalde kolom. Of u kunt aangeven dat wanneer meerdere kolommen worden gecombineerd in één beperking, de combinatie van waarden in de desbetreffende kolommen niet mag worden gedupliceerd. Met andere woorden, elke rij moet verschillend zijn op het gebied van de opgegeven unieke kolom(men). Beperking ‘primaire sleutel’ Wat de gegevens betreft die een beperking (niet) toestaat, is een beperking ‘primaire
sleutel’ hetzelfde als een beperking ‘uniek’.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 193 Werken met lokale SQL-databases
Beperking ‘niet leeg’ Geeft aan dat een bepaalde kolom niet de waarde NULL mag bevatten, met andere woorden, dat
alle rijen in de desbetreffende kolom een waarde moeten hebben. Beperking ‘controle’ Biedt u de mogelijkheid om een willekeurige beperking in te stellen voor een of meer tabellen.
Een veel voorkomende beperking van het ‘controle’ is een regel die bepaalt dat de waarde in een kolom zich binnen een bepaald bereik moet bevinden (bijvoorbeeld dat de waarde in een numerieke kolom groter moet zijn dan 0). Een andere veel voorkomende beperking van het type ‘controle’ definieert relaties tussen kolomwaarden (bijvoorbeeld dat de waarde in een kolom moet verschillen van de waarde in een andere kolom op dezelfde rij). Beperking ‘gegevenstype’ De runtime legt het gegevenstype voor de kolomwaarden op en er treedt een fout op als
wordt geprobeerd om een waarde op te slaan die niet het juiste type heeft voor de kolom. In vele situaties worden waarden echter omgezet zodat ze het gegevenstype hebben dat is ingesteld voor de kolom. Zie “Werken met gegevenstypen” op pagina 194 voor meer informatie. De runtime legt geen beperkingen op voor vreemde-sleutelwaarden. Met andere woorden, vreemde-sleutelwaarden hoeven niet overeen te komen met een bestaande primaire-sleutelwaarde. Naast de vooraf gedefinieerde typen beperkingen ondersteunt de SQL-runtime-engine het gebruik van triggers. Een trigger is te vergelijken met een gebeurtenishandler. Het is een vooraf gedefinieerde instructieset die worden uitgevoerd wanneer zich een bepaalde actie voordoet. U kunt bijvoorbeeld een trigger definiëren die worden geactiveerd wanneer gegevens worden ingevoegd in of verwijderd uit een bepaalde tabel. Een voorbeeld van het gebruik van een trigger is het controleren van wijzigingen in gegevens en het weergeven van een foutmelding als niet wordt voldaan aan de opgegeven voorwaarden. Dit betekent dat een trigger hetzelfde doel kan hebben als een beperking, en dat de strategieën voor het voorkomen en herstellen van beperkingsfouten ook gelden voor fouten die door een trigger worden gegenereerd. De fout-id voor fouten die door een trigger worden gegenereerd, verschilt echter van de fout-id voor beperkingsfouten. De set van beperkingen die gelden voor een bepaalde tabel wordt gedefinieerd terwijl u een toepassing ontwikkelt. Door goed na te denken bij het definiëren van beperkingen vergemakkelijkt u het voorkomen en herstellen van beperkingsfouten in uw toepassingen. Beperkingsfouten zijn echter moeilijk systematisch te voorspellen en te voorkomen. Het voorspellen is moeilijk omdat beperkingsfouten pas optreden wanneer toepassingsgegevens worden toegevoegd. Beperkingsfouten treden op wanneer gegevens aan een database worden toegevoegd nadat deze is gecreëerd. Deze fouten zijn vaak het resultaat van de relatie tussen nieuwe gegevens en gegevens die al in de database aanwezig zijn. De volgende strategieën kunnen u helpen veel voorkomende beperkingsfouten te voorkomen: Plan de databasestructuur en de beperkingen zorgvuldig Het doel van beperkingen is toepassingsregels op te leggen en te helpen de integriteit van de databasegegevens te beschermen. Denk tijdens het plannen van uw toepassing na over de structuur van uw database zodat deze uw toepassing kan ondersteunen. Hierbij identificeert u regels voor de gegevens, zoals of bepaalde waarden vereist zijn, een waarde een standaardinstelling heeft, dubbele waarden zijn toegestaan enzovoort. Deze regels helpen u bij het definiëren van databasebeperkingen. Geef expliciet kolomnamen op U kunt de instructie INSERT gebruiken zonder expliciet de kolommen op te geven
waarin waarden zullen worden ingevoegd. Dit is echter een onnodig risico. Door expliciet de kolommen te benoemen waarin waarden zullen worden ingevoegd, kunt u automatisch gegenereerde waarden, kolommen met standaardwaarden en kolommen met de waarde NULL gebruiken. Bovendien zorgt u hierdoor dat in alle kolommen van het type NOT NULL een expliciete waarde wordt ingevoegd. Gebruik standaardwaarden Wanneer u de beperking NOT NULL voor een kolom opgeeft, geeft u wanneer mogelijk een
standaardwaarde in de kolomdefinitie op. Ook toepassingscode kan in standaardwaarden voorzien. Uw code kan bijvoorbeeld controleren of een tekenreeksvariabele de waarde null heeft en er een waarde aan toewijzen voordat de variabele wordt gebruikt om de waarde van een instructieparameter in te stellen. Valideer gebruikersinvoer Controleer gebruikersinvoer voordat de gegevens daadwerkelijk in de database worden ingevoegd om te zorgen dat de invoer aan de beperkingen voldoet, met name in het geval van de beperkingen NOT
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 194 Werken met lokale SQL-databases
NULL en CHECK. De beperking UNIQUE is uiteraard moeilijker te controleren omdat een SELECT-query moet worden uitgevoerd om te bepalen of de gegevens uniek zijn.
Gebruik triggers U kunt een trigger schrijven die ingevoegde gegevens verifieert (en mogelijk vervangt) of andere
acties uitvoert om ongeldige gegevens te corrigeren. Deze verificatie- en correctieacties kunnen beperkingsfouten voorkomen. In vele opzichten zijn beperkingsfouten moeilijker te voorkomen dan andere fouttypen. Gelukkig zijn er verschillende strategieën om van beperkingsfouten te herstellen zonder dat de toepassing instabiel of onbruikbaar wordt: Gebruik conflictalgoritmen Als u een beperking voor een kolom definieert en als u de instructie INSERT of UPDATE
creëert, kunt u desgewenst een conflictalgoritme opgeven. Een conflictalgoritme definieert de actie die de database uitvoert als een beperkingsfout optreedt. De database-engine kan verschillende mogelijke acties uitvoeren. De database-engine kan één instructie of een complete transactie beëindigen. De engine kan de fout negeren. Of zelfs oude gegevens verwijderen en deze vervangen door de gegevens die de code probeert op te slaan. Zie de sectie "ON CONFLICT (conflict algorithms)" (Conflictalgoritmen) in de bijlage "SQL support in local databases" (SQL-ondersteuning in lokale databases) in ActionScript 3.0 Language and Components Reference voor meer informatie. Geef feedback met een oplossing De set van beperkingen die een bepaalde SQL-opdracht kunnen beïnvloeden, kan
van tevoren worden geïdentificeerd. Dit betekent dat u beperkingsfouten die door een instructie kunnen worden veroorzaakt, kunt voorspellen. Op die kennis kunt u toepassingslogica baseren die op een beperkingsfout reageert. Een toepassing bevat bijvoorbeeld een formulier voor het invoeren van nieuwe producten. Als de kolom met de productnaam in de database is gedefinieerd met een beperking van het type UNIQUE, kan het invoegen van een nieuwe productrij in de database een beperkingsfout veroorzaken. Daarom wordt de toepassing zo ontwikkeld dat deze van tevoren rekening houdt met een beperkingsfout. Als de fout optreedt, waarschuwt de toepassing de gebruiker dat de opgegeven productnaam al bestaat en dat een andere naam moet worden gekozen. Een andere mogelijke reactie is dat informatie over het andere product met dezelfde naam wordt weergegeven.
Werken met gegevenstypen Bij het creëren van een tabel in een database definieert de SQL-instructie voor het creëren van de tabel het gegevenstype voor elke kolom van de tabel. Het toewijzen van typen is weliswaar niet vereist maar u wordt toch aangeraden het kolomtype expliciet op te geven in uw SQL-instructies CREATE TABLE. Normaliter wordt elk object dat u in een database opslaat met de instructie INSERT, weergegeven als een instantie van hetzelfde gegevenstype wanneer u de instructie SELECT uitvoert. De opgehaalde waarde kan echter een ander gegevenstype hebben, afhankelijk van de toewijzing van het type aan de databasekolom waarin de waarde is opgeslagen. Als het gegevenstype van een waarde die in een kolom wordt opgeslagen, niet overeenkomt met het type dat aan de kolom is toegewezen, probeert de database de waarde om te zetten in het type dat aan de kolom is toegewezen. Als bijvoorbeeld het gegevenstype NUMERIC aan een databasekolom is toegewezen, probeert de database ingevoegde gegevens om te zetten in een numerieke opslagklasse (INTEGER of REAL) voordat de gegevens worden opgeslagen. De database genereert een foutmelding als de gegevens niet kunnen worden omgezet. Als de tekenreeks “12345” wordt ingevoegd in een kolom van het type NUMERIC, zet de database op basis van deze regel de tekenreeks automatisch om in het geheel getal 12345 voordat de waarde in de database wordt opgeslagen. Wanneer de waarde wordt opgehaald met de instructie SELECT, wordt deze weergegeven als een instantie van een numeriek gegevenstype (bijvoorbeeld Number) in plaats van een tekenreeksinstantie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 195 Werken met lokale SQL-databases
De beste manier om ongewenste omzetting van het gegevenstype te voorkomen, is het in acht nemen van twee regels. Ten eerste: definieer elke kolom met het type dat overeenkomt met het type gegevens dat u wilt opslaan. Ten tweede: voeg alleen waarden in waarvan het gegevenstype overeenkomt met het toegewezen type. Het in acht nemen van deze regels biedt twee voordelen. Wanneer u de gegevens invoegt, worden deze niet onbedoeld omgezet (waardoor mogelijk de bedoelde betekenis verloren zou gaan). Bovendien worden de gegevens bij het ophalen weergegeven met het oorspronkelijke gegevenstype. Zie de sectie "Data type support" (Ondersteuning van gegevenstypen) in de bijlage "SQL support in local databases" (SQL-ondersteuning in lokale databases) in ActionScript 3.0 Language and Components Reference voor meer informatie over de beschikbare gegevenstypen voor kolommen en het gebruik van gegevenstypen in SQL-instructies.
Synchrone en asynchrone databasebewerkingen gebruiken In de vorige secties zijn veel voorkomende databasebewerkingen besproken, zoals het ophalen, invoegen, updaten en verwijderen van gegevens, evenals het creëren van een databasebestand en tabellen en andere objecten binnen een database. In de voorbeelden hebt u gezien hoe u deze bewerkingen synchroon en asynchroon kunt laten uitvoeren. Ter herinnering: in asynchrone uitvoeringsmodus geeft u de database-engine de opdracht om een bewerking uit te voeren. De database-engine werkt vervolgens op de achtergrond terwijl de toepassing verderwerkt. Nadat de bewerking is voltooid, verzendt de database-engine een gebeurtenis om u dit te melden. Het belangrijkste voordeel van asynchrone uitvoering is dat de runtime de databasebewerkingen op de achtergrond uitvoert terwijl de hoofdtoepassingscode verder wordt uitgevoerd. Dit is vooral belangrijk wanneer het uitvoeren van de bewerking lang duurt. In de synchrone uitvoeringsmodus echter worden de bewerkingen niet op de achtergrond uitgevoerd. U geeft de database-engine de opdracht een bewerking uit te voeren. De code wordt op dat punt onderbroken terwijl de databaseengine zijn werk doet. Nadat de bewerking is voltooid, gaat de uitvoering verder vanaf de volgende regel van uw code. Het is niet mogelijk om via één enkele databaseverbinding bepaalde bewerkingen of instructies synchroon en andere asynchroon uit te voeren. U bepaalt welke uitvoeringsmodus (synchroon of asynchroon) voor een SQLConnection wordt gebruikt wanneer u verbinding maakt met de database. Als u SQLConnection.open() oproept, werkt de verbinding in synchrone uitvoeringsmodus. Roept u SQLConnection.openAsync() op, dan werkt de verbinding in asynchrone uitvoeringsmodus. Nadat een SQLConnection-instantie met een database is verbonden met behulp van open() of openAsync(), wordt deze in synchrone of asynchrone uitvoeringsmodus vergrendeld.
Synchrone databasebewerkingen gebruiken Op het gebied van de daadwerkelijke code die u gebruikt om bewerkingen uit te voeren en erop te reageren, is er niet veel verschil tussen de synchrone en asynchrone uitvoeringsmodus. De belangrijkste verschillen tussen beide modi liggen in twee gebieden. Het eerste verschil is de uitvoering van een bewerking die afhankelijk is van een andere bewerking (bijvoorbeeld rijen die het resultaat zijn van SELECT of de primaire sleutel van de rij die is toegevoegd door de instructie INSERT). Het tweede verschil is de verwerking van fouten.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 196 Werken met lokale SQL-databases
Code schrijven voor synchrone bewerkingen Het belangrijkste verschil tussen synchrone en asynchrone uitvoering is dat u in de synchrone modus de code als één reeks van stappen schrijft. In de asynchrone modus registreert u gebeurtenislisteners en verdeelt u vaak bewerkingen over verschillende listenermethoden. Als een database in de synchrone uitvoeringsmodus is verbonden, kunt u een reeks van opeenvolgende databasebewerkingen binnen één codeblok laten uitvoeren. Deze techniek wordt in het volgende voorbeeld getoond: var conn:SQLConnection = new SQLConnection(); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); // open the database conn.open(dbFile, OpenMode.UPDATE); // start a transaction conn.begin(); // add the customer record to the database var insertCustomer:SQLStatement = new SQLStatement(); insertCustomer.sqlConnection = conn; insertCustomer.text = "INSERT INTO customers (firstName, lastName) " + "VALUES ('Bob', 'Jones')"; insertCustomer.execute(); var customerId:Number = insertCustomer.getResult().lastInsertRowID; // add a related phone number record for the customer var insertPhoneNumber:SQLStatement = new SQLStatement(); insertPhoneNumber.sqlConnection = conn; insertPhoneNumber.text = "INSERT INTO customerPhoneNumbers (customerId, number) " + "VALUES (:customerId, '800-555-1234')"; insertPhoneNumber.parameters[":customerId"] = customerId; insertPhoneNumber.execute(); // commit the transaction conn.commit();
Zoals u ziet, roept u dezelfde methoden op om databasebewerkingen uit te voeren, ongeacht de modus die u gebruikt (synchroon of asynchroon). De belangrijkste verschillen tussen beide modi zijn de uitvoering van een bewerking die afhankelijk is van een andere bewerking, en de verwerking van fouten.
Bewerkingen uitvoeren die afhankelijk zijn van een andere bewerking In de synchrone uitvoeringsmodus hoeft u geen code te schrijven die op een gebeurtenis wacht om te bepalen wanneer een bewerking is voltooid. U mag ervan uitgaan dat als een bewerking op een bepaalde regel van de code is voltooid, de uitvoering verdergaat met de volgende regel. Dit betekent dat als u een bewerking wilt uitvoeren die afhankelijk is van de voltooiing van een andere bewerking, u gewoon de afhankelijke code onmiddellijk na de bewerking schrijft waarvan deze afhankelijk is. Als u bijvoorbeeld wilt dat een toepassing een transactie start, de instructie INSERT uitvoert, de primaire sleutel van de ingevoegde rij ophaalt, die primaire sleutel op een andere rij van een andere tabel invoegt en ten slotte de transactie bevestigt, kunt u de complete code als een reeks van instructies schrijven. In het volgende voorbeeld ziet u het gebruik van deze bewerkingen:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 197 Werken met lokale SQL-databases
var conn:SQLConnection = new SQLConnection(); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); // open the database conn.open(dbFile, SQLMode.UPDATE); // start a transaction conn.begin(); // add the customer record to the database var insertCustomer:SQLStatement = new SQLStatement(); insertCustomer.sqlConnection = conn; insertCustomer.text = "INSERT INTO customers (firstName, lastName) " + "VALUES ('Bob', 'Jones')"; insertCustomer.execute(); var customerId:Number = insertCustomer.getResult().lastInsertRowID; // add a related phone number record for the customer var insertPhoneNumber:SQLStatement = new SQLStatement(); insertPhoneNumber.sqlConnection = conn; insertPhoneNumber.text = "INSERT INTO customerPhoneNumbers (customerId, number) " + "VALUES (:customerId, '800-555-1234')"; insertPhoneNumber.parameters[":customerId"] = customerId; insertPhoneNumber.execute(); // commit the transaction conn.commit();
Fouten verwerken in synchrone uitvoeringsmodus In de synchrone uitvoeringsmodus wacht u niet op een foutgebeurtenis om te bepalen of een bewerking is mislukt. In plaats daarvan plaatst u code die fouten kan veroorzaken in een set codeblokken van het type try..catch..finally. Plaats de code die de fout kan genereren in het blok try. Schrijf de acties die als reactie op de verschillende fouttypen moeten worden uitgevoerd in aparte blokken van het type catch. Plaats eventuele code die u altijd wilt uitvoeren ongeacht het resultaat (bijvoorbeeld het sluiten van een databaseverbinding die u niet meer nodig hebt) in een blok van het type finally. In het volgende voorbeeld ziet u hoe u blokken van het type try..catch..finally voor foutverwerking gebruikt. Dit voorbeeld is gebaseerd op het vorige voorbeeld maar voegt code voor foutverwerking toe:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 198 Werken met lokale SQL-databases
var conn:SQLConnection = new SQLConnection(); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); // open the database conn.open(dbFile, SQLMode.UPDATE); // start a transaction conn.begin(); try { // add the customer record to the database var insertCustomer:SQLStatement = new SQLStatement(); insertCustomer.sqlConnection = conn; insertCustomer.text = "INSERT INTO customers (firstName, lastName)" + "VALUES ('Bob', 'Jones')"; insertCustomer.execute(); var customerId:Number = insertCustomer.getResult().lastInsertRowID; // add a related phone number record for the customer var insertPhoneNumber:SQLStatement = new SQLStatement(); insertPhoneNumber.sqlConnection = conn; insertPhoneNumber.text = "INSERT INTO customerPhoneNumbers (customerId, number)" + "VALUES (:customerId, '800-555-1234')"; insertPhoneNumber.parameters[":customerId"] = customerId; insertPhoneNumber.execute(); // if we've gotten to this point without errors, commit the transaction conn.commit(); } catch (error:SQLError) { // rollback the transaction conn.rollback(); }
De asynchrone uitvoeringsmodus Veel ontwikkelaars gebruiken de asynchrone uitvoeringsmodus liever niet omdat ze denken dat de uitvoering van een SQLStatement-instantie niet kan worden gestart als al een andere SQLStatement wordt uitgevoerd via dezelfde databaseverbinding. Dit is niet juist. U kunt de eigenschap text van een SQLStatement-instantie niet wijzigen terwijl de instructie wordt uitgevoerd. Als u echter een aparte SQLStatement-instantie gebruikt voor elke verschillende SQLinstructie die u wilt uitvoeren, kunt u de methode execute() van een SQLStatement oproepen terwijl een andere SQLStatement-instantie wordt uitgevoerd, zonder dat een fout optreedt. Wanneer u databasebewerkingen uitvoert in de asynchrone uitvoeringsmodus, heeft elke databaseverbinding (elke SQLConnection-instantie) een eigen interne wachtrij of lijst van bewerkingen die de verbinding moet uitvoeren. De runtime voert de bewerkingen één voor één uit in de volgorde waarin ze aan de wachtrij zijn toegevoegd. Wanneer u een SQLStatement-instantie creëert en de overeenkomstige methode execute() oproept, wordt de desbetreffende bewerking voor het uitvoeren van de instructie toegevoegd aan de wachtrij van de verbinding. Als er momenteel geen bewerking wordt uitgevoerd voor de desbetreffende SQLConnection-instantie, wordt de uitvoering van de instructie op de achtergrond gestart. U kunt bijvoorbeeld binnen hetzelfde codeblok een andere SQLStatement-instantie creëren
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 199 Werken met lokale SQL-databases
en ook de methode execute() van de desbetreffende methode oproepen. Die tweede bewerking voor het uitvoeren van de instructie wordt na de eerste instructie in de wachtrij geplaatst. Zodra de eerste instructie is voltooid, voert de runtime de volgende bewerking uit de wachtrij uit. De verwerking van daarop volgende bewerkingen uit de wachtrij vindt op de achtergrond plaats, zelfs wanneer de gebeurtenis result voor de eerste bewerking wordt verzonden in de hoofdtoepassingscode. In de volgende code wordt deze techniek geïllustreerd: // Using asynchronous execution mode var stmt1:SQLStatement = new SQLStatement(); stmt1.sqlConnection = conn; // ... Set statement text and parameters, and register event listeners ... stmt1.execute(); // At this point stmt1's execute() operation is added to conn's execution queue. var stmt2:SQLStatement = new SQLStatement(); stmt2.sqlConnection = conn; // ... Set statement text and parameters, and register event listeners ... stmt2.execute(); // At this point stmt2's execute() operation is added to conn's execution queue. // When stmt1 finishes executing, stmt2 will immediately begin executing // in the background.
Er is een belangrijk neveneffect: de database voert automatisch daarop volgende instructies uit de wachtrij uit. Als een instructie afhankelijk is van het resultaat van een andere bewerking, kunt u de instructie niet toevoegen aan de wachtrij (met andere woorden, u kunt de methode execute() van de instructie niet oproepen) voordat de eerste bewerking is voltooid. De reden hiervoor is dat nadat u de methode execute() van de tweede instructie hebt opgeroepen, u de eigenschap text of parameters van de instructie niet meer kunt wijzigen. In dat geval kunt u de volgende bewerking pas starten nadat de gebeurtenis is verzonden die aangeeft dat de eerste bewerking is voltooid. Als u bijvoorbeeld een instructie wilt uitvoeren in de context van een transactie, hangt de uitvoering van de instructie af van het openen van de transactie. Nadat u de methode SQLConnection.begin() hebt opgeroepen om de transactie te openen, moet u wachten tot de SQLConnection-instantie de gebeurtenis begin verzendt. Pas daarna kunt u de methode execute() van de SQLStatement-instantie oproepen. In dit voorbeeld is de eenvoudigste manier om de toepassing zo te structureren dat de bewerkingen correct worden uitgevoerd, het creëren van een methode die als listener voor de gebeurtenis begin is geregistreerd. De code die de methode SQLStatement.execute() oproept, wordt binnen die listenermethode geplaatst.
Codering gebruiken met SQL-databases Alle Adobe AIR-toepassingen delen dezelfde lokale database-engine. Elke AIR-toepassing kan daarom verbinding maken met en gegevens lezen van en schrijven naar een niet-gecodeerd databasebestand. Vanaf Adobe AIR 1.5 is AIR ook voorzien van de mogelijkheid om gecodeerde databasebestanden te maken en hiermee verbinding te maken. Wanneer u een gecodeerde database gebruikt, moet een toepassing de correcte coderingssleutel opgeven om verbinding te kunnen maken met deze database. Als een onjuiste of geen sleutel wordt opgegeven, kan de toepassing geen verbinding maken met de database. De toepassing kan dan ook geen gegevens van de database lezen of gegevens naar de database schrijven of wijzigen. Als u een gecodeerde database wilt gebruiken, moet u de desbetreffende gecodeerde database maken. Bij een bestaande gecodeerde database kunt u een verbinding tot stand brengen. U kunt ook de coderingssleutel van een gecodeerde database wijzigen. De methoden voor het werken met een gecodeerde database zijn bijna hetzelfde als die voor het werken met een niet-gecodeerde. Het enige verschil is dat u de gecodeerde database moet maken en er verbinding mee tot stand moet brengen. Vooral de uitvoering van SQL-instructies is hetzelfde, of de database nu wel of niet gecodeerd is.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 200 Werken met lokale SQL-databases
Gebruik van gecodeerde databases Codering is nuttig als u de toegang tot de informatie in een database wilt beperken. U kunt de databasecoderingsfunctie van Adobe AIR gebruiken voor verschillende doeleinden. Hieronder volgen enige voorbeelden van situaties waarbij u een gecodeerde database kunt gebruiken:
• Een alleen-lezen cache van privé-toepassingsgegevens die u hebt gedownload van een server • Een lokale opslag van privé-toepassingsgegevens die zijn gesynchroniseerd met een server (gegevens worden verzonden naar en geladen van de server)
• Gecodeerde bestanden gebruikt als bestandsindeling voor documenten die zijn gemaakt door en bewerkt door de toepassing. Dit kunnen privé-bestanden van een bepaalde gebruiker zijn, of ze kunnen worden gedeeld door alle gebruikers van de toepassing.
• Elk ander gebruik van een lokale gegevensopslag, zoals beschreven in “Toepassingen voor lokale SQL-databases” op pagina 170, waarbij de gegevens niet toegankelijk mogen zijn voor andere gebruikers die toegang hebben tot de computer of de databasebestanden. Inzicht in de reden waarom u een gecodeerde database wilt gebruiken kan u helpen met de besluitvorming betreffende de architectuur van de toepassing. Dit is vooral van belang voor de manier waarop uw toepassing de coderingssleutel voor de database maakt, verkrijgt of opslaat. Raadpleeg “Overwegingen bij het gebruik van codering voor een database” op pagina 204 voor meer informatie. Behalve een gecodeerde database kunt u ook een gecodeerde lokale opslag gebruiken om gevoelige gegevens privé te houden. Bij de gecodeerde lokale opslag slaat u één enkele ByteArray-waarde op met behulp van een tekenreekssleutel. Alleen de AIR-toepassing die de waarde heeft opgeslagen, kan deze benaderen, en alleen op de computer waarop deze is opgeslagen. Met de gecodeerde lokale opslag is het niet nodig om uw eigen coderingssleutel te maken. Vanwege deze redenen is de gecodeerde lokale opslag het meest geschikt voor het opslaan van één enkele waarde of een set waarden die gemakkelijk kunnen worden gecodeerd in een ByteArray. Een gecodeerde database is het meest geschikt voor grotere gegevenssets waarbij gestructureerde gegevensopslag en het uitvoeren van query's gewenst zijn. Raadpleeg “Gecodeerde gegevens opslaan” op pagina 220 voor meer informatie over het gebruik van de gecodeerde lokale opslag.
Een gecodeerde database maken Om een gecodeerde database te gebruiken, moet het databasebestand zijn gecodeerd wanneer het wordt gemaakt. Een niet-gecodeerde database kan later niet alsnog worden gecodeerd. Ook kan de codering van een gecodeerde database later niet worden opgeheven. U kunt desgewenst de coderingssleutel van een gecodeerde database wijzigen. Zie “De coderingssleutel van een database wijzigen” op pagina 203 voor meer informatie. Als u een bestaande database hebt die niet gecodeerd is en u gebruik wilt maken van databasecodering, kunt u een nieuwe gecodeerde database maken en de bestaande tabelstructuur en gegevens kopiëren naar die nieuwe database. Het maken van een gecodeerde database gaat op bijna dezelfde manier als het maken van een niet-gecodeerde database; dit wordt beschreven in “Database creëren” op pagina 174. Eerst maakt u een SQLConnection-instantie die de verbinding met de database vertegenwoordigt. U maakt de database door de methode open() of de methode openAsync() van het object SQLConnection aan te roepen. Geef hierbij voor de databaselocatie een bestand op dat nog niet bestaat. Wanneer u een gecodeerde database maakt, is het enige verschil dat u een waarde opgeeft voor de parameter encryptionKey (de vijfde parameter van de methode open() en de zesde parameter van de methode openAsync()). Een geldige waarde voor de parameter encryptionKey is een object ByteArray dat precies 16 bytes bevat. In het volgende voorbeeld wordt gedemonstreerd hoe u een gecodeerde database maakt die wordt geopend in de asynchrone uitvoeringsmodus. Voor het gemak is in dit voorbeeld de coderingssleutel hard-gecodeerd in de toepassingscode. Dit is echter sterk af te raden omdat het niet veilig is.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 201 Werken met lokale SQL-databases
var conn:SQLConnection = new SQLConnection(); conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, errorHandler); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); var encryptionKey:ByteArray = new ByteArray(); encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey); function openHandler(event:SQLEvent):void { trace("the database was created successfully"); } function errorHandler(event:SQLErrorEvent):void { trace("Error message:", event.error.message); trace("Details:", event.error.details); }
In het volgende voorbeeld wordt gedemonstreerd hoe u een gecodeerde database maakt die wordt geopend in de synchrone uitvoeringsmodus. Voor het gemak is in dit voorbeeld de coderingssleutel hard-gecodeerd in de toepassingscode. Dit is echter sterk af te raden omdat het niet veilig is. import flash.data.SQLConnection; import flash.data.SQLMode; import flash.filesystem.File; var conn:SQLConnection = new SQLConnection(); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); var encryptionKey:ByteArray = new ByteArray(); encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! try { conn.open(dbFile, SQLMode.CREATE, false, 1024, encryptionKey); trace("the database was created successfully"); } catch (error:SQLError) { trace("Error message:", error.message); trace("Details:", error.details); }
Een voorbeeld van een aanbevolen manier om een coderingssleutel te genereren vindt u in “Voorbeeld: Een coderingssleutel genereren en gebruiken” op pagina 205.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 202 Werken met lokale SQL-databases
Verbinding maken met een gecodeerde database De procedure voor het tot stand brengen van een verbinding met een gecodeerde database is vergelijkbaar met die voor het tot stand brengen van een verbinding met een niet-gecodeerde database. Die procedure wordt uitgebreid beschreven in “Verbinden met een database” op pagina 177. U gebruikt de methode open() om een verbinding in de synchrone uitvoeringsmodus te openen, of de methode openAsync() om een verbinding in de synchrone uitvoeringsmodus te openen. Het enige verschil is dat u voor het openen van een gecodeerde database de correcte waarde opgeeft voor de parameter encryptionKey (de vijfde parameter van de methode open() en de zesde parameter van de methode openAsync()). Als de opgegeven coderingssleutel niet correct is, treedt er een fout op. Bij de methode open() wordt een SQLErroruitzondering geproduceerd. Bij de methode openAsync() verzendt het object SQLConnection een gebeurtenis SQLErrorEvent waarvan de eigenschap error een object SQLError bevat. In beide gevallen heeft van het object SQLError dat door de uitzondering wordt gegenereerd, de eigenschap errorID de waarde 3138. Die fout-ID correspondeert met het foutbericht dat het geopende bestand geen databasebestand is. In het volgende voorbeeld wordt gedemonstreerd hoe u een gecodeerde database opent in de asynchrone uitvoeringsmodus. Voor het gemak is in dit voorbeeld de coderingssleutel hard-gecodeerd in de toepassingscode. Dit is echter sterk af te raden omdat het niet veilig is. import import import import import
var conn:SQLConnection = new SQLConnection(); conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, errorHandler); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); var encryptionKey:ByteArray = new ByteArray(); encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! conn.openAsync(dbFile, SQLMode.UPDATE, null, false, 1024, encryptionKey); function openHandler(event:SQLEvent):void { trace("the database opened successfully"); } function errorHandler(event:SQLErrorEvent):void { if (event.error.errorID == 3138) { trace("Incorrect encryption key"); } else { trace("Error message:", event.error.message); trace("Details:", event.error.details); } }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 203 Werken met lokale SQL-databases
In het volgende voorbeeld wordt gedemonstreerd hoe u een gecodeerde database opent in de synchrone uitvoeringsmodus. Voor het gemak is in dit voorbeeld de coderingssleutel hard-gecodeerd in de toepassingscode. Dit is echter sterk af te raden omdat het niet veilig is. import flash.data.SQLConnection; import flash.data.SQLMode; import flash.filesystem.File; var conn:SQLConnection = new SQLConnection(); var dbFile:File = File.applicationStorageDirectory.resolvePath("DBSample.db"); var encryptionKey:ByteArray = new ByteArray(); encryptionKey.writeUTFBytes("Some16ByteString"); // This technique is not secure! try { conn.open(dbFile, SQLMode.UPDATE, false, 1024, encryptionKey); trace("the database was created successfully"); } catch (error:SQLError) { if (error.errorID == 3138) { trace("Incorrect encryption key"); } else { trace("Error message:", error.message); trace("Details:", error.details); } }
Een voorbeeld van een aanbevolen manier om een coderingssleutel te genereren vindt u in “Voorbeeld: Een coderingssleutel genereren en gebruiken” op pagina 205.
De coderingssleutel van een database wijzigen Wanneer een database gecodeerd is, kunt u de coderingssleutel ervan later wijzigen. Als u de coderingssleutel van een database wilt wijzigen, opent u eerst een verbinding met de database door een SQLConnection-instantie te maken en de methode open() of openAsync() ervan aan te roepen. Als de database verbonden is, roept u de methode reencrypt() aan en geeft u de nieuwe coderingssleutel daarbij door als argument. Zoals bij de meeste bewerkingen op databases, varieert het gedrag van de methode reencrypt(); dit is ervan afhankelijk of de databaseverbinding gebruikmaakt van een synchrone dan wel een asynchrone uitvoeringsmodus. Als u de methode open() gebruikt om verbinding te maken met de database, worden de reencrypt()-bewerkingen synchroon uitgevoerd. Nadat de bewerking is voltooid, gaat de uitvoering verder vanaf de volgende regel code: var newKey:ByteArray = new ByteArray(); // ... generate the new key and store it in newKey conn.reencrypt(newKey);
Als de databaseverbinding echter wordt geopend met de methode openAsync(), is de werking van reencrypt() asynchroon. De verandering van de coderingssleutel begint met het aanroepen van reencrypt(). Wanneer deze bewerking is voltooid, verzendt het object SQLConnection een gebeurtenis reencrypt. U gebruikt een gebeurtenislistener om te bepalen wanneer het proces reencrypt voltooid is:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 204 Werken met lokale SQL-databases
var newKey:ByteArray = new ByteArray(); // ... generate the new key and store it in newKey conn.addEventListener(SQLEvent.REENCRYPT, reencryptHandler); conn.reencrypt(newKey); function reencryptHandler(event:SQLEvent):void { // save the fact that the key changed }
De bewerking reencrypt() wordt uitgevoerd in zijn eigen transactie. Als de bewerking wordt onderbroken of mislukt (bijvoorbeeld wanneer de toepassing wordt gesloten voordat de bewerking is voltooid), wordt de transactie teruggedraaid. In dat geval is de oorspronkelijke coderingssleutel nog steeds de sleutel voor de database. De methode reencrypt() kan niet worden gebruikt om de codering van een database te verwijderen. Als de waarde null of een coderingssleutel die niet bestaat uit een 16-byte ByteArray, wordt doorgegeven aan de methode reencrypt(), treedt er een fout op.
Overwegingen bij het gebruik van codering voor een database In de sectie “Gebruik van gecodeerde databases” op pagina 200 wordt een aantal omstandigheden beschreven waaronder u gebruik kunt maken van gecodeerde databases. De gebruikscenario's van verschillende toepassingen (inclusief deze en andere scenario's) hebben uiteraard verschillende privacyvereisten. De mate waarin de gegevens in een database privé blijven, wordt voor een groot deel bepaald door de manier waarop u gebruikmaakt van codering in uw toepassing. Als u bijvoorbeeld een gecodeerde database gebruikt om persoonlijke gegevens privé te houden, zodat zelfs andere gebruikers van dezelfde computer er niet bij kunnen, heeft de database van iedere gebruiker een eigen coderingssleutel nodig. Voor optimale beveiliging kan uw toepassing de sleutel genereren aan de hand van een wachtwoord dat door de gebruiker wordt ingevoerd. Als de coderingssleutel wordt gebaseerd op een wachtwoord, kan zelfs een andere gebruiker die in staat is zich voor te doen als gebruiker van deze account op de computer, geen toegang krijgen tot deze gegevens. Aan de andere kant van het privacyspectrum vindt u databasebestanden die kunnen worden gelezen door iedere gebruiker van uw toepassing, maar niet door andere toepassingen. In dat geval moet ieder geïnstalleerd exemplaar van de toepassing toegang hebben tot een gedeelde coderingssleutel. U kunt het ontwerp van uw toepassing en vooral de methode die wordt gebruikt om de coderingssleutel te genereren, aanpassen aan het privacyniveau dat u wilt gebruiken voor uw toepassingsgegevens. Hieronder volgt een lijst met suggesties voor verschillende privacyniveaus voor gegevens:
• Als u een database toegankelijk wil maken voor iedere gebruiker die toegang heeft tot de toepassing op iedere computer, gebruikt u één enkele sleutel die beschikbaar is voor alle exemplaren van de toepassing. De eerste keer dat een toepassing wordt uitgevoerd, kan deze de gedeelde coderingssleutel bijvoorbeeld downloaden vanaf een server met gebruikmaking van een veilig protocol zoals SSL. De toepassing kan de sleutel dan opslaan in de gecodeerde lokale opslag voor toekomstig gebruik. Als alternatief kunt u de gegevens per gebruiker coderen op de computer en de gegevens synchroniseren met een externe gegevensopslag zoals een server, zodat de gegevens overal toegankelijk zijn.
• Als u een database voor slechts één gebruiker toegankelijk wilt maken op alle computers, genereert u de coderingssleutel aan de hand van een geheim dat alleen de gebruiker kent (bijvoorbeeld een wachtwoord). U moet dan absoluut niet gebruikmaken van een waarde die is gekoppeld aan een bepaalde computer (bijvoorbeeld een waarde die is opgeslagen in de gecodeerde lokale opslag) om de sleutel te genereren. Als alternatief kunt u de gegevens per gebruiker coderen op de computer en de gegevens synchroniseren met een externe gegevensopslag zoals een server, zodat de gegevens overdraagbaar zijn.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 205 Werken met lokale SQL-databases
• Als een database toegankelijk moet zijn voor één gebruiker op één computer, genereert u de sleutel aan de hand van een wachtwoord en een gegenereerde salt. Een voorbeeld van deze methode vindt u in “Voorbeeld: Een coderingssleutel genereren en gebruiken” op pagina 205. Hieronder volgt een aantal extra beveiligingsoverwegingen waarmee u rekening moet houden als u een toepassing ontwerpt die gebruikmaakt van een gecodeerde database:
• Een systeem is zo veilig als de zwakste schakel. Als u gebruikmaakt van een door de gebruiker ingevoerd wachtwoord om een coderingssleutel te genereren, is het aan te raden beperkingen met betrekking tot de lengte en de complexiteit van het wachtwoord op te geven. Een kort wachtwoord met eenvoudige kenmerken is gemakkelijk te raden.
• De broncode van een AIR-toepassing wordt op de computer van een gebruiker opgeslagen als onbewerkte tekst (voor HTML-inhoud) of met een gemakkelijk te decompileren binaire indeling (voor SWF-inhoud). Omdat de broncode toegankelijk is, moet u rekening houden met de volgende twee punten:
• Maak nooit gebruik van een hard-gecodeerde sleutel in de broncode • Ga er altijd van uit dat de methode die wordt gebruikt om een coderingssleutel te genereren (bijvoorbeeld een willekeurige tekengenerator of een bepaald hash-algoritme) gemakkelijk kan worden bepaald door een aanvaller
• AIR-databasecodering maakt gebruik van de Advanced Encryption Standard (AES) met Counter with CBC-MAC (CCM)-modus. Deze codering is alleen veilig als een door de gebruiker ingevoerde sleutel wordt gecombineerd met een salt-waarde. Een voorbeeld van deze methode vindt u in “Voorbeeld: Een coderingssleutel genereren en gebruiken” op pagina 205.
• Wanneer u ervoor kiest om een database te coderen, worden alle schijfbestanden gecodeerd die door de databaseengine samen met die database worden gebruikt. De database-engine slaat echter bepaalde gegevens tijdelijk op in een geheugencache om de lees- en schrijfprestaties bij transacties te verbeteren. Gegevens die aanwezig zijn in het geheugen, zijn niet gecodeerd. Als een aanvaller toegang kan krijgen tot het geheugen dat wordt gebruikt door een AIR-toepassing, bijvoorbeeld door middel van een debugger, zijn de gegevens in een database die nu open en nietgecodeerd is, beschikbaar.
Voorbeeld: Een coderingssleutel genereren en gebruiken In deze voorbeeldtoepassing wordt een methode gedemonstreerd om een coderingssleutel te genereren. Deze toepassing is speciaal ontworpen om het maximale privacy- en beveiligingsniveau te bieden voor de gegevens van de gebruikers. Eén belangrijk aspect van het beveiligen van privégegevens is dat de gebruiker een wachtwoord moet invoeren telkens wanneer de toepassing verbinding met de database maakt. Zoals in dit voorbeeld wordt geïllustreerd, betekent dit dat een toepassing die een dergelijk privacyniveau vereist, de databasecoderingssleutel nooit rechtstreeks mag opslaan. De toepassing bestaat uit twee delen: een ActionScript-klasse die een coderingssleutel genereert (de klasse EncryptionKeyGenerator) en een basisgebruikersinterface die demonstreert hoe die klasse moet worden gebruikt. De volledige broncode vindt u in “Complete voorbeeldcode voor het genereren en gebruiken van een coderingssleutel” op pagina 213.
De klasse EncryptionKeyGenerator gebruiken om een veilige coderingssleutel te verkrijgen. In de sectie “De klasse EncryptionKeyGenerator” op pagina 208 worden de technieken beschreven die de klasse EncryptionKeyGenerator gebruikt om een coderingssleutel voor een database te gebruiken. Het is echter niet nodig om deze details te kennen om de klasse EncryptionKeyGenerator in uw toepassing te gebruiken.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 206 Werken met lokale SQL-databases
Ga als volgt te werk om de klasse EncryptionKeyGenerator in uw toepassing te gebruiken: 1 De klasse EncryptionKeyGenerator is opgenomen in het as3corelib-project (open-source ActionScript 3.0 core
library project). U kunt het as3corelib-pakket, inclusief broncode en documentatie downloaden. U kunt de SWCof broncodebestanden ook downloaden van de projectpagina. 2 Plaats de broncode voor de klasse EncryptionKeyGenerator (of de as3corelib-SWC) op een locatie waar de
broncode van de toepassing deze kan vinden. 3 Voeg aan de broncode van uw toepassing een import-instructie voor de klasse EncryptionKeyGenerator toe. import com.adobe.air.crypto.EncryptionKeyGenerator;
4 Vóór het punt waarop de code de database maakt of een verbinding met de database opent, voegt u code toe om een
EncryptionKeyGenerator-instantie te maken. Daartoe roept u de EncryptionKeyGenerator()-constructor aan. var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator();
5 Vraag een wachtwoord aan de gebruiker: var password:String = passwordInput.text; if (!keyGenerator.validateStrongPassword(password)) { // display an error message return; }
De EncryptionKeyGenerator-instantie gebruikt dit wachtwoord als de basis voor de coderingssleutel (weergegeven in de volgende stap). De EncryptionKeyGenerator-instantie test het wachtwoord aan de hand van bepaalde vereisten voor sterke wachtwoorden. Als de validatie mislukt, treedt een fout op. Zoals in de voorbeeldcode wordt geïllustreerd, kunt u het wachtwoord op voorhand controleren door de methode validateStrongPassword() van het EncryptionKeyGenerator-object aan te roepen. Op die manier kunt u bepalen of het wachtwoord aan de minimale vereisten voor een sterk wachtwoord voldoet, en kunt u een fout vermijden. 6 Genereer de coderingssleutel vanuit het wachtwoord: var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password);
De methode getEncryptionKey() genereert en retourneert de coderingssleutel (een ByteArray van 16 bytes). U kunt de coderingssleutel gebruiken om de nieuwe gecodeerde database te maken of u kunt de bestaande openen. De methode getEncryptionKey() heeft één verplichte parameter, namelijk het wachtwoord dat in stap 5 is verkregen. Opmerking: Om het hoogste niveau voor beveiliging en privacy van de gegevens te behouden, moet een toepassing de gebruiker om het wachtwoord vragen, telkens wanneer de toepassing verbinding met de database maakt. Sla het wachtwoord of de coderingssleutel van de toepassing niet rechtstreeks op. Dit levert beveiligingsrisico's op. In plaats daarvan moet een toepassing -zoals in dit voorbeeld wordt geïllustreerd - telkens opnieuw de dezelfde techniek gebruiken om de coderingssleutel uit het wachtwoord te halen, dus zowel wanneer de gecodeerde database wordt gemaakt als wanneer later verbinding met de database wordt gemaakt.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 207 Werken met lokale SQL-databases
De methode getEncryptionKey() accepteert ook een tweede (optionele) parameter, de parameter overrideSaltELSKey. De EncryptionKeyGenerator maakt een willekeurige waarde (een zogenaamde salt) die als deel van de coderingssleutel wordt gebruikt. Om de coderingssleutel opnieuw te kunnen maken, wordt de saltwaarde opgeslagen in de ELS (Encrypted Local Store) van de AIT-toepassing. Standaard gebruikt de klasse EncryptionKeyGenerator een bepaalde tekenreeks als de ELS-sleutel. Hoewel onwaarschijnlijk, is het mogelijk dat de sleutel een conflict kan opleveren met een andere sleutel die in de toepassing wordt gebruikt. In plaats van de standaardsleutel te gebruiken, kunt u ook uw eigen ELS-sleutel opgeven. In dat geval geeft u een aangepaste sleutel op door deze als tweede getEncryptionKey()-parameter door te geven, zoals hier wordt geïllustreerd: var customKey:String = "My custom ELS salt key"; var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password, customKey);
7 De database maken of openen
Met de coderingssleutel die door de methode getEncryptionKey() wordt geretourneerd, kan uw code een nieuwe gecodeerde database maken of proberen om verbinding te maken met de bestaande gecodeerde database. In beide gevallen gebruikt u de methode open() of openAsync() van de klasse SQLConnection zoals wordt beschreven in “Een gecodeerde database maken” op pagina 200 en “Verbinding maken met een gecodeerde database” op pagina 202. In dit voorbeeld is de toepassing ontworpen om de database te openen in de asynchrone uitvoeringsmodus. De code stelt de juiste gebeurtenislisteners in en roept de methode openAsync() aan, waarbij de coderingssleutel wordt doorgegeven als het laatste argument: conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, openError); conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey);
In de listenermethoden verwijdert de code de gebeurtenislistener-registraties. Vervolgens wordt een statusbericht weergegeven waarin wordt aangegeven of de database is gemaakt, geopend of dat er een fout is opgetreden. Het belangrijkste gedeelte van deze gebeurtenishandlers zit in de methode openError(). In die methode controleert een if-instructie of de database bestaat (wat betekent dat er wordt geprobeerd verbinding te maken met een bestaande database) en of de fout-id overeenkomt met de constante EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID. Als beide voorwaarden waar zijn, betekent dit waarschijnlijk dat de gebruiker een verkeerd wachtwoord heeft ingevoerd. (Het kan ook betekenen dat het opgegeven bestand helemaal geen databasebestand is.) Hier volgt de code die de fout-id controleert: if (!createNewDB && event.error.errorID == EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID) { statusMsg.text = "Incorrect password!"; } else { statusMsg.text = "Error creating or opening database."; }
Voor de volledige code van de voorbeeldgebeurtenislisteners raadpleegt u “Complete voorbeeldcode voor het genereren en gebruiken van een coderingssleutel” op pagina 213.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 208 Werken met lokale SQL-databases
De klasse EncryptionKeyGenerator Het is niet nodig dat u precies begrijpt hoe de klasse EncryptionKeyGenerator werkt om deze te gebruiken om een veilige coderingssleutel voor uw toepassingsdatabase te maken. Het gebruik van de klasse wordt uitgelegd in “De klasse EncryptionKeyGenerator gebruiken om een veilige coderingssleutel te verkrijgen.” op pagina 205. Het is misschien echter handig om te begrijpen welke technieken de klasse gebruikt. Misschien wilt de klasse bijvoorbeeld aanpassen, of bepaalde technieken van deze klasse gebruiken voor situaties waarin een ander niveau van gegevensprivacy is gewenst. De klasse EncryptionKeyGenerator is opgenomen in het as3corelib-project (open-source ActionScript 3.0 core library project). U kunt het as3corelib-pakket inclusief broncode en documentatie downloaden. U kunt ook de broncode op de projectsite bekijken of deze downloaden om tijdens de uitleg te volgen. Wanneer code een EncryptionKeyGenerator-exemplaar maakt en de methode getEncryptionKey() aanroept, moeten enkele stappen worden uitgevoerd om ervoor te zorgen dat alleen de juiste gebruiker toegang heeft tot de gegevens. Het proces voor het genereren van een coderingssleutel vanuit een door de gebruiker ingevoerd wachtwoord voordat de database wordt gemaakt, is precies hetzelfde als wanneer de coderingssleutel opnieuw moet worden gemaakt om de database te openen. Een sterk wachtwoord verkrijgen en valideren Wanneer code de methode getEncryptionKey() aanroept, wordt een wachtwoord als parameter doorgegeven. Dit wachtwoord wordt gebruikt als de basis voor de coderingssleutel. Door gebruik te maken van informatie die alleen bekend is aan de gebruiker, bent u er met dit ontwerp zeker van dat alleen de gebruiker die het wachtwoord kent, toegang kan krijgen tot de gegevens in de database. Zelfs als een aanvaller toegang kan krijgen tot de account van die gebruiker op de computer, kan de aanvaller de database alleen openen als hij beschikt over het wachtwoord. Voor maximale veiligheid slaat de toepassing het wachtwoord nooit op. In de voorbeeldtoepassing is passwordInput de instantienaam van een TextInput-component waarin de gebruiker het wachtwoord invoert. In plaats van de text-waarde van het component rechtstreeks te manipuleren, kopieert de toepassing het wachtwoord naar een variabele met de naam password. var password:String = passwordInput.text;
De voorbeeldtoepassing maakt vervolgens een EncryptionKeyGenerator-instantie en roept de methode getEncryptionKey() van deze instantie aan, waarbij de variabele password als een argument wordt doorgegeven: var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator(); var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password);
Wanneer de methode getEncryptionKey() wordt aangeroepen, controleert de klasse EncryptionKeyGenerator eerst het door de gebruiker ingevoerde wachtwoord om na te gaan of het een sterk wachtwoord is. In dit geval moet het wachtwoord uit 8 tot 32 tekens bestaan. Verder moet het wachtwoord zowel hoofd- als kleine letters bevatten, en minimaal één cijfer of symbool. De reguliere expressie waarmee dit patroon wordt gecontroleerd, is gedefinieerd als een constante met de naam STRONG_PASSWORD_PATTERN: private static const STRONG_PASSWORD_PATTERN:RegExp = /(?=^.{8,32}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/;
De code waarmee het wachtwoord wordt gecontroleerd, bevindt zich in de methode validateStrongPassword() van de klasse EncryptionKeyGenerator. De code is als volgt:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 209 Werken met lokale SQL-databases
public function vaidateStrongPassword(password:String):Boolean { if (password == null || password.length <= 0) { return false; } return STRONG_PASSWORD_PATTERN.test(password)) }
De methode getEncryptionKey() roept de methode validateStrongPassword() aan en genereert een uitzondering als het wachtwoord ongeldig is. De methode validateStrongPassword() is een openbare methode zodat code een wachtwoord kan controleren zonder de methode getEncryptionKey() aan te roepen om te vermijden dat een fout wordt veroorzaakt. Het wachtwoord uitbreiden tot 256 bits Verderop in het proces moet het wachtwoord 256 bits lang zijn. De code vraagt niet iedere gebruiker een wachtwoord in te voeren dat precies 256 bits (32 tekens) lang is, maar creëert een langer wachtwoord door de tekens van het wachtwoord te herhalen. De methode getEncryptionKey() roept de methode concatenatePassword() aan om het lange wachtwoord te maken. var concatenatedPassword:String = concatenatePassword(password);
Hier volgt de code voor de methode concatenatePassword(): private function concatenatePassword(pwd:String):String { var len:int = pwd.length; var targetLength:int = 32; if (len == targetLength) { return pwd; } var repetitions:int = Math.floor(targetLength / len); var excess:int = targetLength % len; var result:String = ""; for (var i:uint = 0; i < repetitions; i++) { result += pwd; } result += pwd.substr(0, excess); return result; }
Als het wachtwoord korter is dan 256 bits, voegt de code het wachtwoord nogmaals toe om er 256 bits van te maken. Als de lengte niet precies klopt, wordt het laatste stuk afgekapt zodat het wachtwoord precies 256 bits lang is.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 210 Werken met lokale SQL-databases
Een salt-waarde van 256 bits genereren of ophalen De volgende stap is het verkrijgen van een salt-waarde van 256 bits die in een latere stap wordt gecombineerd met het wachtwoord. Een salt is een willekeurige waarde die wordt toegevoegd aan of gecombineerd met een door de gebruiker ingevoerde waarde om een wachtwoord te vormen. Als u een salt gebruikt met een wachtwoord, weet u zeker dat zelfs als de gebruiker een bestaand woord of veelgebruikte term als wachtwoord gebruikt, de combinatie van wachtwoord met salt die het systeem gebruikt, een willekeurige waarde is. Deze willekeurigheid helpt een woordenlijstaanval te voorkomen, waarbij een hacker een lijst met woorden gebruikt om een wachtwoord te raden. Verder wordt door het genereren van de salt-waarde en het opslaan daarvan in de gecodeerde lokale opslag, de salt-waarde gekoppeld aan de account van de gebruiker op de computer waarop de database zich bevindt. Als de toepassing de methode getEncryptionKey() de eerste keer aanroept, maakt de code een willekeurige saltwaarde van 256 bits. In het vervolg laadt de code de waarde uit de gecodeerde lokale opslag. De salt wordt opgeslagen in een variabele met de naam salt. De code bepaalt of er al een salt is gemaakt door te proberen de salt te laden uit de gecodeerde lokale opslag: var salt:ByteArray = EncryptedLocalStore.getItem(saltKey); if (salt == null) { salt = makeSalt(); EncryptedLocalStore.setItem(saltKey, salt); }
Als de code een nieuwe salt-waarde maakt, genereert de methode makeSalt() een willekeurige waarde van 256 bits. Aangezien deze waarde uiteindelijk wordt opgeslagen in de gecodeerde lokale opslag, wordt de waarde gegenereerd als ByteArray-object. De methode makeSalt() gebruikt de methode Math.random() om een willekeurige waarde te genereren. De methode Math.random() kan niet 256 bits tegelijk genereren. In plaats daarvan gebruikt de code een lus om Math.random() acht keer aan te roepen. Iedere keer wordt een willekeurige uint-waarde tussen 0 en 4294967295 (de maximale uint-waarde) gegenereerd. De uint-waarde wordt voor het gemak gebruikt, aangezien een uint precies 32 bits gebruikt. Door acht uint-waarden naar de ByteArray te schrijven wordt een waarde van 256 bits gegenereerd. Hieronder volgt de code voor de methode makeSalt(): private function makeSalt():ByteArray { var result:ByteArray = new ByteArray; for (var i:uint = 0; i < 8; i++) { result.writeUnsignedInt(Math.round(Math.random() * uint.MAX_VALUE)); } return result; }
Wanneer de code de salt opslaat in de ELS (Encrypted Local Store) of de salt uit de ELS ophaalt, heeft deze een Stringsleutel nodig waarin de salt wordt opgeslagen. De salt-waarde kan niet worden opgehaald zonder de sleutel te kennen. In dat geval kan de coderingssleutel niet opnieuw worden gemaakt wanneer de database opnieuw moet worden geopend. Standaard gebruikt de EncryptionKeyGenerator een op voorhand gedefinieerde ELS-sleutel die is gedefinieerd in de constante SALT_ELS_KEY. In plaats van de standaardsleutel te gebruiken, kan de toepassingscode ook een ELS-sleutel opgeven die moet worden gebruikt in de aanroep van de methode getEncryptionKey(). De standaardsleutel of de in de toepassing opgegeven ELS-sleutels wordt opgeslagen in een variabele met de naam saltKey. Die variabele wordt gebruikt in de aanroepen van EncryptedLocalStore.setItem() en EncryptedLocalStore.getItem(), zoals u in de vorige listing hebt kunnen zien.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 211 Werken met lokale SQL-databases
Het 256-bits wachtwoord combineren met de salt met behulp van de XOR-operator De code heeft nu een wachtwoord van 256 bits en een salt-waarde van 256 bits. Vervolgens wordt een bitsgewijze XORbewerking gebruikt om de salt en het samengevoegde wachtwoord in één enkele waarde te gebruiken. In feite wordt met deze techniek een wachtwoord van 256 bits gemaakt bestaande uit tekens uit het hele bereik van mogelijke tekens. Dit principe is waar, ook al bestaat het ingevoerde wachtwoord hoogstwaarschijnlijk voornamelijk uit alfanumerieke tekens. Deze extra willekeurigheid biedt het voordeel dat de set mogelijke wachtwoorden groot is zonder dat de gebruiker een lang en complex wachtwoord moet invoeren. Het resultaat van de XOR-bewerking wordt opgeslagen in de variabele unhashedKey. De bitsgewijze XOR voor de twee waarden wordt in werkelijkheid uitgevoerd in de methode xorBytes(): var unhashedKey:ByteArray = xorBytes(concatenatedPassword, salt);
De bitsgewijze XOR-operator (^) gebruikt twee uint-waarden en geeft als resultaat een uint-waarde. (Een uint-waarde bevat 32 bits.) De ingevoerde waarden die als argumenten worden doorgegeven aan de methode xorBytes(), bestaan uit een tekenreeks (het wachtwoord) en een ByteArray (de salt). De code gebruikt een lus om 32 bits per keer uit ieder invoergegeven te extraheren, die dan worden gecombineerd met gebruikmaking van de XOR-operator. private function xorBytes(passwordString:String, salt:ByteArray):ByteArray { var result:ByteArray = new ByteArray(); for (var i:uint = 0; i < 32; i += 4) { // ... } return result; }
Binnen de lus worden de eerste 32 bits (4 bytes) uit de parameter passwordString gehaald. Deze bits worden geëxtraheerd en vervolgens geconverteerd naar een (o1) met een proces dat uit twee delen bestaat. Eerst haalt de methode charCodeAt() de numerieke waarde van ieder teken op. Vervolgens wordt deze waarde naar de juiste positie in de uint verschoven met behulp van de bitsgewijze operator voor verschuiven naar links (<<). De verschoven waarde wordt toegevoegd aan o1. Het eerste teken (i) wordt bijvoorbeeld de eerste 8 bits door de operator voor bitsgewijs naar links verplaatsen (<<) te gebruiken om de bits 24 bits naar links te verplaatsen en die waarde toe te wijzen aan o1. Het tweede teken (i + 1) wordt de tweede 8 bits door de waarde ervan 16 bits naar links te verplaatsen en het resultaat toe te voegen aan o1. De waarden voor het derde en het vierde teken worden op dezelfde manier toegevoegd. // ... // Extract 4 bytes from the password string and convert to a uint var o1:uint = passwordString.charCodeAt(i) << 24; o1 += passwordString.charCodeAt(i + 1) << 16; o1 += passwordString.charCodeAt(i + 2) << 8; o1 += passwordString.charCodeAt(i + 3); // ...
De variabele o1 bevat nu 32 bits uit de parameter passwordString. Vervolgens worden 32 bits geëxtraheerd uit de parameter salt door de methode readUnsignedInt() ervan aan te roepen. De 32 bits worden opgeslagen in de uintvariabele o2.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 212 Werken met lokale SQL-databases
Tot slot worden de twee 32-bits waarden gecombineerd met de operator XOR en wordt het resultaat weggeschreven naar een ByteArray met de naam result. // ... var xor:uint = o1 ^ o2; result.writeUnsignedInt(xor); // ...
Als de lus is voltooid, wordt de ByteArray met het XOR-resultaat geretourneerd. // ... } return result; }
De sleutel hashen Wanneer het samengevoegde wachtwoord en de salt zijn gecombineerd, moet deze tekenreeks verder worden beveiligd door er het hashing-logaritme SHA-256 op toe te passen. Door de waarde te hashen wordt het voor een aanvaller moeilijker deze te reverse-engineeren. Op dit moment heeft de code een ByteArray met de naam unhashedKey die het samengevoegde wachtwoord bevat dat met de salt is gecombineerd. Het as3corelib-project (de kernbibliotheek van ActionScript 3.0) bevat een klasse SHA256 in het pakket com.adobe.crypto. De methode SHA256.hashBytes() die een SHA-256-hash uitvoert voor een ByteArray en een tekenreeks retourneert die het hash-resultaat van 256 bits bevat als een hexadecimaal getal. De klasse EncryptionKeyGenerator gebruikt de klasse SHA256 om de sleutel te husselen (hashing): var hashedKey:String = SHA256.hashBytes(unhashedKey);
De coderingssleutel uit de hash extraheren De coderingssleutel moet een ByteArray zijn die precies 16 bytes (128 bits) lang is. Het resultaat van het hash-algoritme SHA-256 is altijd 256 bits lang. Dat betekent dat in de laatste stap 128 bits uit het hash-resultaat gehaald moeten worden die de uiteindelijke coderingssleutel gaan vormen. In de klasse EncryptionKeyGenerator reduceert de code de sleutel tot 128 bits door de methode generateEncryptionKey() aan te roepen. Vervolgens wordt het resultaat van die methode geretourneerd als het resultaat van de methode getEncryptionKey(): var encryptionKey:ByteArray = generateEncryptionKey(hashedKey); return encryptionKey;
Het is niet noodzakelijk om de eerste 128 bits als coderingssleutel te gebruiken. U zou een reeks bits kunnen selecteren vanaf een willekeurig punt, u zou elke andere bit kunnen selecteren, of bits op een andere manier kunnen selecteren. Essentieel is dat de code 128 specifieke bits selecteert en dat diezelfde 128 bits iedere keer opnieuw worden gebruikt.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 213 Werken met lokale SQL-databases
In dit geval gebruikt de methode generateEncryptionKey() de reeks bits die op de 18de byte begint, als coderingssleutel. Zoals eerder vermeld geeft de klasse SHA256 als resultaat een tekenreeks met een 256-bits hash als hexadecimaal getal. Eén enkel blok van 128 bits heeft te veel bytes om in één keer aan een ByteArray toe te voegen. De code gebruikte daarom een for-lus om tekens uit de hexadecimale tekenreeks te extraheren, deze te converteren naar numerieke waarden en die toe te voegen aan de ByteArray. De resultaatreeks van SHA-256 is 64 tekens lang. Een bereik van 128 bits is gelijk aan 32 tekens in de tekenreeks, en elk teken vertegenwoordigt 4 bits. De kleinste gegevenstoename die u kunt toevoegen aan een ByteArray is 1 byte (8 bits), hetgeen equivalent is aan twee tekens in de hash-tekenreeks. De lus telt daarom van 0 tot 31 (32 tekens) in stappen van 2 tekens. Binnen de lus bepaalt de code eerst de beginpositie voor het huidige paar tekens. Aangezien het gewenste bereik start bij het teken op indexpositie 17 (de 18e byte), wordt aan de variabele position de huidige iteratorwaarde (i) plus 17 toegekend. De code gebruikt de methode substr() van het tekenreeksobject om de twee tekens op de huidige positie te extraheren. Deze twee tekens worden opgeslagen in de variabele hex. Vervolgens gebruikt de code de methode parseInt() om de hex-tekenreeks te converteren naar een decimaal geheel getal. Deze slaat die waarde op in de intvariabele byte. Tot slot voegt de code de waarde in byte toe aan de ByteArray result met behulp van de methode writeByte(). Wanneer de lus gereed is, bevat de ByteArray result 16 bytes en is deze gereed voor gebruik als databasecoderingssleutel. private function generateEncryptionKey(hash:String):ByteArray { var result:ByteArray = new ByteArray(); for (var i:uint = 0; i < 32; i += 2) { var position:uint = i + 17; var hex:String = hash.substr(position, 2); var byte:int = parseInt(hex, 16); result.writeByte(byte); } return result; }
Complete voorbeeldcode voor het genereren en gebruiken van een coderingssleutel Hier volgt de volledige code voor de voorbeeldtoepassing 'Een coderingssleutel genereren en gebruiken'. De code bestaat uit twee delen. Het voorbeeld gebruikt de klasse EncryptionKeyGenerator om een coderingssleutel te maken op basis van een wachtwoord. De klasse EncryptionKeyGenerator is opgenomen in het as3corelib-project (open-source ActionScript 3.0 core library project). U kunt het as3corelib-pakket, inclusief broncode en documentatie downloaden. U kunt de SWC- of broncodebestanden ook downloaden van de projectpagina. Het FLA-bestand van de toepassing bevat de broncode voor een eenvoudige toepassing die een verbinding met een gecodeerde database maakt of opent. Het FLA-bestand heeft vier onderdelen in het werkgebied geplaatst: Instantienaam
Type onderdeel
Beschrijving
instructies
Label
Bevat de instructies die aan de gebruiker worden gegeven
passwordInput
TextInput
Invoerveld waarin de gebruiker het wachtwoord typt
openButton
Button
Knop waarop de gebruiker klikt nadat het wachtwoord is ingevoerd
statusMsg
Label
Geeft statusberichten (geslaagd of niet geslaagd) weer
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 214 Werken met lokale SQL-databases
De code voor de toepassing wordt gedefinieerd in een hoofdframe in frame 1 van de hoofdtijdlijn. Hier volgt de code voor de toepassing: import com.adobe.air.crypto.EncryptionKeyGenerator; const dbFileName:String = "encryptedDatabase.db"; var dbFile:File; var createNewDB:Boolean = true; var conn:SQLConnection; init(); // ------- Event handling ------function init():void { passwordInput.displayAsPassword = true; openButton.addEventListener(MouseEvent.CLICK, openConnection); statusMsg.setStyle("textFormat", new TextFormat(null, null, 0x990000)); conn = new SQLConnection(); dbFile = File.applicationStorageDirectory.resolvePath(dbFileName); if (dbFile.exists) { createNewDB = false; instructions.text = "Enter your database password to open the encrypted database."; openButton.label = "Open Database"; } else { instructions.text = "Enter a password to create an encrypted database. The next time you open the application, you will need to re-enter the password to open the database again."; openButton.label = "Create Database"; } } function openConnection(event:MouseEvent):void { var keyGenerator:EncryptionKeyGenerator = new EncryptionKeyGenerator(); var password:String = passwordInput.text; if (password == null || password.length <= 0) { statusMsg.text = "Please specify a password."; return; } if (!keyGenerator.validateStrongPassword(password)) { statusMsg.text = "The password must be 8-32 characters long. It must contain at least one lowercase letter, at least one uppercase letter, and at least one number or symbol."; return; }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 215 Werken met lokale SQL-databases
passwordInput.text = ""; passwordInput.enabled = false; openButton.enabled = false; var encryptionKey:ByteArray = keyGenerator.getEncryptionKey(password); conn.addEventListener(SQLEvent.OPEN, openHandler); conn.addEventListener(SQLErrorEvent.ERROR, openError); conn.openAsync(dbFile, SQLMode.CREATE, null, false, 1024, encryptionKey); } function openHandler(event:SQLEvent):void { conn.removeEventListener(SQLEvent.OPEN, openHandler); conn.removeEventListener(SQLErrorEvent.ERROR, openError); statusMsg.setStyle("textFormat", new TextFormat(null, null, 0x009900)); if (createNewDB) { statusMsg.text = "The encrypted database was created successfully."; } else { statusMsg.text = "The encrypted database was opened successfully."; } } function openError(event:SQLErrorEvent):void { conn.removeEventListener(SQLEvent.OPEN, openHandler); conn.removeEventListener(SQLErrorEvent.ERROR, openError); if (!createNewDB && event.error.errorID == EncryptionKeyGenerator.ENCRYPTED_DB_PASSWORD_ERROR_ID) { statusMsg.text = "Incorrect password!"; } else { statusMsg.text = "Error creating or opening database."; } }
Strategieën voor het werken met SQL-databases Er zijn verschillende manieren waarop een toepassing een lokale SQL-database kan benaderen en ermee kan werken. Het ontwerp van de toepassing kan variëren op het gebied van de structuur van de toepassingscode, de sequentie en timing van de uitvoering van de bewerkingen enzovoort. De technieken die u kiest, kunnen een invloed hebben op het gemak waarmee uw toepassing kan worden ontwikkeld. Ze kunnen een invloed hebben op het gemak waarmee de toepassing in de toekomst kan worden aangepast. Ze kunnen ook een invloed hebben op de prestaties van de toepassing voor de gebruiker.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 216 Werken met lokale SQL-databases
Niet-lege databases distribueren Als u een lokale SQL-database van AIR in uw toepassing gebruikt, verwacht de toepassing een database met een bepaalde structuur (tabellen, kolommen enzovoort). Sommige toepassingen verwachten ook bepaalde gegevens in het databasebestand. U kunt op verschillende manieren zorgen dat de database de juiste structuur heeft, onder andere door de database binnen de toepassingscode te creëren. Wanneer de toepassing wordt geladen, controleert deze of het gekoppelde databasebestand zich op een bepaalde locatie bevindt. Als dat niet het geval is, voert de toepassing een reeks opdrachten uit om het databasebestand te creëren, de databasestructuur toe te passen en de tabellen te vullen met de initiële gegevens. De code die de database en de overeenkomstige tabellen creëert, is vaak complex. Hoewel deze code doorgaans slechts één keer tijdens de levensduur van de geïnstalleerde toepassing wordt gebruikt, wordt de toepassing er groter en complexer door. Een alternatief voor het programmamatig creëren van de database, structuur en gegevens is uw toepassing te distribueren met een niet-lege database. Hiervoor neemt u het databasebestand op in het AIR-pakket van de toepassing. Net als alle bestanden die in een AIR-pakket worden opgenomen, wordt een gebundeld databasebestand geïnstalleerd in de toepassingsmap (de map die wordt ingesteld door de eigenschap File.applicationDirectory). Bestanden in die map zijn echter alleen-lezen. Gebruik het bestand uit het AIR-pakket als “sjabloon”database. De eerste keer dat een gebruiker de toepassing uitvoert, kopieert u het oorspronkelijke databasebestand naar de toepassingsopslagdirectory van de gebruiker (of een andere locatie). Vervolgens wordt die database in de toepassing gebruikt.
Databaseprestaties verbeteren Met een aantal technieken die in Adobe AIR zijn ingebouwd, kunt u de prestaties van de databasebewerkingen in uw toepassing verbeteren. Naast de hier beschreven technieken kan ook de manier waarop een SQL-instructie is geschreven, de databaseprestaties beïnvloeden. Er zijn doorgaans meerdere manieren om de SQL-instructie SELECT te schrijven om een specifieke resultaatset op te halen. In sommige gevallen is de belasting op de database-engine afhankelijk van de techniek die u gebruikt. Dit aspect van het verbeteren van de databaseprestaties (het ontwerpen van SQL-instructies voor prestatieverbetering) wordt niet besproken in de documentatie bij Adobe AIR.
Gebruik één SQLStatement-instantie per SQL-instructie Voordat een SQL-instructie wordt uitgevoerd, wordt deze door de runtime voorbereid (gecompileerd) om de stappen te bepalen die intern moeten worden uitgevoerd om de instructie uit te voeren. Als u SQLStatement.execute() oproept voor een SQLStatement-instantie die nog niet heeft uitgevoerd, wordt de instructie automatisch voorbereid voordat deze wordt uitgevoerd. De volgende keren dat u de methode execute() oproept, is de instructie al voorbereid mits de eigenschap SQLStatement.text niet is gewijzigd. Als gevolg daarvan wordt deze sneller uitgevoerd. Als u het maximale voordeel wilt halen uit het hergebruik van instructies, en waarden tussen de uitvoering van instructies gewijzigd moeten worden, gebruikt u instructieparameters om uw instructie aan te passen. (U geeft instructieparameters op via de associatieve-array-eigenschap SQLStatement.parameters.) Bij het wijzigen van de eigenschap text van de SQLStatement-instantie moet de runtime de instructie opnieuw voorbereiden. Als u de waarden van instructieparameters wijzigt, is dit niet het geval. Zie “Parameters gebruiken in instructies” op pagina 180 voor meer informatie over het gebruik van parameters in instructies. Aangezien het voorbereiden en uitvoeren van een instructie voor een grote belasting van de database-engine kan zorgen, wordt u aangeraden de initiële gegevens vooraf te laden en vervolgens andere instructies op de achtergrond uit te voeren. Laad de gegevens die de toepassing het eerst nodig heeft. Nadat het initiële opstarten van uw toepassing is voltooid, of tijdens een andere periode van inactiviteit binnen de toepassing, voert u andere instructies uit. Als uw toepassing bijvoorbeeld de database helemaal niet nodig heeft om het beginscherm weer te geven, wacht u tot het
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 217 Werken met lokale SQL-databases
beginscherm verschijnt, opent u vervolgens de databaseverbinding, en creëert u ten slotte de SQLStatement-instanties en voert u alle mogelijke instanties uit. Het is echter ook mogelijk dat uw toepassing bij het opstarten onmiddellijk bepaalde gegevens weergeeft, zoals het resultaat van een query. In dat geval voert u de SQLStatement-instantie voor de desbetreffende query uit. Nadat de initiële gegevens zijn geladen en weergegeven, creëert u SQLStatement-instanties voor andere databasebewerkingen en voert u indien mogelijk later andere instructies uit die nodig zijn. Als u een SQLStatement-instantie opnieuw gebruikt, moet uw toepassing een verwijzing naar de SQLStatementinstantie bijhouden nadat deze is voorbereid. Hiervoor definieert u de variabele als een variabele van het type ‘klasse’ en niet van het type ‘functie’. Een goede manier hiervoor is uw toepassing zo te structureren dat een SQL-instructie aan één klasse wordt toegewezen. U kunt ook een groep van instructies die gecombineerd worden uitgevoerd, toewijzen aan één klasse. Wanneer u de SQLStatement-instantie(s) als lidvariabelen van de klasse definieert, blijven ze bestaan zolang de instantie van de klasse waaraan ze zijn toegewezen, in de toepassing bestaat. Als minimale oplossing kunt u gewoon een variabele definiëren die de SQLStatement-instantie buiten een functie bevat zodat de instantie in het geheugen blijft bestaan. Definieer de SQLStatement-instantie bijvoorbeeld als een lidvariabele in een ActionScriptklasse of als een niet-functievariabele in een JavaScript-bestand. Vervolgens kunt u de parameterwaarden van de instructie instellen en de methode execute() van de instructie oproepen wanneer u de query daadwerkelijk wilt uitvoeren.
Meerdere bewerkingen in een transactie groeperen U voert bijvoorbeeld een groot aantal SQL-instructies uit die gegevens toevoegen of wijzigen (instructies van het type INSERT of UPDATE). U kunt een aanzienlijke prestatieverbetering verkrijgen door alle instructies binnen een expliciete transactie uit te voeren. Als u niet expliciet een transactie begint, wordt elke instructie binnen zijn eigen, automatisch gegenereerde transactie uitgevoerd. Nadat elke transactie (elke instructie) is voltooid, schrijft de runtime de resultaatgegevens naar het databasebestand op de schijf. Anderzijds moet u rekening houden met wat er gebeurt als u expliciet een transactie genereert en de instructies in het kader van die transactie uitvoert. De runtime voert alle wijzigingen in het geheugen uit en schrijft ze vervolgens alle tegelijk naar het databasebestand wanneer de transactie wordt bevestigd. Het naar schijf schrijven van gegevens is doorgaans het meest tijdsintensieve deel van de bewerking. Dit betekent dat u de prestaties aanzienlijk kunt verbeteren door de gegevens alle tegelijk naar schijf te schrijven in plaats van één keer per SQL-instructie.
Runtimeverwerking tot het minimum beperken Met behulp van de volgende technieken kunt u onnodige belasting van de database-engine voorkomen en toepassingen sneller maken:
• Geef altijd expliciet database- en tabelnamen op in een instructie. (Gebruik ‘main’ voor de hoofddatabase.) Gebruik bijvoorbeeld SELECT id_werknemer FROM main.werknemers in plaats van SELECT id_werknemer FROM werknemers. Door de databasenaam expliciet op te geven zorgt u dat de runtime niet elke database hoeft te
doorzoeken om de vereiste tabel te vinden. Bovendien kan de runtime niet de verkeerde database kiezen. Neem altijd deze regel in acht, zelfs als een SQLConnection met maar één database is verbonden. De SQLConnection is namelijk op de achtergrond ook verbonden met een tijdelijke database die toegankelijk is via SQL-instructies.
• Geef altijd expliciet kolomnamen op in een instructie van het type SELECT of INSERT. • Verdeel de rijen die worden weergegeven door een instructie van het type SELECT die een groot aantal rijen ophaalt. Zie “SELECT-resultaten in delen ophalen” op pagina 187 voor meer informatie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 218 Werken met lokale SQL-databases
Wijzig het schema niet Wijzig indien mogelijk het schema (de tabelstructuur) van een database niet meer nadat u gegevens hebt toegevoegd aan de tabellen van de database. In een databasebestand bevinden de tabeldefinities zich doorgaans aan het begin van het bestand. Wanneer u verbinding maakt met een database, worden deze definities door de runtime geladen. Wanneer u gegevens toevoegt aan databasetabellen, worden deze gegevens na de tabeldefinitiegegevens geplaatst. Als u echter schemawijzigingen aanbrengt, zoals het toevoegen van een kolom aan een tabel of het toevoegen van een nieuwe tabel, worden de nieuwe tabeldefinitiegegevens gemengd met de tabelgegevens in het databasebestand. Als niet alle tabeldefinitiegegevens zich aan het begin van het databasebestand bevinden, duurt het langer om verbinding te maken met de database omdat de runtime de tabeldefinitiegegevens op verschillende plaatsen in het bestand moet zoeken. Roep voor het uitvoeren van schemawijzigingen de methode SQLConnection.compact() op nadat de wijzigingen zijn voltooid. Hierdoor wordt het databasebestand opnieuw ingedeeld zodat alle tabeldefinitiegegevens zich aan het begin van het bestand bevinden. Het uitvoeren van de bewerking compact() kan echter lang duren, met name bij grote databasebestanden.
Aanbevolen procedures voor het werken met lokale SQL-databases Hieronder volgt een lijst van suggesties voor technieken die u kunt toepassen om de prestaties, de beveiliging en het onderhoudsgemak van uw toepassingen te verhogen bij het werken met lokale SQL-databases. Zie “Databaseprestaties verbeteren” op pagina 216 voor nog meer technieken voor het verbeteren van uw databasetoepassingen.
Creëer vooraf databaseverbindingen Zelfs als uw toepassing geen instructies uitvoert wanneer deze wordt geladen, maakt u een instantie van een SQLConnection-object en roept u de methode open() of openAsync() van de instantie zo vroeg mogelijk op (bijvoorbeeld onmiddellijk nadat de toepassing is gestart) om vertraging bij het uitvoeren van instructies te voorkomen. Zie “Verbinden met een database” op pagina 177.
Gebruik databaseverbindingen opnieuw Als u tijdens de uitvoering van uw toepassing een bepaalde database benadert, zorgt u voor een verwijzing naar de SQLConnection-instantie en gebruikt u deze altijd opnieuw in de hele toepassing zodat u de verbinding niet elke keer hoeft te sluiten en weer te openen. Zie “Verbinden met een database” op pagina 177.
Gebruik bij voorkeur de asynchrone uitvoeringsmodus Bij het schrijven van code voor het benaderen van gegevens kan het verleidelijk zijn om bewerkingen synchroon in plaats van asynchroon te laten uitvoeren omdat het gebruik van synchrone bewerkingen vaak kortere en minder complexe code vereist. Zoals is beschreven in “Synchrone en asynchrone databasebewerkingen gebruiken” op pagina 195 kunnen synchrone bewerkingen de prestaties echter zo verminderen dat de gebruiker dit merkt, zodat het werken met uw toepassing minder aantrekkelijk wordt. De tijd die nodig is om één bewerking uit te voeren, is afhankelijk van de bewerking en met name van de hoeveelheid gegevens die moet worden verwerkt. Bijvoorbeeld: een SQL-instructie van het type INSERT die maar één rij aan de database toevoegt, heeft minder tijd nodig dan een instructie van het type SELECT die duizenden rijen gegevens moet ophalen. Wanneer u echter de synchrone modus gebruikt om meerdere bewerkingen uit te voeren, worden de bewerkingen doorgaans samengeperst. Zelfs als elke bewerking slechts een korte uitvoeringstijd heeft, blokkeert de toepassing tot alle synchrone bewerkingen zijn voltooid. Hierdoor is de totale uitvoeringstijd van meerdere samengeperste bewerkingen mogelijk lang genoeg om uw toepassing onbruikbaar te maken.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 219 Werken met lokale SQL-databases
Gebruik daarom standaard de asynchrone modus, met name voor bewerkingen met een groot aantal rijen. Er bestaat een techniek om de verwerking van grote resultaatsets van de instructie SELECT te verdelen. Zie hiervoor “SELECTresultaten in delen ophalen” op pagina 187. Deze techniek kan echter alleen in de asynchrone uitvoeringsmodus worden gebruikt. Gebruik alleen synchrone bewerkingen wanneer u een bepaald resultaat niet met asynchrone programmering kunt verkrijgen, wanneer u de afname aan prestaties waarmee de gebruikers van de toepassing worden geconfronteerd in overweging hebt genomen, en wanneer u de toepassing hebt getest zodat u weet wat de invloed op de prestaties van de toepassing zal zijn. Het gebruik van de asynchrone uitvoeringsmodus kan het coderen van de toepassing complexer maken. Vergeet echter niet dat u de code maar één hoeft te schrijven maar de gebruikers van uw toepassing deze vele keren moeten gebruiken, traag of snel. In vele gevallen kan een groot aantal SQL-bewerkingen tegelijk in de wachtrij worden geplaatst wanneer u een aparte SQLStatement-instantie voor elke uit te voeren SQL-instructie gebruikt, waardoor asynchrone code op ongeveer dezelfde manier als synchrone code wordt geschreven. Zie “De asynchrone uitvoeringsmodus” op pagina 198 voor meer informatie.
Gebruik aparte SQL-instructies en wijzig de eigenschap ‘text’ van de SQLStatement niet Creëer voor elke SQL-instructie die meer dan één keer in de toepassing wordt uitgevoerd, een aparte SQLStatementinstantie voor elke SQL-instructie. Gebruik die SQLStatement-instantie elke keer dat de overeenkomstige SQLopdracht wordt uitgevoerd. Als u bijvoorbeeld een toepassing schrijft met vier verschillende SQL-bewerkingen die meerdere keren worden uitgevoerd. In dat geval creëert u vier aparte SQLStatement-instanties en roept u de methode execute() van elke instructie op om deze uit te voeren. U kunt ook één SQLStatement-instantie voor alle SQLinstructies gebruiken, waarbij de eigenschap text van de instantie elke keer opnieuw wordt gedefinieerd voordat de instructie wordt uitgevoerd. Deze techniek wordt echter afgeraden. Zie “Gebruik één SQLStatement-instantie per SQL-instructie” op pagina 216 voor meer informatie.
Gebruik instructieparameters Gebruik SQLStatement-parameters en voeg gebruikersinvoer niet samen tot instructietekst. Het gebruik van parameters maakt uw toepassing veiliger omdat het SQL-injectieaanvallen onmogelijk maakt. Hierdoor kunt u objecten gebruiken in query’s (in plaats van alleen literale SQL-waarden). Bovendien worden de instructies efficiënter uitgevoerd omdat ze opnieuw kunnen worden gebruikt zonder dat ze opnieuw hoeven te worden gecompileerd elke keer dat ze worden uitgevoerd. Zie “Parameters gebruiken in instructies” op pagina 180 voor meer informatie.
Gebruik constanten voor kolom- en parameternamen Als u geen itemClass voor een SQLStatement opgeeft, moet u om spelfouten te voorkomen tekenreeksconstanten definiëren die de naam van de kolommen in een tabel bevatten. Gebruik deze constanten in de instructietekst en voor de eigenschapnamen bij het ophalen van waarden van resultaatobjecten. Gebruik ook voor parameternamen constanten.
220
Hoofdstuk 19: Gecodeerde gegevens opslaan De Adobe® AIR™-runtime beschikt over een permanente gecodeerde lokale opslag voor elke AIR-toepassing die op de computer van een gebruiker is geïnstalleerd. Hier kunt u gegevens opslaan en ophalen die op de lokale vaste schijf van de gebruikers zijn opgeslagen in een gecodeerde indeling die niet gemakkelijk kan worden ontcijferd door andere toepassingen of gebruikers. Voor elke AIR-toepassing wordt een afzonderlijke gecodeerde lokale opslag gebruikt en elke AIR-toepassing gebruikt een afzonderlijke gecodeerde lokale opslag voor elke gebruiker. Opmerking: Naast de gecodeerde lokale opslag biedt AIR ook codering voor inhoud die is opgeslagen in SQL-databases. Zie voor meer informatie “Codering gebruiken met SQL-databases” op pagina 199. In de gecodeerde lokale opslag kunt u informatie opslaan die moet worden beveiligd, zoals aanmeldingsgegevens voor webservices. AIR maakt in Windows van DPAPI, in Mac OS van KeyChain en in Linux van KeyRing of KWallet gebruik om de gecodeerde lokale opslag te koppelen aan elke toepassing en gebruiker. De gecodeerde lokale opslag gebruikt AESCBC 128-bits codering. Informatie in de gecodeerde lokale opslag is alleen beschikbaar voor de inhoud van een AIR-toepassing in de toepassingsbeveiligingssandbox. Gebruik de statische methoden setItem() en removeItem() van de klasse EncryptedLocalStore om gegevens in de lokale opslag op te slaan en op te halen. De gegevens worden opgeslagen in een hashtabel, waarbij tekenreeksen worden gebruikt als sleutels en de gegevens worden opgeslagen als bytearrays. Met de volgende code wordt bijvoorbeeld een tekenreeks opgeslagen in de gecodeerde lokale opslag: var str:String = "Bob"; var bytes:ByteArray = new ByteArray(); bytes.writeUTFBytes(str); EncryptedLocalStore.setItem("firstName", bytes); var storedValue:ByteArray = EncryptedLocalStore.getItem("firstName"); trace(storedValue.readUTFBytes(storedValue.length)); // "Bob"
De derde parameter van de methode setItem(), de parameter stronglyBound, is optioneel. Wanneer deze parameter op true is ingesteld, is de gecodeerde lokale opslag beter beveiligd doordat het opgeslagen item wordt gebonden aan de digitale handtekening en bits van de opslaande AIR-toepassing en aan de uitgevers-id van de toepassing, wanneer: var str:String = "Bob"; var bytes:ByteArray = new ByteArray(); bytes.writeUTFBytes(str); EncryptedLocalStore.setItem("firstName", bytes, true);
Voor een item dat is opgeslagen terwijl stronglyBound op true is ingesteld, zullen volgende oproepen van getItem() alleen slagen als de oproepende AIR-toepassing identiek is aan de opslaande toepassing (als er geen gegevens in bestanden in de toepassingsmap zijn gewijzigd). Als de oproepende AIR-toepassing niet identiek is aan de opslaande toepassing, genereert de toepassing een uitzonderingsfout wanneer u getItem() oproept voor een sterk gebonden item. Als u uw toepassing bijwerkt, kan deze geen sterk gebonden gegevens lezen die eerder in de gecodeerde lokale opslag zijn geschreven.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 221 Gecodeerde gegevens opslaan
Standaard kan een AIR-toepassing de gecodeerde lokale opslag van een andere toepassing niet lezen. Met de instelling stronglyBound zijn items extra sterk gebonden (aan de gegevens in de toepassingsbits) waardoor wordt voorkomen dat een schadelijke toepassing gegevens in de gecodeerde lokale opslag van uw toepassing kan lezen door de uitgeversid van uw toepassing te kapen. Als u een toepassing bijwerkt voor het gebruik van een ander handtekeningcertificaat (met een migratiehandtekening), heeft de bijgewerkte versie geen toegang tot de items in de oorspronkelijke opslag, zelfs niet als de parameter stronglyBound op false was ingesteld. Zie “Certificaten wijzigen” op pagina 332 voor meer informatie. U kunt een waarde uit de gecodeerde lokale opslag verwijderen met de methode EncryptedLocalStore.removeItem(), zoals in het volgende voorbeeld: EncryptedLocalStore.removeItem("firstName");
U kunt alle gegevens in de gecodeerde lokale opslag wissen door de methode EncryptedLocalStore.reset() op te roepen, zoals in het volgende voorbeeld: EncryptedLocalStore.reset();
Bij het opsporen van fouten in een toepassing in ADL (AIR Debug Launcher) gebruikt de toepassing een andere gecodeerde lokale opslag dan de opslag die wordt gebruikt in de geïnstalleerde versie van de toepassing. De gecodeerde lokale opslag kan langzamer werken als de opgeslagen hoeveelheid gegevens groter is dan 10 MB. Wanneer u een AIR-toepassing verwijdert, worden de gegevens die in de gecodeerde lokale opslag zijn opgeslagen, niet verwijderd. De gegevens van de gecodeerde lokale opslag worden in een submap van de map met toepassingsgegevens van de gebruiker geplaatst; het pad van deze submap is Adobe/AIR/ELS/ gevolgd door de toepassings-id.
222
Hoofdstuk 20: Informatie over de HTMLomgeving Adobe®AIR™ maakt gebruik van WebKit (www.webkit.org), dat ook wordt gebruikt door de webbrowser Safari, om HTML- en JavaScript-inhoud te parseren, in te delen en weer te geven. Het gebruik van de AIR API's in HTML-inhoud is optioneel. U kunt de inhoud van een HTMLLoader-object of HTML-venster geheel in HTML en JavaScript programmeren. De meeste bestaande HTML-pagina's en -toepassingen kunnen normaal gesproken met weinig wijzigingen worden uitgevoerd (mits ze gebruikmaken van HTML-, CSS-, DOM- en JavaScript-functies die compatibel zijn met WebKit). Aangezien AIR-toepassingen rechtstreeks op de desktopcomputer worden uitgevoerd, met volledige toegang tot het bestandssysteem, is het beveiligingsmodel voor HTML-inhoud strenger dan het beveiligingsmodel van een typische webbrowser. In AIR wordt alleen inhoud die wordt geladen uit de installatiemap van de toepassing geplaatst in de toepassingssandbox. De toepassingssandbox heeft het hoogste machtigingsniveau en biedt toegang tot de AIR API's. AIR plaatst andere inhoud in geïsoleerde sandboxen op basis van de locatie waar deze inhoud vandaan komt. Bestanden die zijn geladen uit het bestandssysteem, gaan naar een lokale sandbox. Bestanden die zijn geladen van het netwerk met behulp van het protocol http: of https:, gaan naar een sandbox op basis van het domein van de externe server. Inhoud in deze niet-toepassingssandboxen krijgt geen toegang tot AIR API's en wordt uitgevoerd op dezelfde manier als bij een normale webbrowser. AIR maakt gebruik van WebKit (www.webkit.org), dat ook wordt gebruikt door de webbrowser Safari, om HTML- en JavaScript-inhoud te parseren, in te delen en weer te geven. De ingebouwde hostklassen en -objecten van AIR bieden een API voor functies die traditioneel worden gekoppeld aan desktoptoepassingen. Het gaat hierbij bijvoorbeeld over het lezen en schrijven van bestanden en het beheer van vensters. Adobe AIR neemt ook de API's over van Adobe® Flash® Player. Het gaat hierbij bijvoorbeeld over functies als geluid en binaire sockets. HTML-inhoud in AIR geeft geen SWF- of PDF-inhoud weer wanneer alfa-, schaal- of transparantie-instellingen worden toegepast. Meer informatie kunt u vinden in Belangrijke opmerkingen voor het laden van SWF- of PDFinhoud in een HTML-pagina en “Venstertransparantie” op pagina 64.
Overzicht van de HTML-omgeving Adobe AIR biedt een volledige browserachtige JavaScript-omgeving met een HTML-renderer, documentobjectmodel en JavaScript-interpreter. De JavaScript-omgeving wordt vertegenwoordigd door de AIR-klasse HTMLLoader. In HTML-vensters bevat een HTMLLoader-object alle HTML-inhoud. Dit object bevindt zich op zijn beurt weer in een NativeWindow-object. In SWF-inhoud kan de klasse HTMLLoader, die een uitbreiding vormt van de klasse Sprite, worden toegevoegd aan de weergavelijst van een stage, net als ieder ander weergaveobject. De ActionScript™eigenschappen van de klasse worden beschreven in “Scripts schrijven voor de HTML-container” op pagina 264 en ook in Flex 3 ActionScript Language Reference.
Informatie over de JavaScript-omgeving en de relatie met AIR In het volgende diagram wordt de relatie geïllustreerd tussen de JavaScript-omgeving en de AIR-runtimeomgeving. Er wordt maar één native venster weergegeven. Een AIR-toepassing kan echter meerdere vensters bevatten. (En een venster kan meerdere HTMLLoader-objecten bevatten.)
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 223 Informatie over de HTML-omgeving
AIR-runtime-omgeving
NativeWindow
HTMLLoader venster JavaScriptomgeving venster
venster
hoofdtekst
htmlLoader
kop
native4Window
runtime h1
div
tabel
p
De JavaScript-omgeving heeft zijn eigen Document- en Window-objecten. JavaScript-code kan interageren met de AIR-runtimeomgeving via de eigenschappen runtime, nativeWindow en htmlLoader. ActionScript-code kan interageren met de JavaScript-omgeving via de eigenschap window van een HTMLLoader-object, dat een referentie vormt naar het JavaScript Window-object. Verder kunnen zowel ActionScript- als JavaScript-objecten luisteren naar gebeurtenissen die zijn verzonden door zowel AIR- als JavaScript-objecten.
De eigenschap runtime geeft toegang tot AIR API-klassen zodat u nieuwe AIR-objecten en ook toegangsklasseleden (statische leden) kunt maken. Als u een AIR API wilt openen, voegt u de naam van de klasse (met pakket) toe aan de eigenschap runtime. Als u bijvoorbeeld een File-object wilt maken, gebruikt u de volgende opdracht: var file = new window.runtime.filesystem.File();
Opmerking: De AIR SDK bevat een JavaScript-bestand, AIRAliases.js, waarin aanvullende handige aliassen voor de meestgebruikte AIR-klassen worden gedefinieerd. Als u dit bestand importeert, kunt u de korte vorm air.Class gebruiken in plaats van window.runtime.package.Class. U kunt bijvoorbeeld het File-object maken met new air.File(). Het NativeWindow-object bevat eigenschappen voor het beheer van het bureaubladvenster. Vanuit een HTMLpagina kunt u toegang krijgen tot het omvattende NativeWindow-object met behulp van de eigenschap window.nativeWindow. Het HTMLLoader-object bevat eigenschappen, methoden en gebeurtenissen voor het beheer van de manier waarop inhoud wordt geladen en weergegeven. Vanuit een HTML-pagina kunt u toegang krijgen tot het bovenliggende HTMLLoader-object met behulp van de eigenschap window.htmlLoader.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 224 Informatie over de HTML-omgeving
Belangrijk: Alleen pagina's die zijn geïnstalleerd als onderdeel van een toepassing, hebben de eigenschap htmlLoader, nativeWindow of runtime. Ze hebben deze eigenschappen alleen wanneer ze zijn geladen als document van het hoogste niveau. Deze eigenschappen worden niet toegevoegd wanneer een document wordt geladen in een frame of iframe. (Een onderliggend document kan toegang krijgen tot deze eigenschappen van het bovenliggende document, zolang het onderliggende document zich bevindt in dezelfde beveiligingssandbox. Een document dat bijvoorbeeld is geladen in een frame, kan toegang krijgen tot de eigenschap runtime van het bovenliggende document met behulp van parent.runtime.)
Informatie over beveiliging AIR voert alle code binnen een beveiligingssandbox uit op basis van het brondomein. Toepassingsinhoud, die beperkt is tot inhoud die is geladen uit de installatiemap van de toepassing, wordt geplaatst in de toepassingssandbox. Toegang tot de runtimeomgeving en de AIR API's is alleen beschikbaar voor HTML en JavaScript die worden uitgevoerd binnen deze sandbox. Tegelijkertijd wordt de meeste dynamische evaluatie en uitvoering van JavaScript geblokkeerd in de toepassingssandbox nadat alle handlers voor de paginagebeurtenis load zijn geretourneerd. U kunt een toepassingspagina toewijzen in een niet-toepassingssandbox door de pagina te laden in een frame of iframe en de AIR-specifieke kenmerken sandboxRoot en documentRoot van het frame in te stellen. Door de waarde sandboxRoot in te stellen op een werkelijk extern domein, kunt u de sandboxinhoud inschakelen zodat u inhoud in dat domein kunt cross-scripten. Het toewijzen van pagina's op deze manier kan nuttig zijn bij het laden en scripten van externe inhoud, bijvoorbeeld in een mash-up-toepassing. Een andere manier om toepassings- en niet-toepassingsinhoud in staat te stellen om elkaar te cross-scripten, en de enige manier om niet-toepassingsinhoud toegang te geven tot AIR API's, is het maken van een sandboxbridge. Een bovenliggende-onderliggende bridge maakt het mogelijk voor inhoud in een onderliggend frame, iframe of venster om toegang te krijgen tot speciaal aangewezen methoden en eigenschappen die zijn gedefinieerd in de toepassingssandbox. Een onderliggende-bovenliggende bridge daarentegen maakt het toepassingsinhoud mogelijk om toegang te krijgen tot bepaalde methoden en eigenschappen die zijn gedefinieerd in de sandbox van de onderliggende. Sandboxbridges worden gecreëerd door de eigenschappen parentSandboxBridge en childSandboxBridge van het Window-object in te stellen. Zie “Beveiliging in HTML” op pagina 31 en “Frame- en iframe-elementen in HTML” op pagina 232 voor meer informatie.
Informatie over invoegtoepassingen en ingesloten objecten AIR ondersteunt de invoegtoepassing Adobe ® Acrobat®. Gebruikers moeten beschikken over Acrobat of Adobe® Reader® 8.1 (of hoger) om PDF-inhoud te kunnen weergeven. Het HTMLLoader-object biedt een eigenschap waarmee kan worden gecontroleerd of het systeem van een gebruiker PDF kan weergeven. SWF-bestandsinhoud kan ook worden weergegeven binnen de HTML-omgeving. Deze functie is echter ingebouwd in AIR en maakt geen gebruik van een externe invoegtoepassing. Er worden geen andere Webkit-invoegtoepassingen ondersteund in AIR.
Zie ook “Beveiliging in HTML” op pagina 31 “Sandboxen in HTML” op pagina 225 “Frame- en iframe-elementen in HTML” op pagina 232 “JavaScript-object Window” op pagina 231 “XMLHttpRequest-objecten” op pagina 226 “PDF-inhoud toevoegen” op pagina 278
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 225 Informatie over de HTML-omgeving
AIR- en Webkit-extensies Adobe AIR maakt gebruik van de open source Webkit-engine, die ook wordt gebruikt in de webbrowser Safari. AIR voegt verschillende extensies toe waarmee toegang tot de runtimeklassen en -objecten mogelijk is. Deze extensies hebben ook een functie bij de beveiliging. Verder voegt Webkit zelf functies toe die niet zijn opgenomen in de W3Cstandaarden voor HTML, CSS en JavaScript. Alleen de AIR-toevoegingen en de belangrijkste Webkit-extensies worden hier behandeld. Documentatie over nietstandaard HTML, CSS en JavaScript vindt u in www.webkit.org en developer.apple.com. Informatie over standaarden vindt u op de W3C-website. Mozilla biedt ook een waardevolle algemene referentie over HTML-, CSS- en DOMonderwerpen (de Webkit-engine is niet identiek aan de Mozilla-engine). Opmerking: AIR ondersteunt niet de volgende standaard en uitgebreide WebKit-functies: de JavaScript Window objectmethode print(), invoegtoepassingen, behalve Acrobat of Adobe Reader 8.1+, SVG (Scalable Vector Graphics) en de CSS-eigenschap opacity.
JavaScript in AIR AIR brengt een aantal wijzigingen aan in het normale gedrag van veelgebruikte JavaScript-objecten. Veel van deze wijzigingen worden aangebracht om het gemakkelijker te maken veilige toepassingen in AIR te schrijven. Deze verschillen in gedrag betekenen echter ook dat bepaalde veelgebruikte JavaScript-coderingspatronen en bestaande webtoepassingen die gebruikmaken van die patronen, niet altijd zoals verwacht zullen worden uitgevoerd in AIR. Zie “JavaScript-beveiligingsfouten voorkomen” op pagina 240 voor meer informatie over het corrigeren van dit soort problemen.
Sandboxen in HTML AIR plaatst inhoud in geïsoleerde sandboxen afhankelijk van de oorsprong van de inhoud. De sandboxregels zijn consistent met het zelfde-oorsprongbeleid dat wordt geïmplementeerd door de meeste webbrowsers. Ze zijn ook consistent met de regels voor sandboxen die worden geïmplementeerd door Adobe Flash Player. Verder biedt AIR het nieuwe sandboxtype toepassing, waarmee toepassingsinhoud kan worden opgeslagen en beveiligd. Zie “Sandboxen” op pagina 28 voor meer informatie over de typen sandboxen die u kunt tegenkomen bij de ontwikkeling van AIRtoepassingen. Toegang tot de runtimeomgeving en de AIR API's is alleen beschikbaar voor HTML en JavaScript die worden uitgevoerd binnen de toepassingssandbox. Tegelijkertijd wordt dynamische evaluatie en uitvoering van de verschillende vormen van JavaScript uit veiligheidsoverwegingen voor een groot deel beperkt binnen de toepassingssandbox. Deze beperkingen gelden altijd, ongeacht of de toepassing rechtstreeks informatie van een server laadt. (Zelfs bestandsinhoud, geplakte tekenreeksen en gegevens die rechtstreeks door de gebruiker worden ingevoerd, kunnen onbetrouwbaar zijn.) De oorsprong van de inhoud in een pagina bepaalt de sandbox waaraan deze wordt toegewezen. Alleen inhoud die is geladen vanuit de toepassingsmap (de installatiemap waarnaar wordt verwezen door het URL-schema app:) wordt in de toepassingssandbox geplaatst. Inhoud die wordt geladen vanuit het bestandssysteem, wordt in de lokaal-metbestandssysteem of lokaal-vertrouwde sandbox geplaatst, waarmee toegang tot en interactie met het lokale bestandssysteem mogelijk is, maar niet met externe inhoud. Inhoud die wordt geladen vanaf het netwerk, wordt in een externe sandbox geplaatst die correspondeert met het brondomein.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 226 Informatie over de HTML-omgeving
Als een toepassingspagina toestemming moet hebben om desgewenst te interageren met inhoud in een externe sandbox, kan die pagina worden toegewezen aan hetzelfde domein als de externe inhoud. Als u bijvoorbeeld een toepassing schrijft waarin kaartgegevens uit een internetservice worden weergegeven, kan de pagina van deze toepassing waarin inhoud van de service wordt geladen en weergegeven, worden toegewezen aan het servicedomein. De kenmerken voor het toewijzen van pagina's aan externe sandboxen en domeinen zijn nieuwe kenmerken die worden toegevoegd aan de frame- en iframe-elementen in HTML. Als u inhoud in een niet-toepassingssandbox wilt toestaan om veilig AIR-functies te gebruiken, kunt u een bovenliggende sandboxbridge instellen. Als u toepassingsinhoud wilt toestaan om veilig methoden en toegangseigenschappen van inhoud in andere sandboxen te benaderen, kunt u een onderliggende sandboxbridge instellen. Veilig betekent hier dat externe inhoud niet per ongeluk verwijzingen kan ophalen naar objecten, eigenschappen of methoden die niet expliciet beschikbaar zijn gemaakt. Alleen eenvoudige gegevenstypen, functies en anonieme objecten kunnen via de bridge worden doorgegeven. U moet echter nog steeds voorkomen dat potentieel gevaarlijke functies expliciet beschikbaar worden gemaakt. Als u bijvoorbeeld een interface beschikbaar hebt gemaakt waarmee externe inhoud bestanden op iedere willekeurige locatie in het systeem van een gebruiker kan lezen en schrijven, biedt u externe inhoud mogelijk kans om uw gebruikers grote schade te berokkenen.
De JavaScript-functie eval() Het gebruik van de functie eval() is beperkt binnen de toepassingssandbox als een pagina eenmaal is geladen. Sommige vormen van gebruik zijn toegestaan, zodat gegevens met JSON-indeling veilig kunnen worden geparseerd. Een evaluatie die uitvoerbare instructies als gevolg heeft, resulteert echter altijd in een fout. “Codebeperkingen voor de inhoud van verschillende sandboxen” op pagina 33 beschrijft het toegestane gebruik van de functie eval().
Functieconstructors In de toepassingssandbox kunnen functieconstructors worden gebruikt voordat een pagina geheel is geladen. Nadat alle handlers voor de paginagebeurtenis load zijn voltooid, kunnen geen nieuwe functies meer worden gemaakt.
Externe scripts laden HTML-pagina's in de toepassingssandbox kunnen geen scripttags gebruiken om JavaScript-bestanden te laden van buiten de toepassingsmap. Als een pagina in uw toepassing een script van buiten de toepassingsmap moet laden, moet die pagina worden toegewezen aan een niet-toepassingssandbox.
XMLHttpRequest-objecten AIR is voorzien van een XHR-object (XMLHttpRequest), waarmee toepassingen gegevens kunnen aanvragen. In het volgende voorbeeld ziet u een eenvoudige gegevensaanvraag: xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "http:/www.example.com/file.data", true); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) { //do something with data... } } xmlhttp.send(null);
In tegenstelling tot een browser is het bij AIR mogelijk dat inhoud die wordt uitgevoerd in de toepassingssandbox, gegevens uit elk willekeurig domein aanvraagt. Het resultaat van een XHR die een JSON-tekenreeks bevat, kan worden geëvalueerd in gegevensobjecten, behalve als het resultaat ook uitvoerbare code bevat. Als het XHR-resultaat ook uitvoerbare instructies bevat, treedt er een fout op en mislukt de evaluatiepoging.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 227 Informatie over de HTML-omgeving
Om te voorkomen dat code uit externe bronnen per ongeluk wordt ingebracht, retourneren synchrone XHR's een leeg resultaat als ze zijn gemaakt voordat een pagina geheel is geladen. Asynchrone XHR's worden altijd geretourneerd nadat een pagina is geladen. AIR blokkeert standaard domeinoverschrijdende XMLHttpRequests in niet-toepassingssandboxen. Een bovenliggend venster in de toepassingssandbox kan ervoor kiezen domeinoverschrijdende aanvragen in een onderliggend frame dat inhoud in een niet-toepassingssandbox bevat, toe te staan door het kenmerk allowCrossDomainXHR, dat wordt toegevoegd door AIR, in te stellen op true in het omvattende frame- of iframe-element: <iframe id="mashup" src="http://www.example.com/map.html" allowCrossDomainXHR="true"
Opmerking: Desgewenst kan de AIR-klasse URLStream ook worden gebruikt om gegevens te downloaden. Als u een XMLHttpRequest naar een externe server stuurt vanuit een frame of iframe dat toepassingsinhoud bevat die is toegewezen aan een externe sandbox, moet u ervoor zorgen dat de toewijzende URL het serveradres dat in de XHR wordt gebruikt, niet maskeert. Bekijk bijvoorbeeld de volgende iframe-definitie, die toepassingsinhoud toewijst in een externe sandbox voor het domein example.com: <iframe id="mashup" src="http://www.example.com/map.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/" allowCrossDomainXHR="true"
Omdat het kenmerk sandboxRoot de basis-URL van het adres www.example.com opnieuw toewijst, worden alle aanvragen geladen vanuit de toepassingsmap en niet vanaf de externe server. Aanvragen worden altijd opnieuw toegewezen, ongeacht of ze afkomstig zijn van paginanavigatie of een XMLHttpRequest. Om te voorkomen dat gegevensaanvragen naar de externe server per ongeluk worden geblokkeerd, wijst u sandboxRoot toe aan een submap van de externe URL en niet aan de hoofdmap. Die map hoeft niet echt te bestaan.
Als u bijvoorbeeld wilt toestaan dat aanvragen naar www.example.com gegevens laden vanaf de externe server en niet uit de toepassingsmap, verandert u het vorige iframe-element in de volgende: <iframe id="mashup" src="http://www.example.com/map.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/" allowCrossDomainXHR="true"
In dit geval wordt alleen de inhoud van de submap air lokaal geladen. Zie “Frame- en iframe-elementen in HTML” op pagina 232 en “Beveiliging in HTML” op pagina 31 voor meer informatie over de toewijzing van sandboxen.
Canvas-objecten Het Canvas-object definieert een API voor het tekenen van geometrische vormen zoals lijnen, bogen, ellipsen en veelhoeken. Als u de API voor Canvas wilt gebruiken, voegt u eerst een Canvas-element toe aan het document en tekent u daar vervolgens in met behulp van de JavaScript-API voor Canvas. In de meeste andere opzichten gedraagt het Canvas-object zich als een afbeelding. In het volgende voorbeeld ziet u hoe u een driehoek tekent met behulp van een Canvas-object:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 228 Informatie over de HTML-omgeving
Zie de Safari JavaScript Reference van Apple voor meer informatie over de API voor Canvas. Het Webkit-project is onlangs begonnen met het aanpassen van de API voor Canvas ten einde deze te standaardiseren volgens de HTML 5 Working Draft die is voorgesteld door WHATWG (Web Hypertext Application Technology Working Group) en W3C. Als gevolg daarvan kan een deel van de documentatie in de Safari JavaScript Reference inconsistent zijn met de Canvas-versie die wordt gepresenteerd in AIR.
Cookies In AIR-toepassingen kan alleen inhoud in externe sandboxen (inhoud die is geladen vanaf bronnen van het type http: en https:) gebruikmaken van cookies (de eigenschap document.cookie). In de toepassingssandbox bieden AIR API's andere manieren om permanente gegevens op te slaan (zoals de klassen EncryptedLocalStore en FileStream).
Clipboard-objecten De WebKit-API voor Clipboard wordt aangestuurd door de volgende gebeurtenissen: copy, cut en paste. Het gebeurtenisobject dat bij deze gebeurtenissen wordt doorgegeven, geeft via de eigenschap clipboardData toegang tot het klembord. Gebruik de volgende methoden van het object clipboardData om klembordgegevens te lezen of te schrijven: Methode
Beschrijving
clearData(mimeType)
Hiermee wist u de klembordgegevens. Stel de parameter mimeType in op het MIME-type van de gegevens die u wilt wissen.
getData(mimeType)
Hiermee haalt u de klembordgegevens op. Deze methode kan alleen worden opgeroepen in een handler voor de gebeurtenis paste. Stel de parameter mimeType in op het MIME-type van de gegevens die u wilt retourneren.
setData(mimeType, data)
Hiermee kopieert u gegevens naar het klembord. Stel de parameter mimeType in op het MIME-type van de gegevens.
JavaScript-code buiten de toepassingssandbox kan alleen via deze gebeurtenissen toegang krijgen tot het klembord. Inhoud in de toepassingssandbox kan echter rechtstreeks toegang krijgen tot het systeemklembord via de AIR-klasse Clipboard. U kunt bijvoorbeeld de volgende opdracht gebruiken om gegevens over tekstopmaak op het klembord te krijgen: var clipping = air.Clipboard.generalClipboard.getData("text/plain", air.ClipboardTransferMode.ORIGINAL_ONLY);
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 229 Informatie over de HTML-omgeving
De volgende MIME-typen zijn geldig voor gegevens: MIME-type
Waarde
Tekst
"text/plain"
HTML
"text/html"
URL
"text/uri-list"
Bitmap
"image/x-vnd.adobe.air.bitmap"
Bestandenlijst
"application/x-vnd.adobe.air.file-list"
Belangrijk: Alleen inhoud in de toepassingssandbox kan toegang krijgen tot bestandsgegevens die aanwezig zijn op het klembord. Als niet-toepassingsinhoud probeert toegang te krijgen tot een bestandsobject vanaf het klembord, wordt een beveiligingsfout veroorzaakt. Zie “kopiëren en plakken” op pagina 153 en Using the Pasteboard from JavaScript (Apple Developer Center) voor meer informatie over het gebruik van het klembord.
Slepen en neerzetten: Het slepen en neerzetten in en uit HTML produceert de volgende DOM-gebeurtenissen: dragstart, drag, dragend, dragenter, dragover, dragleave en drop. Het gebeurtenisobject dat bij deze gebeurtenissen wordt doorgegeven, geeft via de eigenschap dataTransfer toegang tot de gesleepte gegevens. De eigenschap dataTransfer verwijst naar een object dat dezelfde methoden biedt als het clipboardData-object dat is gekoppeld aan een gebeurtenis van het type clipboard. U kunt bijvoorbeeld de volgende functie gebruiken om tekstopmaakgegevens van de gebeurtenis drop te krijgen: function onDrop(dragEvent){ return dragEvent.dataTransfer.getData("text/plain", air.ClipboardTransferMode.ORIGINAL_ONLY); }
Het dataTransfer-object heeft de volgende belangrijke leden: Lid
Beschrijving
clearData(mimeType)
Hiermee wist u de gegevens. Stel de parameter mimeType in op het MIME-type van de gegevensrepresentatie die u wilt wissen.
getData(mimeType)
Hiermee haalt u de gesleepte gegevens op. Deze methode kan alleen worden opgeroepen in een handler voor de gebeurtenis drop. Stel de parameter mimeType in op het MIME-type van de gegevens die u wilt ophalen.
setData(mimeType, data)
Hiermee stelt u de gegevens in die moeten worden gesleept. Stel de parameter mimeType in op het MIMEtype van de gegevens.
types
Een array van tekenreeksen die de MIME-typen bevat van alle gegevensrepresentaties die nu beschikbaar zijn in het dataTransfer-object.
effectsAllowed
Hiermee geeft u aan of de gesleepte gegevens kunnen worden gekopieerd, verplaatst, gekoppeld of een combinatie daarvan. Stel de eigenschap effectsAllowed in de handler voor de gebeurtenis dragstart in.
dropEffect
Hiermee geeft u aan welke van de toegestane neerzeteffecten (drop) worden ondersteund door een sleepdoel (drag). Stel de eigenschap dropEffect in de handler voor de gebeurtenis dragEnter in. Tijdens het slepen verandert de cursor van vorm. Deze geeft aan wat voor effect er zou optreden als de gebruiker de muis loslaat. Als er geen dropEffect is opgegeven, wordt een eigenschapseffect uit effectsAllowed gekozen. Het kopieereffect (copy) heeft prioriteit over het verplaatsingseffect (move), en dat heeft weer prioriteit over het koppelingseffect (link). De gebruiker kan de standaardprioriteit wijzigen met behulp van het toetsenbord.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 230 Informatie over de HTML-omgeving
Zie “Slepen en neerzetten” op pagina 137 en Using the Drag-and-Drop from JavaScript (Apple Developer Center) voor meer informatie over het toevoegen van ondersteuning voor slepen en neerzetten aan een AIR-toepassing.
De eigenschappen innerHTML en outerHTML AIR stelt beveiligingsbeperkingen in voor het gebruik van de eigenschappen innerHTML en outerHTML voor het uitvoeren van inhoud in de toepassingssandbox. Voordat de paginagebeurtenis load optreedt en terwijl eventuele gebeurtenishandlers voor load worden uitgevoerd, gelden er geen beperkingen voor het gebruik van de eigenschappen innerHTML en outerHTML. Als de pagina echter is geladen, kunt u de eigenschap innerHTML of outerHTML alleen gebruiken om statische inhoud toe te voegen aan het document. Eventuele opdrachten die zich bevinden in de tekenreeks die is toegewezen aan innerHTML of outerHTML en die worden geëvalueerd naar uitvoerbare code, worden genegeerd. Als u bijvoorbeeld een kenmerk om een gebeurtenis terug te roepen (callback) opneemt in een elementdefinitie, wordt de gebeurtenislistener niet toegevoegd. Op dezelfde manier worden ingesloten tags van het type <script> niet geëvalueerd. Zie “Beveiliging in HTML” op pagina 31 voor meer informatie.
De methoden Document.write() en Document.writeln() Het gebruik van de methoden write()en writeln() is niet beperkt in de toepassingssandbox vóór de paginagebeurtenis load. Als de pagina echter is geladen, wordt bij het oproepen van een van deze methoden de pagina niet gewist en wordt er ook geen nieuwe pagina gemaakt. In een niet-toepassingssandbox wordt, net zoals bij de meeste webbrowsers, door het oproepen van document.write() of writeln() nadat een pagina geheel is geladen, de huidige pagina gewist en wordt een nieuwe lege pagina geopend.
De eigenschap Document.designMode Hiermee stelt u de eigenschap document.designMode in op de waarde on als u alle elementen in het document bewerkbaar wilt maken. Met de ingebouwde editor kunt u tekst bewerken, kopiëren, plakken, slepen en neerzetten. Het instellen van designMode op on is equivalent met het instellen van de eigenschap contentEditable van het element body op true. U kunt de eigenschap contentEditable voor de meeste HTML-elementen gebruiken om te definiëren welke secties van een document kunnen worden bewerkt. Zie “Het HTML-kenmerk contentEditable” op pagina 235 voor meer informatie.
unload-gebeurtenissen (voor body- en frameset-objecten) In de tag frameset of body van het bovenste niveau van een venster (inclusief het hoofdvenster van de toepassing), mag u de gebeurtenis unload niet gebruiken om te reageren op het venster dat of de toepassing die wordt gesloten. In plaats daarvan gebruikt u de gebeurtenis exiting van het NativeApplication-object (om te bepalen wanneer een toepassing wordt gesloten). U kunt ook de gebeurtenis closing van het NativeApplication-object gebruiken (om te bepalen wanneer een toepassing wordt gesloten). De volgende JavaScript-code geeft bijvoorbeeld het bericht "Goodbye" weer wanneer de gebruiker de toepassing sluit: var app = air.NativeApplication.nativeApplication; app.addEventListener(air.Event.EXITING, closeHandler); function closeHandler(event) { alert("Goodbye."); }
Scripts kunnen echter wel succesvol reageren op de gebeurtenis unload die wordt veroorzaakt door navigatie van een frame, iframe of vensterinhoud van het bovenste niveau. Opmerking: In een volgende versie van Adobe AIR worden deze beperkingen mogelijk verwijderd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 231 Informatie over de HTML-omgeving
JavaScript-object Window Het Window-object blijft het globale object binnen de JavaScript-uitvoeringscontext. In de toepassingssandbox voegt AIR nieuwe eigenschappen toe aan het JavaScript-object Window ten einde toegang te geven tot de ingebouwde AIRklassen en belangrijke hostobjecten. Verder vertonen bepaalde methoden en eigenschappen binnen de toepassingssandbox ander gedrag dan daarbuiten. De eigenschap Window.runtime De eigenschap runtime stelt u in staat om de ingebouwde runtimeklassen te
instantiëren en te gebruiken vanuit de toepassingssandbox. Deze klassen omvatten de AIR- en Flash Player-API's (maar bijvoorbeeld niet het Flex-framework). Met de volgende opdracht maakt u bijvoorbeeld een AIRbestandsobject: var preferencesFile = new window.runtime.flash.filesystem.File();
Het bestand AIRAliases.js, dat zich bevindt in de AIR SDK, bevat aliasdefinities waarmee u dergelijke verwijzingen kunt verkorten. Als AIRAliases.js bijvoorbeeld in een pagina wordt geïmporteerd, kan een File-object worden gemaakt met de volgende opdracht: var preferencesFile = new air.File();
De eigenschap window.runtime is alleen gedefinieerd voor inhoud binnen de toepassingssandbox en alleen voor het bovenliggende document van een pagina met frames of iframes. Zie “Het bestand AIRAliases.js gebruiken” op pagina 244. De eigenschap Window.nativeWindow De eigenschap nativeWindow biedt een verwijzing naar het onderliggende
native Window-object. Met deze eigenschap kunt u vensterfuncties en eigenschappen zoals schermpositie, grootte en zichtbaarheid in een script opnemen. Ook kunt u venstergebeurtenissen zoals sluiten, grootte wijzigen en verplaatsen hiermee verwerken. Met de volgende opdracht sluit u bijvoorbeeld het venster: window.nativeWindow.close();
Opmerking: De functies voor vensterbesturing die worden geboden door het NativeWindow-object, overlappen de functies die worden geboden door het JavaScript-object Window. In dergelijke gevallen kunt u de methode gebruiken die u het handigst vindt. De eigenschap window.nativeWindow is alleen gedefinieerd voor inhoud binnen de toepassingssandbox en alleen voor het bovenliggende document van een pagina met frames of iframes. De eigenschap Window.htmlLoader De eigenschap htmlLoader biedt een referentie voor het AIR-object
HTMLLoader dat de HTML-inhoud bevat. Met deze eigenschap kunt u het uiterlijk en het gedrag van de HTMLomgeving in een script opnemen. U kunt bijvoorbeeld de eigenschap htmlLoader.paintsDefaultBackground gebruiken om te bepalen of het besturingselement een standaard witte achtergrond gebruikt: window.htmlLoader.paintsDefaultBackground = false;
Opmerking: Het HTMLLoader-object zelf heeft een eigenschap window die verwijst naar het JavaScript-object Window van de HTML-inhoud die het bevat. U kunt deze eigenschap gebruiken om toegang te krijgen tot de JavaScript-omgeving via een verwijzing naar de bevattende HTMLLoader. De eigenschap window.htmlLoader is alleen gedefinieerd voor inhoud binnen de toepassingssandbox en alleen voor het bovenliggende document van een pagina met frames of iframes. De eigenschappen Window.parentSandboxBridge en Window.childSandboxBridge Met de eigenschappen parentSandboxBridge en childSandboxBridge kunt u een interface definiëren tussen een bovenliggend en een onderliggend frame. Zie “Cross-scripting van inhoud in verschillende beveiligingssandboxen” op pagina 253 voor meer informatie.
De functies Window.setTimeout() en Window.setInterval() AIR past beveiligingsbeperkingen toe op het gebruik van
de functies setTimeout() en setInterval() binnen de toepassingssandbox. U kunt de code die moet worden
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 232 Informatie over de HTML-omgeving
uitgevoerd, niet definiëren als tekenreeks bij het oproepen van setTimeout() of setInterval(). U moet hiervoor een functieverwijzing gebruiken. Zie “setTimeout() en setInterval()” op pagina 242 voor meer informatie. De functie Window.open() Wanneer de methode open() wordt opgeroepen door code die wordt uitgevoerd in een niet-toepassingssandbox, wordt er als gevolg van gebruikersinteractie (bijvoorbeeld een muisklik of het indrukken van een toets) alleen een venster geopend. Verder staat de toepassingstitel vóór de venstertitel (om te verhinderen dat vensters die worden geopend door externe inhoud, zich voordoen als vensters die worden geopend door de toepassing). Zie “Beperkingen betreffende het oproepen van de JavaScript-methode window.open()” op pagina 36 voor meer informatie.
Het object air.NativeApplication Het NativeApplication-object biedt informatie over de toepassingsstatus, verzendt verschillende belangrijke gebeurtenissen op toepassingsniveau en biedt nuttige functies voor het beheer van het gedrag van de toepassing. Er wordt automatisch één instantie van het NativeApplication-object gemaakt. Deze kan worden benaderd via de door de klasse gedefinieerde eigenschap NativeApplication.nativeApplication. Om vanuit JavaScript-code toegang te krijgen tot het object, kunt u het volgende gebruiken: var app = window.runtime.flash.desktop.NativeApplication.nativeApplication;
Als het script AIRAliases.js is geïmporteerd, kunt u ook de kortere vorm gebruiken: var app = air.NativeApplication.nativeApplication;
U kunt het NativeApplication-object alleen benaderen vanuit de toepassingssandbox. Interactie met het besturingssysteem: “Werken met runtime- en besturingssysteeminformatie” op pagina 306 beschrijft het NativeApplication-object in detail.
Het JavaScript URL-schema Uitvoering van code die is gedefinieerd in een JavaScript URL-schema (zoals in href="javascript:alert('Test')"), wordt geblokkeerd binnen de toepassingssandbox. Er treedt geen fout op.
Extensies voor HTML AIR en WebKit definiëren een aantal niet-standaard HTML-elementen en -kenmerken, zoals: “Frame- en iframe-elementen in HTML” op pagina 232 “Het HTML-element Canvas” op pagina 234 “Gebeurtenishandlers voor HTML-elementen” op pagina 235
Frame- en iframe-elementen in HTML AIR voegt nieuwe kenmerken toe aan de frame- en iframe-elementen van inhoud in de toepassingssandbox: Het kenmerk sandboxRoot Het kenmerk sandboxRoot geeft een alternatief, niet-toepassingsbrondomein op voor het
bestand dat wordt opgegeven door het framekenmerk src. Het bestand wordt geladen in de niet-toepassingssandbox die correspondeert met het opgegeven domein. Inhoud in het bestand en inhoud die wordt geladen van het opgegeven domein, kan onderling cross-scripten. Belangrijk: Als u de waarde van sandboxRoot instelt op de basis-URL van het domein, worden alle aanvragen voor inhoud van dat domein geladen uit de toepassingsmap en niet vanaf de externe server (of die aanvraag nu resulteert uit paginanavigatie, uit een XMLHttpRequest of uit een andere manier om inhoud te laden).
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 233 Informatie over de HTML-omgeving
Het kenmerk documentRoot Het kenmerk documentRoot geeft de lokale map op waaruit URL's moeten worden
geladen die worden omgezet in bestanden in de locatie die wordt opgegeven door sandboxRoot. Bij het omzetten van URL's, of dit nu gebeurt bij het framekenmerk src dan wel in inhoud die in het frame wordt geladen, wordt het deel van de URL dat overeenkomt met de waarde die wordt opgegeven in sandboxRoot, vervangen door de waarde die wordt opgegeven in documentRoot. Bij de volgende frametag geldt dus: <iframe src="http://www.example.com/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/"/> child.html wordt geladen uit de submap sandbox van de toepassingsinstallatiemap. Relatieve URL's in child.html
worden omgezet op basis van de map sandbox. Merk op dat bestanden op de externe server op www.example.com/airniet toegankelijk zijn in het frame, omdat AIR zou proberen ze te laden uit de map
app:/sandbox/. Het kenmerk allowCrossDomainXHR Neem de code allowCrossDomainXHR="allowCrossDomainXHR" op in de
openingsframetag als u wilt toestaan dat inhoud in het frame XMLHttpRequests uitvoert naar een willekeurig extern domein. Standaard kan niet-toepassingsinhoud dergelijke aanvragen alleen uitvoeren binnen het eigen brondomein. Het toestaan van XHR's naar andere domeinen heeft ernstige gevolgen voor de beveiliging. Code in de pagina kan gegevens uitwisselen met een willekeurig domein. Als er op de een of andere manier kwaadaardige inhoud in de pagina wordt ingebracht, kunnen alle gegevens die toegankelijk zijn voor code in de huidige sandbox, worden aangetast. Schakel alleen XHR's die andere domeinen kunnen bereiken in voor pagina's die u zelf maakt en beheert, en alleen als het laden van gegevens uit andere domeinen absoluut noodzakelijk is. Ook moet u alle externe gegevens die door de pagina worden geladen zorgvuldig valideren om te voorkomen dat code wordt ingebracht of dat andere aanvallen worden uitgevoerd. Belangrijk: Als het kenmerk allowCrossDomainXHR is opgenomen in een frame- of iframe-element, zijn XHR's naar andere domeinen ingeschakeld (behalve als de toegewezen waarde "0" is of begint met de letter "f" of "n"). Als u bijvoorbeeld allowCrossDomainXHR instelt op "deny" (weigeren), zijn XHR's naar andere domeinen nog steeds toegestaan. Laat het kenmerk helemaal weg uit de elementdeclaratie als u aanvragen naar andere domeinen niet wilt inschakelen. ondominitialize, kenmerk Geeft een gebeurtenishandler op voor de framegebeurtenis dominitialize. Dit is een
AIR-specifieke gebeurtenis die wordt geactiveerd wanneer de window- en document-objecten van het frame zijn gemaakt, maar voordat er scripts zijn geparseerd of documentelementen zijn gemaakt. Het frame verzendt de gebeurtenis dominitialize zo vroeg tijdens de uitvoering van de laadsequentie, dat eventuele scripts in de onderliggende pagina kunnen verwijzen naar objecten, variabelen en functies die door de handler dominitialize zijn toegevoegd aan het onderliggende document. De bovenliggende pagina kan alleen rechtstreeks objecten toevoegen aan of toegang krijgen tot objecten in een onderliggend document, als de bovenliggende pagina zich bevindt in dezelfde sandbox als de onderliggende. Een bovenliggende pagina in de toepassingssandbox kan echter wel een sandboxbridge tot stand brengen voor communicatie met inhoud in een niet-toepassingssandbox. In de volgende voorbeelden ziet u hoe u de iframe-tag in AIR gebruikt: Plaats child.html in een externe sandbox zonder toewijzing aan een werkelijk domein op een externe server: <iframe src="http://localhost/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://localhost/air/"/>
Plaats child.html in een externe sandbox, waarbij XMLHttpRequests alleen zijn toegestaan voor www.example.com: <iframe src="http://www.example.com/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/"/>
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 234 Informatie over de HTML-omgeving
Plaats child.html in een externe sandbox, waarbij XMLHttpRequests zijn toegestaan voor een willekeurig extern domein: <iframe src="http://www.example.com/air/child.html" documentRoot="app:/sandbox/" sandboxRoot="http://www.example.com/air/" allowCrossDomainXHR="allowCrossDomainXHR"/>
Plaats child.html in een lokaal-met-bestandssysteem sandbox: <iframe
Plaats child.html in een externe sandbox waarbij de gebeurtenis dominitialize wordt gebruikt om een sandboxbridge tot stand te brengen. <script> var bridgeInterface = {}; bridgeInterface.testProperty = "Bridge engaged"; function engageBridge(){ document.getElementById("sandbox").parentSandboxBridge = bridgeInterface; } <iframe id="sandbox" src="http://www.example.com/air/child.html" documentRoot="app:/" sandboxRoot="http://www.example.com/air/" ondominitialize="engageBridge()"/>
Het volgende document, child.html, illustreert hoe onderliggende inhoud de bovenliggende sandboxbridge kan benaderen: <script> document.write(window.parentSandboxBridge.testProperty);
Zie “Cross-scripting van inhoud in verschillende beveiligingssandboxen” op pagina 253 en “Beveiliging in HTML” op pagina 31 voor meer informatie.
Het HTML-element Canvas Hiermee definieert u een tekengebied voor gebruik met de Webkit-API voor Canvas. Opdrachten met betrekking tot afbeeldingen kunnen niet worden opgegeven in de tag zelf. Als u op het canvas wilt tekenen, roept u de canvastekenmethoden aan via JavaScript.
Zie “Canvas-objecten” op pagina 227 voor meer informatie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 235 Informatie over de HTML-omgeving
Gebeurtenishandlers voor HTML-elementen DOM-objecten in AIR en Webkit verzenden bepaalde gebeurtenissen die niet aanwezig zijn in het standaard DOMgebeurtenismodel. In de volgende tabel worden de verwante gebeurteniskenmerken aangegeven die u kunt gebruiken om handlers voor deze gebeurtenissen op te geven: Naam callbackkenmerk
Beschrijving
oncontextmenu
Wordt opgeroepen wanneer een contextmenu wordt opgeroepen, bijvoorbeeld door met de rechtermuisknop op geselecteerde tekst te klikken of de Command-toets ingedrukt te houden tijdens het klikken.
oncopy
Wordt opgeroepen wanneer een selectie in een element wordt gekopieerd.
oncut
Wordt opgeroepen wanneer een selectie in een element wordt geknipt.
ondominitialize
Wordt opgeroepen wanneer het DOM wordt gemaakt van een document dat is geladen in een frame of iframe, maar voordat eventuele DOM-elementen worden gemaakt of scripts geparseerd.
ondrag
Wordt opgeroepen wanneer een element wordt gesleept.
ondragend
Wordt opgeroepen wanneer een gesleept element wordt losgelaten.
ondragenter
Wordt opgeroepen wanneer een sleepbeweging de grenzen van een element bereikt.
ondragleave
Wordt opgeroepen wanneer een sleepbeweging de grenzen van een element verlaat.
ondragover
Wordt continu opgeroepen zolang een sleepbeweging zich binnen de grenzen van een element bevindt.
ondragstart
Wordt opgeroepen wanneer een sleepbeweging begint.
ondrop
Wordt opgeroepen wanneer een sleepbeweging wordt losgelaten boven een element.
onerror
Wordt opgeroepen wanneer er een fout optreedt bij het laden van een element.
oninput
Wordt opgeroepen wanneer er tekst wordt ingevoerd in een formulierelement.
onpaste
Wordt opgeroepen wanneer een item wordt geplakt in een element.
onscroll
Wordt opgeroepen wanneer de inhoud van een schuifbaar element wordt geschoven.
onsearch
Wordt opgeroepen wanneer een element wordt gekopieerd (? Apple docs correct ?)
onselectstart
Wordt opgeroepen wanneer een selectie begint.
Het HTML-kenmerk contentEditable U kunt het kenmerk contentEditable aan een willekeurig HTML-element toevoegen om gebruikers toe te staan de inhoud van het element te bewerken. Met de volgende HTML-voorbeeldcode wordt het gehele document ingesteld als bewerkbaar, behalve het eerste p-element:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 236 Informatie over de HTML-omgeving
de Finibus Bonorum et Malorum
Sed ut perspiciatis unde omnis iste natus error.
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis.
Opmerking: Als u de eigenschap document.designMode instelt op on, zijn alle elementen in het document bewerkbaar, ongeacht de instelling van contentEditable voor een individueel element. Als u echter designModeinstelt op off, kunnen elementen waarvoor contentEditable is ingesteld op true, nog steeds worden bewerkt. Zie “De eigenschap Document.designMode” op pagina 230 voor meer informatie.
Extensies voor CSS WebKit ondersteunt verschillende uitgebreide CSS-eigenschappen. In de volgende tabel worden de uitgebreide eigenschappen aangegeven die worden ondersteund. Aanvullende niet-standaardeigenschappen zijn beschikbaar in WebKit maar worden niet volledig ondersteund in AIR omdat ze in WebKit nog worden ontwikkeld of omdat het experimentele functies zijn die mogelijk in de toekomst worden verwijderd. Naam CSS-eigenschap
Waarden
Beschrijving
-webkit-border-horizontal-spacing
Niet-negatieve lengte-eenheid
Geeft de horizontale component van de randafstand op.
-webkit-border-vertical-spacing
Niet-negatieve lengte-eenheid
Geeft de verticale component van de randafstand op.
-webkit-line-break
after-white-space, normal
Geeft de regel voor het afbreken van tekst op die moet worden gebruikt voor CJKtekst (Chinees, Japans en Koreaans).
-webkit-margin-bottom-collapse
collapse, discard, separate
Bepaalt hoe de ondermarge van een tabelcel wordt samengevouwen.
-webkit-margin-collapse
collapse, discard, separate
Bepaalt hoe de boven- en ondermarge van een tabelcel worden samengevouwen.
-webkit-margin-start
Een willekeurige lengte-eenheid.
De breedte van de beginmarge. Voor tekst die van links naar rechts wordt geschreven, overschrijft deze eigenschap de linkermarge. Voor tekst die van rechts naar links wordt geschreven, overschrijft deze eigenschap de rechtermarge.
-webkit-margin-top-collapse
collapse, discard, separate
Bepaalt hoe de bovenmarge van een tabelcel wordt samengevouwen.
-webkit-nbsp-mode
normal, space
Bepaalt het gedrag van vaste spaties binnen de ingesloten inhoud.
-webkit-padding-start
Een willekeurige lengte-eenheid.
Geeft aan met welke breedte de opvulling moet worden gestart. Voor tekst die van links naar rechts wordt geschreven, overschrijft deze eigenschap de linkeropvulling. Voor tekst die van rechts naar links wordt geschreven, overschrijft deze eigenschap de rechteropvulling.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 237 Informatie over de HTML-omgeving
Naam CSS-eigenschap
Waarden
Beschrijving
-webkit-rtl-ordering
logical, visual
Overschrijft de standaardverwerking van tekst die gedeeltelijk van links naar rechts en gedeeltelijk van rechts naar links wordt geschreven.
-webkit-text-fill-color
Een willekeurige benoemde kleur of numerieke kleurwaarde
Geeft de tekstvulkleur op.
-webkit-text-security
circle, disc, none, square
Geeft de vervangende vorm op die moet worden gebruikt in een invoerveld voor wachtwoorden.
-webkit-user-drag
•
auto - standaardgedrag
Overschrijft het gedrag dat automatisch wordt toegepast bij slepen.
•
element - het gehele element wordt gesleept
•
none - het element kan niet worden gesleept
-webkit-user-modify
read-only, read-write, read-writeplaintext-only
Geeft aan of de inhoud van een element kan worden bewerkt.
-webkit-user-select
•
auto - standaardgedrag
Geeft aan of een gebruiker de inhoud van een element kan selecteren.
•
none - het element kan niet worden geselecteerd
•
text - alleen tekst in het element kan worden geselecteerd
Zie de handleiding Apple Safari CSS Reference (http://developer.apple.com/documentation/AppleApplications/Reference/SafariCSSRef/) voor meer informatie.
238
Hoofdstuk 21: Programmeren in HTML en JavaScript Een aantal programmeeraspecten zijn uniek voor de ontwikkeling van Adobe® AIR™-toepassingen met HTML en JavaScript. De volgende informatie is belangrijk, ongeacht of u een HTML-gebaseerde AIR-toepassing programmeert, of dat u een SWF-gebaseerde AIR-toepassing programmeert die HTML en JavaScript uitvoert met behulp van de klasse HTMLLoader (of de Flex™-component mx:HTML).
Informatie over de klasse HTMLLoader De klasse HTMLLoader van Adobe AIR definieert het weergaveobject dat HTML-inhoud kan weergeven in een AIRtoepassing. SWF-gebaseerde toepassingen kunnen een HTMLLoader-besturingselement aan een bestaand venster toevoegen of een HTML-venster maken dat automatisch een HTMLLoader-object bevat met HTMLLoader.createRootWindow(). Het HTMLLoader-object kan vanuit de geladen HTML-pagina worden opgeroepen met de JavaScript-eigenschap window.htmlLoader.
HTML-inhoud laden vanuit een URL De volgende code laadt een URL in een HTMLLoader-object (voeg de HTMLLoader toe als onderliggend object van de Stage of andere weergaveobjectcontainer om de HTML-inhoud in uw toepassing weer te geven): import flash.html.HTMLLoader; var html:HTMLLoader = new HTMLLoader; html.width = 400; html.height = 600; var urlReq:URLRequest = new URLRequest("http://www.adobe.com/"); html.load(urlReq);
De eigenschappen width en height van een HTMLLoader-object zijn standaard allebei ingesteld op 0. U wordt aangeraden deze afmetingen in te stellen als u een HTMLLoader-object aan het Stage-object toevoegt. De HTMLLoader verstuurt verschillende gebeurtenissen terwijl een pagina wordt geladen. Op basis van deze gebeurtenissen kunt u bepalen wanneer het veilig is om met de geladen pagina te interageren. Deze gebeurtenissen worden beschreven in “HTML-gerelateerde gebeurtenissen afhandelen” op pagina 258. U kunt HTML-tekst ook renderen met behulp van de klasse TextField, maar de mogelijkheden hiervan zijn beperkt. De klasse TextField van Adobe® Flash® Player ondersteunt een subset van de HTML-markeringen, maar vanwege de groottebeperkingen zijn de mogelijkheden hiervan beperkt. (De klasse HTMLLoader die in Adobe AIR is opgenomen, is niet beschikbaar in Flash Player.)
HTML-inhoud laden vanuit een tekenreeks De methode loadString() van een HTMLLoader-object laadt een tekenreeks met HTML-inhoud in het HTMLLoader-object: var html:HTMLLoader = new HTMLLoader(); var htmlStr:String = "Hello world."; html.loadString(htmlStr);
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 239 Programmeren in HTML en JavaScript
Standaard wordt inhoud die is geladen via de methode loadString(), geplaatst in een niet-toepassingssandbox met de volgende kenmerken:
• Deze kan inhoud laden van het netwerk, maar niet van het bestandssysteem. • Deze kan geen gegevens laden met behulp van XMLHttpRequest. • De eigenschap window.location wordt ingesteld op "about:blank". • De inhoud kan geen toegang krijgen tot de eigenschap window.runtime (inhoud in een niet-toepassingssandbox kan dit bijvoorbeeld wel). In AIR 1.5 omvat de klasse HTMLLoader een eigenschap placeLoadStringContentInApplicationSandbox. Wanneer deze eigenschap voor een HTMLLoader-object is ingesteld op true, wordt inhoud die wordt geladen via de methode loadString(), geplaatst in de toepassingssandbox. (De standaardwaarde is false.) Inhoud die wordt geladen via de methode loadString(), krijgt daarmee toegang tot de eigenschap window.runtime en tot alle API's van AIR. Als u deze eigenschap instelt op true, moet u ervoor zorgen dat de gegevensbron voor een tekenreeks die wordt gebruikt in een aanroep naar de methode loadString(), vertrouwd wordt. Code-instructies in de HTMLtekenreeks worden uitgevoerd met alle toepassingsmachtigingen wanneer deze eigenschap is ingesteld op true. Stel deze eigenschap alleen in op true wanneer u er zeker van bent dat de tekenreeks geen schadelijke code kan bevatten. In toepassingen die zijn gecompileerd met de SDK's van AIR 1.0 of AIR 1.1, wordt inhoud die wordt geladen via de methode loadString(), geplaatst in de toepassingssandbox.
Belangrijke veiligheidsregels bij gebruik van HTML in AIR-toepassingen De bestanden die u met de AIR-toepassing installeert, hebben toegang tot de API's van AIR. Om veiligheidsredenen heeft de inhoud van andere bronnen geen toegang tot deze API's. Voorbeeld: deze beperking voorkomt dat inhoud van een extern domein (bijvoorbeeld http://example.com) de inhoud van de bureaubladmap van de gebruiker (of nog erger) kan lezen. Omdat beveiligingshiaten kunnen worden gebruikt door de functie eval() (en verwante API's) op te roepen, kan inhoud die met de toepassing wordt geïnstalleerd, deze methoden standaard niet gebruiken. Bepaalde Ajaxframeworks gebruiken echter de functie eval() en verwante API's. Om inhoud goed te structureren zodat deze kan werken in een AIR-toepassing, moet u rekening houden met de beveiligingsbeperkingen voor inhoud van verschillende bronnen. Inhoud van verschillende bronnen wordt geplaatst in afzonderlijke beveiligingsclassificaties, die sandboxen worden genoemd (zie “Sandboxen” op pagina 28). Inhoud die met de toepassing wordt geïnstalleerd, wordt standaard in een sandbox geïnstalleerd die de toepassingssandbox wordt genoemd. Deze verleent toegang tot de API's van AIR. De toepassingssandbox is de veiligste sandbox, aangezien beperkingen voorkomen dat niet-vertrouwde code wordt uitgevoerd. U kunt inhoud die met uw toepassing is geïnstalleerd, ook in een andere sandbox plaatsen. Inhoud in niettoepassingssandboxen werkt in een beveiligde omgeving, zoals in een webbrowser. Voorbeeld: code in niettoepassingssandboxen kan eval() en verwante methoden gebruiken (maar anderzijds heeft deze code geen toegang tot de API's van AIR). De runtime voorziet in manieren om inhoud in verschillende sandboxen veilig te laten communiceren (zonder bijvoorbeeld API's van AIR toegankelijk te maken voor niet-toepassingsinhoud). Zie “Crossscripting van inhoud in verschillende beveiligingssandboxen” op pagina 253 voor meer informatie. Als u code oproept die niet in een sandbox kan worden gebruikt vanwege beveiligingsbeperkingen, geeft de runtime de foutmelding weer dat er in de runtime van Adobe AIR een beveiligingsfout betreffende JavaScript-code in de toepassingsbeveiligingssandbox is opgetreden. Om deze fout te voorkomen, volgt u de coderingsrichtlijnen in de volgende sectie, “JavaScript-beveiligingsfouten voorkomen” op pagina 240. Zie “Beveiliging in HTML” op pagina 31 voor meer informatie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 240 Programmeren in HTML en JavaScript
JavaScript-beveiligingsfouten voorkomen Als u code oproept die niet in een sandbox kan worden gebruikt vanwege deze beveiligingsbeperkingen, geeft de runtime de foutmelding weer dat er in de runtime van Adobe AIR een beveiligingsfout betreffende JavaScript-code in de toepassingsbeveiligingssandbox is opgetreden. Ga als volgt te werk om deze fout te voorkomen.
Oorzaken van JavaScript-beveiligingsfouten Code die wordt uitgevoerd in de toepassingssandbox, is uitgesloten van de meeste bewerkingen waarbij tekenreeksen worden geëvalueerd en uitgevoerd nadat de documentgebeurtenis load is geactiveerd en eventuele handlers voor de gebeurtenis load zijn afgesloten. Als u de volgende typen JavaScript-instructies gebruikt die potentieel onveilige tekenreeksen evalueren en uitvoeren, worden JavaScript-fouten gegenereerd:
• De functie eval() • setTimeout() en setInterval() • Functieconstructor Bovendien mislukken de volgende typen JavaScript-instructies zonder een Javascript-fout voor onveilige inhoud te genereren:
• javascript: URL's • Gebeurteniscallbacks die via onevent-kenmerken in innerHTML- en outerHTML-instructies zijn toegewezen • JavaScript-bestanden laden van buiten de installatiemap van de toepassing • document.write() en document.writeln() • Synchrone XMLHttpRequests vóór de gebeurtenis load of tijdens de gebeurtenishandler load • Dynamisch gecreëerde scriptelementen Opmerking: In enkele beperkte gevallen is de evaluatie van tekenreeksen toegestaan. Zie “Codebeperkingen voor de inhoud van verschillende sandboxen” op pagina 33 voor meer informatie. Adobe houdt een lijst bij van Ajax-frameworks die de toepassingsbeveiligingssandbox ondersteunen. Deze lijst vindt u op http://www.adobe.com/go/airappsandboxframeworks_nl. In de volgende secties vindt u informatie om scripts zo aan te passen, dat deze JavaScript-fouten voor onveilige inhoud en stille defecten worden voorkomen voor code die in de toepassingssandbox wordt uitgevoerd.
Toepassingsinhoud toewijzen aan een andere sandbox In de meeste gevallen kunt u een toepassing aanpassen of opnieuw structureren, zodat JavaScript-beveiligingsfouten worden voorkomen. Als aanpassen of opnieuw structureren echter niet mogelijk is, kunt u de inhoud van de toepassing in een andere sandbox laden met de techniek die is beschreven in “Toepassingsinhoud laden in een niettoepassingssandbox” op pagina 254. Als deze inhoud ook toegang moet hebben tot de API's van AIR, kunt u een sandboxbridge maken, zoals beschreven in “Sandboxbridge-interface instellen” op pagina 254.
De functie eval() In de toepassingssandbox kunt u de functie eval() alleen gebruiken vóór de gebeurtenis load van de pagina of tijdens de gebeurtenishandler load. Nadat de pagina is geladen, wordt geen code uitgevoerd als eval() wordt opgeroepen. In de volgende gevallen kunt u uw code echter aanpassen om het gebruik van eval() te voorkomen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 241 Programmeren in HTML en JavaScript
Eigenschappen toewijzen aan een object In plaats van een tekenreeks te parseren om de eigenschapsaccessor te bouwen: eval("obj." + propName + " = " + val);
roep eigenschappen op met haakjesnotering: obj[propName] = val;
Functies maken met variabelen die beschikbaar zijn in de context Vervang instructies zoals deze: function compile(var1, var2){ eval("var fn = function(){ this."+var1+"(var2) }"); return fn; }
door: function compile(var1, var2){ var self = this; return function(){ self[var1](var2) }; }
Objecten maken met de naam van de klasse als tekenreeksparameter Bekijken we een hypothetische JavaScript-klasse die met de volgende code is gedefinieerd: var CustomClass = { Utils: { Parser: function(){ alert('constructor') } }, Data: { } }; var constructorClassName = "CustomClass.Utils.Parser";
De eenvoudigste manier om een instantie te maken, is met behulp van eval(): var myObj; eval('myObj=new ' + constructorClassName +'()')
U kunt het oproepen van eval() echter voorkomen door elke component van de klassenaam te parseren en het nieuwe object op te bouwen met behulp van de haakjesnotering:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 242 Programmeren in HTML en JavaScript
function getter(str) { var obj = window; var names = str.split('.'); for(var i=0;i
Om de instantie te maken, gebruikt u: try{ var Parser = getter(constructorClassName); var a = new Parser(); }catch(e){ alert(e); }
setTimeout() en setInterval() Vervang de tekenreeks die als handlerfunctie is opgegeven, door een functieverwijzing of een object. Voorbeeld: vervang een instructie zoals: setTimeout("alert('Timeout')", 10);
door: setTimeout(alert('Timeout'), 10);
Of, als de functie vereist dat het object this wordt ingesteld door de oproeper, vervangt u een instructie zoals: this.appTimer = setInterval("obj.customFunction();", 100);
door het volgende: var _self = this; this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);
Functieconstructor Oproepen van new Function(param, body) kunnen worden vervangen door een inline functiedeclaratie of alleen worden gebruikt voordat de gebeurtenis load van de pagina is afgehandeld.
javascript: URL's De code die in een koppeling met behulp van het URL-schema javascript: is gedefinieerd, wordt in de toepassingssandbox genegeerd. Er wordt geen JavaScript-fout voor onveilige inhoud gegenereerd. U kunt koppelingen vervangen die gebruikmaken van URL's van het type javascript:, zoals: Click Me
door:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 243 Programmeren in HTML en JavaScript
Gebeurteniscallbacks die via onevent-kenmerken in innerHTML- en outerHTML-instructies zijn toegewezen Als u innerHTML of outerHTML gebruikt om elementen toe te voegen aan de DOM van een document, worden gebeurteniscallbacks die in de instructie zijn toegewezen, zoals onclick of onmouseover, genegeerd. Er wordt geen beveiligingsfout gegenereerd. In plaats daarvan kunt u het kenmerk id aan de nieuwe elementen toewijzen en de callbackfuncties van de gebeurtenishandler instellen met de methode addEventListener(). U hebt bijvoorbeeld een doelelement in een document, zoals:
JavaScript-bestanden laden van buiten de installatiemap van de toepassing Scriptbestanden kunnen niet van buiten de toepassingssandbox worden geladen. Er wordt geen beveiligingsfout gegenereerd. Alle scriptbestanden die in de toepassingssandbox worden uitgevoerd, moeten in de toepassingsmap zijn geïnstalleerd. Als u externe scripts in een pagina wenst te gebruiken, moet u de pagina toewijzen aan een andere sandbox. Zie “Toepassingsinhoud laden in een niet-toepassingssandbox” op pagina 254.
document.write() en document.writeln() Oproepen van document.write() of document.writeln() worden genegeerd nadat de gebeurtenis load van de pagina is afgehandeld. Er wordt geen beveiligingsfout gegenereerd. Als alternatief kunt u een nieuw bestand laden of de hoofdtekst van het document vervangen met behulp van DOM-manipulatietechnieken.
Synchrone XMLHttpRequests vóór de gebeurtenis load of tijdens de gebeurtenishandler load Synchrone XMLHttpRequests die worden gestart vóór de gebeurtenis load van de pagina of tijdens de handler voor de gebeurtenis load, retourneren geen inhoud. Asynchrone XMLHttpRequests kunnen worden gestart maar retourneren pas na de gebeurtenis load. Nadat de gebeurtenis load is afgehandeld, gedragen synchrone XMLHttpRequests zich op de normale manier.
Dynamisch gecreëerde scriptelementen Scriptelementen die dynamisch zijn gecreëerd, bijvoorbeeld met innerHTML of de methode document.createElement(), worden genegeerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 244 Programmeren in HTML en JavaScript
API-klassen van AIR oproepen vanuit JavaScript Naast de standaardelementen en de uitgebreide elementen van Webkit, heeft HTML- en JavaScript-code toegang tot de hostklassen die door de runtime worden geboden. Met deze klassen hebt u toegang tot de geavanceerde functies van AIR, zoals:
• Toegang tot het bestandssysteem • Gebruik van lokale SQL-databases • Besturing van toepassings- en venstermenu's • Toegang tot netwerksockets • Gebruik van door de gebruiker gedefinieerde klassen en objecten • Geluidsmogelijkheden Voorbeeld: de AIR API voor het bestandssysteem bevat de klasse File, die in het pakket flash.filesystem is opgenomen. U kunt als volgt een File-object in JavaScript maken: var myFile = new window.runtime.flash.filesystem.File();
Het runtime-object is een speciaal JavaScript-object, dat beschikbaar is voor HTML-inhoud die in AIR in de toepassingssandbox wordt uitgevoerd. Hiermee hebt u vanuit JavaScript toegang tot runtimeklassen. De eigenschap flash van het runtime-object biedt toegang tot het pakket flash. De eigenschap flash.filesystem van het runtime-object biedt toegang tot het pakket flash.filesystem (dit pakket bevat de klasse File). Pakketten zijn een manier om klassen te organiseren die in ActionScript worden gebruikt. Opmerking: De eigenschap runtime wordt niet automatisch toegevoegd aan de vensterobjecten van pagina's die in een frame of iframe zijn geladen. Zolang het onderliggende document zich echter in de toepassingssandbox bevindt, heeft het onderliggende element toegang tot de eigenschap runtime van het bovenliggende element. Vanwege de pakketstructuur van de runtimeklassen zou een ontwikkelaar lange reeksen JavaScript-code moeten typen om toegang te krijgen tot elke klasse (bijvoorbeeld window.runtime.flash.desktop.NativeApplication). Daarom omvat de SDK van AIR het bestand AIRAliases.js, waarmee u veel makkelijker toegang hebt tot runtimeklassen (door bijvoorbeeld gewoon air.NativeApplication te typen). De API-klassen van AIR worden in deze handleiding besproken. Andere klassen van de API voor Flash Player die interessant kunnen zijn voor HTML-ontwikkelaars, worden beschreven in Adobe AIR Language Reference for HTML Developers. ActionScript is de taal die wordt gebruikt in SWF-inhoud (Flash Player). De syntaxis van JavaScript en die van ActionScript zijn echter bijna identiek. (Ze zijn allebei gebaseerd op versies van de taal ECMAScript.) Alle ingebouwde klassen zijn zowel in JavaScript (in HTML-inhoud) als in ActionScript (in SWFinhoud) beschikbaar. Opmerking: JavaScript-code kan geen gebruik maken van de klassen Dictionary, XML en XMLList, die wel beschikbaar zijn in ActionScript.
Het bestand AIRAliases.js gebruiken De runtimeklassen zijn georganiseerd in een pakketstructuur, zoals hierna wordt geïllustreerd:
•
window.runtime.flash.desktop.NativeApplication
•
window.runtime.flash.desktop.ClipboardManager
•
window.runtime.flash.filesystem.FileStream
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 245 Programmeren in HTML en JavaScript
•
window.runtime.flash.data.SQLDatabase
In de SDK van AIR is ook het bestand AIRAliases.js opgenomen, dat "alias"-definities bevat waarmee u runtimeklassen kunt oproepen zonder omslachtig typewerk. Voorbeeld: u kunt de klassen die hierboven zijn vermeld, oproepen door gewoon het volgende te typen:
•
air.NativeApplication
•
air.Clipboard
•
air.FileStream
•
air.SQLDatabase
Deze lijst is slechts een kort fragment van de klassen in het bestand AIRAliases.js. De volledige lijst van klassen en functies op pakketniveau vindt u in Adobe AIR Language Reference for HTML Developers. Naast de vaak gebruikte runtimeklassen bevat het bestand AIRAliases.js ook aliassen voor vaak gebruikte functies op pakketniveau: window.runtime.trace(), window.runtime.flash.net.navigateToURL() en window.runtime.flash.net.sendToURL(), met als alias air.trace(), air.navigateToURL() en air.sendToURL(). Als u het bestand AIRAliases.js wilt gebruiken, neemt u de volgende script-verwijzing op in uw HTML-pagina: <script src="AIRAliases.js">
Pas indien nodig het pad aan in de src-verwijzing. Belangrijk: Tenzij anders is aangegeven, gaat de JavaScript-voorbeeldcode in deze documentatie ervan uit dat u het bestand AIRAliases.js hebt opgenomen in uw HTML-pagina.
Informatie over URL's in AIR In HTML-inhoud die in AIR wordt uitgevoerd, kunt u een van de volgende URL-schema's gebruiken om srckenmerken te definiëren voor de tags img, frame, iframe en script, in het kenmerk href van de tag link, of op een willekeurige plaats waar u een URL kunt opgeven. URL-schema
Beschrijving
Voorbeeld
file
Het pad op basis van de hoofdmap van het bestandssysteem. file:///c:/AIR Test/test.txt
app
Het pad op basis van de hoofdmap van de geïnstalleerde toepassing.
app:/images
app-storage
Het pad op basis van de opslagmap van de toepassing. Voor elke geïnstalleerde toepassing definieert AIR een unieke opslagmap. Dit is de plaats waar gegevens worden opgeslagen die eigen zijn aan die toepassing.
app-storage:/settings/prefs.xml
http
Een standaard HTTP-aanvraag.
http://www.adobe.com
https
Een standaard HTTPS-aanvraag.
https://secure.example.com
Zie “URL-schema's van AIR gebruiken in URL's” op pagina 314 voor meer informatie over het gebruik van URLschema's in AIR.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 246 Programmeren in HTML en JavaScript
API's van AIR, zoals de klassen File, Loader, URLStream en Sound, maken vaak gebruik van een URLRequest-object in plaats van een tekenreeks waarin de URL is opgenomen. Het URLRequest-object zelf wordt geïnitialiseerd met een tekenreeks, die dezelfde URL-schema's kan gebruiken. Voorbeeld: de volgende instructie creëert een URLRequestobject waarmee de startpagina van Adobe kan worden opgevraagd: var urlReq = new air.URLRequest("http://www.adobe.com/");
Zie “URL-aanvragen en netwerken” op pagina 312 voor meer informatie over URLRequest-objecten.
ActionScript-objecten beschikbaar maken voor JavaScript JavaScript in de HTML-pagina die door een HTMLLoader-object is geladen, kan de klassen, objecten en functies oproepen die in de ActionScript-uitvoeringscontext zijn gedefinieerd. Daartoe wordt gebruikgemaakt van de eigenschappen window.runtime, window.htmlLoader en window.nativeWindow van de HTML-pagina. U kunt ook ActionScript-objecten en -functies beschikbaar maken voor JavaScript-code door verwijzingen naar die objecten en functies op te nemen in de JavaScript-uitvoeringscontext.
Basisvoorbeeld om JavaScript-objecten op te roepen vanuit ActionScript In het volgende voorbeeld ziet u hoe u eigenschappen kunt toevoegen die ActionScript-objecten verwijzen naar het algemene vensterobject van een HTML-pagina: var html:HTMLLoader = new HTMLLoader(); var foo:String = "Hello from container SWF." function helloFromJS(message:String):void { trace("JavaScript says:", message); } var urlReq:URLRequest = new URLRequest("test.html"); html.addEventListener(Event.COMPLETE, loaded); html.load(urlReq); function loaded(e:Event):void{ html.window.foo = foo; html.window.helloFromJS = helloFromJS; }
De HTML-inhoud (in een bestand met de naam test.html), die in het vorige voorbeeld in het HTMLLoader-object is geladen, kan de eigenschap foo oproepen, evenals de methode helloFromJS(), die in het bovenliggende SWFbestand is gedefinieerd:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 247 Programmeren in HTML en JavaScript
<script> function alertFoo() { alert(foo); }
Als u de JavaScript-context oproept van een document dat op dat moment wordt geladen, kunt u met de gebeurtenis htmlDOMInitialize al vroeg in de constructiesequentie van de pagina objecten maken, zodat ze toegankelijk zijn voor scripts die in de pagina zijn gedefinieerd. Als u wacht op de gebeurtenis complete, kunnen alleen scripts die na de gebeurtenis load van de pagina worden uitgevoerd, toegang krijgen tot de toegevoegde objecten.
Klassedefinities beschikbaar maken voor JavaScript Als u de ActionScript-klassen van uw toepassing beschikbaar wilt maken in JavaScript, kunt u de geladen HTMLinhoud toewijzen aan het toepassingsdomein waarin zich de klassedefinities bevinden. Het toepassingsdomein van de JavaScript-uitvoeringscontext kan worden ingesteld met de eigenschap runtimeApplicationDomain van het HTMLLoader-object. Als u het toepassingsdomein bijvoorbeeld wilt instellen op het primaire toepassingsdomein, stelt u runtimeApplicationDomain in op ApplicationDomain.currentDomain, zoals in de volgende code: html.runtimeApplicationDomain = ApplicationDomain.currentDomain;
Nadat de eigenschap runtimeApplicationDomain is ingesteld, deelt de JavaScript-context klassedefinities met het toegewezen domein. Als u een instantie van een aangepaste klasse in JavaScript wilt maken, verwijst u naar de klassedefinitie via de eigenschap window.runtime en gebruikt u de operator new: var customClassObject = new window.runtime.CustomClass();
De HTML-inhoud moet afkomstig zijn van een compatibel beveiligingsdomein. Als de HTML-inhoud afkomstig is van een ander beveiligingsdomein dan dat van het toepassingsdomein dat u toewijst, gebruikt de pagina in plaats daarvan een standaard toepassingsdomein. Voorbeeld: als u een externe pagina van internet laadt, kunt u ApplicationDomain.currentDomain niet toewijzen als het toepassingsdomein van de pagina.
Gebeurtenislisteners verwijderen Als u gebeurtenislisteners voor JavaScript toevoegt aan objecten buiten de huidige pagina, inclusief runtimeobjecten, objecten in de geladen SWF-inhoud en zelfs JavaScript-objecten die in andere pagina's worden uitgevoerd, moet u deze gebeurtenislisteners altijd verwijderen als de pagina niet meer is geladen. Anders verzendt de gebeurtenislistener de gebeurtenis naar een handlerfunctie die niet meer bestaat. In dit geval wordt er een foutmelding weergegeven dat de toepassing heeft geprobeerd te verwijzen naar een JavaScript-object in een HTML-pagina die niet meer is geladen. Wanneer u overbodige gebeurtenislisteners verwijdert, kan AIR ook het overeenkomstige geheugen opnieuw gebruiken. Zie “Gebeurtenislisteners verwijderen in HTML-pagina's die navigeren” op pagina 262 voor meer informatie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 248 Programmeren in HTML en JavaScript
HTML DOM- en JavaScript-objecten oproepen vanuit ActionScript Nadat het HTMLLoader-object de gebeurtenis complete heeft verzonden, hebt u toegang tot alle objecten in het HTML DOM (Document Object Model) voor de pagina. Toegankelijke objecten zijn onder andere weergaveelementen (zoals de objecten div en p in de pagina), evenals JavaScript-variabelen en -functies. De gebeurtenis complete komt overeen met de JavaScript-gebeurtenis load van de pagina. Vóór complete wordt verzonden, mogen variabelen, functies en DOM-elementen niet zijn geparseerd of gecreëerd. Indien mogelijk wacht u op de gebeurtenis complete vóór u het HTML DOM benadert. Bekijken we als voorbeeld de volgende HTML-pagina: <script> foo = 333; function test() { return "OK."; }
Hi.
Deze eenvoudige HTML-pagina definieert een JavaScript-variabele met de naam foo en een JavaScript-functie met de naam test(). Beide zijn eigenschappen van het algemene object window van de pagina. Bovendien bevat het object window.document een element met de naam P (met de id p1), dat u kunt oproepen met de methode getElementById(). Nadat de pagina is geladen (wanneer het HTMLLoader-object de gebeurtenis complete verzendt), kunt u al deze objecten benaderen vanuit ActionScript, zoals wordt geïllustreerd met de volgende ActionScript-code: var html:HTMLLoader = new HTMLLoader(); html.width = 300; html.height = 300; html.addEventListener(Event.COMPLETE, completeHandler); var xhtml:XML = <script> foo = 333; function test() { return "OK."; }
Hi.
; html.loadString(xhtml.toString()); function completeHandler(e:Event):void { trace(html.window.foo); // 333 trace(html.window.document.getElementById("p1").innerHTML); // Hi. trace(html.window.test()); // OK. }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 249 Programmeren in HTML en JavaScript
Als u de inhoud van een HTML-element wilt oproepen, gebruikt u de eigenschap innerHTML. De vorige code gebruikt bijvoorbeeld html.window.document.getElementById("p1").innerHTML om de inhoud van het HTML-element p1 op te halen. U kunt ook eigenschappen voor de HTML-pagina instellen vanuit ActionScript. Het volgende voorbeeld stelt de inhoud van het element p1 en de waarde van de JavaScript-variabele foo op de pagina in met behulp van een verwijzing naar het bevattende HTMLLoader-object: html.window.document.getElementById("p1").innerHTML = "Goodbye"; html.window.foo = 66;
SWF-inhoud insluiten in HTML In een AIR-toepassing kunt u SWF-inhoud insluiten in HTML-inhoud, net zoals in een browser. Sluit de SWF-inhoud in met behulp van de tag object, de tag embed of beide. Opmerking: Vaak wordt zowel de tag object als de tag embed gebruikt om SWF-inhoud weer te geven in een HTMLpagina. Deze techniek biedt echter geen voordelen in AIR. U kunt de W3C-standaard tag object op zichzelf gebruiken in inhoud die in AIR moet worden weergegeven. U kunt ook desgewenst de tags object en embed samen blijven gebruiken voor HTML-inhoud die ook in een browser wordt weergegeven. In het volgende voorbeeld ziet u hoe u de HTML-tag object gebruikt om een SWF-bestand in HTML-inhoud weer te geven. Het SWF-bestand wordt vanuit de toepassingsmap geladen maar u kunt een willekeurig URL-schema gebruiken dat door AIR wordt ondersteund. (De bronlocatie van het SWF-bestand bepaalt de beveiligingssandbox waarin AIR de inhoud plaatst.)
U kunt ook een script gebruiken om inhoud dynamisch te laden. In het volgende voorbeeld ziet u hoe u een objectknooppunt maakt om het SWF-bestand weer te geven dat is opgegeven in de parameter urlString. Het voorbeeld voegt het knooppunt toe als onderliggend element van het pagina-element met de id die is opgegeven met de parameter elementID: <script> function showSWF(urlString, elementID){ var displayContainer = document.getElementById(elementID); displayContainer.appendChild(createSWFObject(urlString,650,650)); } function createSWFObject(urlString, width, height){ var SWFObject = document.createElement("object"); SWFObject.setAttribute("type","application/x-shockwave-flash"); SWFObject.setAttribute("width","100%"); SWFObject.setAttribute("height","100%"); var movieParam = document.createElement("param"); movieParam.setAttribute("name","movie"); movieParam.setAttribute("value",urlString); SWFObject.appendChild(movieParam); return SWFObject; }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 250 Programmeren in HTML en JavaScript
ActionScript-bibliotheken in een HTML-pagina gebruiken AIR breidt het HTML-scriptelement uit, zodat een pagina ActionScript-klassen kan importeren in een gecompileerd SWF-bestand. Stel dat de bibliotheek myClasses.swf zich in de submap lib van de hoofdtoepassingsmap bevindt. Als u deze bibliotheek wilt importeren, neemt u de volgende scripttag op in een HTML-bestand: <script src="lib/myClasses.swf" type="application/x-shockwave-flash">
Belangrijk: Het kenmerk type moet type="application/x-shockwave-flash" zijn, anders wordt de bibliotheek niet goed geladen. Als de SWF-inhoud is gecompileerd als Flash Player 10 of AIR 1.5 SWF, moet u de XML-naamruimte van het descriptorbestand van de toepassing instellen op de AIR 1.5-naamruimte. Zie “Eigenschappen definiëren in het descriptorbestand van de toepassing” op pagina 46 voor meer informatie. De map lib en het bestand myClasses.swf moeten ook worden opgenomen wanneer het AIR-bestand in een pakket wordt geplaatst. Benader de geïmporteerde klassen via de eigenschap runtime van het JavaScript-object Window: var libraryObject = new window.runtime.LibraryClass();
Als de klassen in het SWF-bestand zijn verdeeld in pakketten, moet u ook de pakketnaam opnemen. Als de definitie LibraryClass zich bijvoorbeeld in een pakket met de naam utilities bevindt, maakt u met de volgende instructie een instantie van de klasse: var libraryObject = new window.runtime.utilities.LibraryClass();
Opmerking: Als u in AIR een ActionScript SWF-bibliotheek wilt compileren als onderdeel van een HTML-pagina, gebruikt u de compiler acompc. Het hulpprogramma acompc maakt deel uit van de SDK van Flex 3 en wordt beschreven in de Flex 3 SDK-documentatie.
HTML DOM- en JavaScript-objecten oproepen vanuit een geïmporteerd ActionScript-bestand Als u objecten in een HTML-pagina wenst op te roepen vanuit ActionScript in een SWF-bestand dat in de pagina is geïmporteerd met behulp van de tag <script>, geeft u een verwijzing naar een JavaScript-object zoals window of document op aan een functie die in de ActionScript-code is gedefinieerd. Gebruik de verwijzing binnen de functie om het JavaScript-object op te roepen (of andere objecten die toegankelijk zijn via de doorgegeven verwijzing). Bekijken we als voorbeeld de volgende HTML-pagina:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 251 Programmeren in HTML en JavaScript
<script src="ASLibrary.swf" type="application/x-shockwave-flash"> <script> num = 254; function getStatus() { return "OK."; } function runASFunction(window){ var obj = new runtime.ASClass(); obj.accessDOM(window); }
Body text.
Deze eenvoudige HTML-pagina heeft een JavaScript-variabele met de naam num en een JavaScript-functie met de naam getStatus(). Beide zijn eigenschappen van het object window van de pagina. Bovendien bevat het object window.document een element met de naam P (met de id p1). De pagina laadt het ActionScript-bestand "ASLibrary.swf", waarin zich de klasse ASClass bevindt. ASClass definieert de functie accessDOM(), die de waarden van deze JavaScript-objecten bijhoudt. De methode accessDOM() gebruikt het JavaScript-object Window als argument. Op basis van deze Window-verwijzing kunnen andere objecten in de pagina worden benaderd, zoals variabelen, functies en DOM-elementen, zoals wordt geïllustreerd in de volgende definitie: public class ASClass{ public function accessDOM(window:*):void { trace(window.num); // 254 trace(window.document.getElementById("p1").innerHTML); // Body text.. trace(window.getStatus()); // OK. } }
U kunt eigenschappen van de HTML-pagina ophalen en instellen op basis van een geïmporteerde ActionScript-klasse. De volgende functie stelt bijvoorbeeld de inhoud van het element p1 op de pagina in, evenals de waarde van de JavaScript-variabele foo op de pagina: public function modifyDOM(window:*):void { window.document.getElementById("p1").innerHTML = "Bye"; window.foo = 66;
Date- en RegExp-objecten converteren De talen JavaScript en ActionScript definiëren allebei de klassen Date en RegExp, maar objecten van deze typen worden niet automatisch geconverteerd tussen de twee uitvoeringscontexten. U moet de Date- en RegExp-objecten naar het equivalente type converteren vóór u ze gebruikt om eigenschappen of functieparameters in de andere uitvoeringscontext in te stellen. Voorbeeld: de volgende ActionScript-code converteert het JavaScript-object Date met de naam jsDate naar het ActionScript-object Date: var asDate:Date = new Date(jsDate.getMilliseconds());
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 252 Programmeren in HTML en JavaScript
De volgende ActionScript-code converteert het JavaScript-object RegExp met de naam jsRegExp naar het ActionScript-object RegExp: var flags:String = ""; if (jsRegExp.dotAll) flags += "s"; if (jsRegExp.extended) flags += "x"; if (jsRegExp.global) flags += "g"; if (jsRegExp.ignoreCase) flags += "i"; if (jsRegExp.multiline) flags += "m"; var asRegExp:RegExp = new RegExp(jsRegExp.source, flags);
HTML-opmaakmodellen bewerken vanuit ActionScript Nadat het HTMLLoader-object de gebeurtenis complete heeft verzonden, kunt u CSS-stijlen in een pagina onderzoeken en bewerken. Bekijken we als voorbeeld het volgende eenvoudige HTML-document: <style> .style1A { font-family:Arial; font-size:12px } .style1B { font-family:Arial; font-size:24px } <style> .style2 { font-family:Arial; font-size:12px }
Style 1A
Style 1B
Style 2
Nadat een HTMLLoader-object deze inhoud heeft geladen, kunt u de CSS-stijlen in de pagina als volgt bewerken via de array cssRules van de array window.document.styleSheets: var html:HTMLLoader = new HTMLLoader( ); var urlReq:URLRequest = new URLRequest("test.html"); html.load(urlReq); html.addEventListener(Event.COMPLETE, completeHandler); function completeHandler(event:Event):void { var styleSheet0:Object = html.window.document.styleSheets[0]; styleSheet0.cssRules[0].style.fontSize = "32px"; styleSheet0.cssRules[1].style.color = "#FF0000"; var styleSheet1:Object = html.window.document.styleSheets[1]; styleSheet1.cssRules[0].style.color = "blue"; styleSheet1.cssRules[0].style.font-family = "Monaco"; }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 253 Programmeren in HTML en JavaScript
Deze code past de CSS-stijlen zo aan, dat het resulterende HTML-document er als volgt uitziet:
Let op: code kan stijlen aan de pagina toevoegen nadat het HTMLLoader-object de gebeurtenis complete heeft verzonden.
Cross-scripting van inhoud in verschillende beveiligingssandboxen Het beveiligingsmodel van de runtime isoleert code op basis van de oorsprong. Door cross-scripting van de inhoud in verschillende beveiligingssandboxen kunt u inhoud in een bepaalde beveiligingssandbox toegang bieden tot bepaalde eigenschappen en methoden in een andere sandbox.
AIR-beveiligingssandboxen en JavaScript-code AIR past een zelfde-oorsprongbeleid toe, dat voorkomt dat code in een bepaald domein kan interageren met inhoud in een ander domein. Alle bestanden worden in een sandbox geplaatst op basis van hun oorsprong. Inhoud in de toepassingssandbox kan normaal gesproken niet het zelfde-oorsprongprincipe schenden en inhoud die van buiten de installatiemap van de toepassing is geladen, cross-scripten. AIR biedt echter een aantal technieken waarmee u crossscripting kunt toepassen op niet-toepassingsinhoud. Eén techniek maakt gebruik van frames of iframes om toepassingsinhoud aan een andere beveiligingssandbox toe te wijzen. Pagina's die vanaf de sandboxzone van de toepassing zijn geladen, gedragen zich alsof ze vanaf het externe domein zijn geladen. Voorbeeld: als u toepassingsinhoud toewijst aan het domein example.com, kan die inhoud pagina's cross-scripten die vanaf example.com zijn geladen. Deze techniek plaatst de toepassingsinhoud in een andere sandbox, zodat code binnen die inhoud niet langer is onderworpen aan de uitvoeringsbeperkingen voor code in geëvalueerde tekenreeksen. U kunt deze techniek van sandboxtoewijzing gebruiken om deze beperkingen te verminderen, zelfs als u geen cross-scripting van externe inhoud hoeft uit te voeren. Inhoud op die manier toewijzen, kan met name interessant zijn als u met een van de vele JavaScriptframeworks werkt, of met bestaande code die is gebaseerd op de evaluatie van tekenreeksen. Neem echter het extra risico in acht dat onvertrouwde inhoud kan worden geïnjecteerd en uitgevoerd als inhoud buiten de toepassingssandbox wordt uitgevoerd. Pas hiervoor de nodige voorzorgsmaatregelen toe. Anderzijds verliest toepassingsinhoud die aan een andere sandbox is toegewezen, de toegangsrechten voor de API's van AIR, zodat de techniek van sandboxtoewijzing niet kan worden gebruikt om AIR-functionaliteit toegankelijk te maken voor code die buiten de toepassingssandbox wordt uitgevoerd. Met een andere cross-scriptingtechniek kunt u een interface (sandboxbridge) maken tussen inhoud in een niettoepassingssandbox en het bovenliggende document in de toepassingssandbox. Dankzij deze bridge heeft de onderliggende inhoud toegang tot eigenschappen en methoden die door de bovenliggende inhoud worden gedefinieerd, en omgekeerd. Beide situaties kunnen zich ook tegelijk voordoen. Ten slotte kunt u ook domeinoverschrijdende XMLHttpRequests uitvoeren vanuit de toepassingssandbox en optioneel vanuit andere sandboxen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 254 Programmeren in HTML en JavaScript
Zie “Frame- en iframe-elementen in HTML” op pagina 232, “Beveiliging in HTML” op pagina 31 en het “XMLHttpRequest-objecten” op pagina 226 voor meer informatie.
Toepassingsinhoud laden in een niet-toepassingssandbox Om toepassingsinhoud veilig te cross-scripten met inhoud die van buiten de installatiemap van de toepassing is geladen, kunt u het element frame of iframe gebruiken om toepassingsinhoud in dezelfde beveiligingssandbox als de externe inhoud te laden. Als u geen cross-scripting van de externe inhoud nodig hebt maar toch een pagina van uw toepassing buiten de toepassingssandbox wilt laden, kunt u dezelfde techniek gebruiken, waarbij u http://localhost/ of een andere onschuldige waarde opgeeft als het domein of de oorsprong. AIR voegt de nieuwe kenmerken sandboxRoot en documentRoot toe aan het element frame, zodat u kunt bepalen of een toepassingsbestand dat in het frame is geladen, moet worden toegewezen aan een niet-toepassingssandbox. Bestanden met een pad onder de URL sandboxRoot worden in plaats daarvan geladen vanuit de map documentRoot. Om veiligheidsredenen wordt de toepassingsinhoud die op die manier wordt geladen, behandeld alsof deze vanaf de URL sandboxRoot is geladen. De eigenschap sandboxRoot geeft de URL op die moet worden gebruikt om de sandbox en het domein te bepalen waarin de frame-inhoud moet worden geplaatst. Het URL-schema file:, http: of https: moet worden gebruikt. Als u een relatieve URL opgeeft, blijft de inhoud in de toepassingssandbox. De eigenschap documentRoot bepaalt de map waaruit de frame-inhoud moet worden geladen. Het URL-schema file:, app: of app-storage: moet worden gebruikt. In het volgende voorbeeld ziet u hoe u inhoud die in de submap sandbox van de toepassing is geïnstalleerd, toewijst voor uitvoering in de externe sandbox en het domein www.example.com: <iframe src="http://www.example.com/local/ui.html" sandboxRoot="http://www.example.com/local/" documentRoot="app:/sandbox/">
De pagina ui.html kan met behulp van de volgende scripttag een JavaScript-bestand laden vanuit de lokale map sandbox: <script src="http://www.example.com/local/ui.js">
Deze pagina kan ook inhoud laden vanuit een map op de externe server met bijvoorbeeld de volgende scripttag: <script src="http://www.example.com/remote/remote.js">
De URL sandboxRoot maskeert alle inhoud op dezelfde URL op de externe server. In het vorige voorbeeld hebt u geen toegang tot externe inhoud op www.example.com/local/ (of een van de submappen) omdat AIR de aanvraag omleidt naar de lokale toepassingsmap. Alle aanvragen worden omgeleid, ongeacht of ze afkomstig zijn van paginanavigatie, een XMLHttpRequest of een andere manier om inhoud te laden.
Sandboxbridge-interface instellen U kunt een sandboxbridge gebruiken als inhoud in de toepassingssandbox toegang moet hebben tot eigenschappen of methoden die zijn gedefinieerd door inhoud in een niet-toepassingssandbox, of als niet-toepassingsinhoud toegang moet hebben tot eigenschappen en methoden die zijn gedefinieerd door inhoud in de toepassingssandbox. Creëer een bridge met de eigenschappen childSandboxBridge en parentSandboxBridge van het object window van een willekeurig onderliggend document.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 255 Programmeren in HTML en JavaScript
Onderliggende sandboxbridges creëren Met de eigenschap childSandboxBridge kan het onderliggende document een interface toegankelijk kan maken voor inhoud in het bovenliggende document. Als u een interface toegankelijk wilt maken, moet u de eigenschap childSandbox instellen op een functie of object in het onderliggende document. Vervolgens hebt u toegang tot het object of de functie vanuit de inhoud van het bovenliggende document. In het volgende voorbeeld ziet u hoe een script dat in een onderliggend document wordt uitgevoerd, een object dat een functie en eigenschap bevat, toegankelijk kan maken voor het bovenliggende document: var interface = {}; interface.calculatePrice = function(){ return ".45 cents"; } interface.storeID = "abc" window.childSandboxBridge = interface;
Als deze onderliggende inhoud wordt geladen in een iframe met de id "child", kunt u de interface vanuit de bovenliggende inhoud benaderen door de eigenschap childSandboxBridge van het frame te lezen: var childInterface = document.getElementById("child").contentWindow.childSandboxBridge; air.trace(childInterface.calculatePrice()); //traces ".45 cents" air.trace(childInterface.storeID)); //traces "abc"
Bovenliggende sandboxbridges creëren Met de eigenschap parentSandboxBridge kan het bovenliggende document een interface toegankelijk kan maken voor inhoud in een onderliggend document. Als u een interface toegankelijk wilt maken, stelt het bovenliggende document de eigenschap parentSandbox van een onderliggend document in op een functie of object dat in het bovenliggende document wordt gedefinieerd. Vervolgens hebt u toegang tot het object of de functie vanuit de inhoud van het onderliggende document. In het volgende voorbeeld ziet u hoe een script dat in een bovenliggend document wordt uitgevoerd, een object dat een functie bevat, toegankelijk kan maken voor een onderliggend document: var interface = {}; interface.save = function(text){ var saveFile = air.File("app-storage:/save.txt"); //write text to file } document.getElementById("child").contentWindow.parentSandboxBridge = interface;
Via deze interface kan inhoud in het onderliggende frame tekst opslaan in een bestand met de naam save.txt. Er is echter geen andere toegang tot het bestandssysteem. De onderliggende inhoud kan bijvoorbeeld de functie Save als volgt oproepen: var textToSave = "A string."; window.parentSandboxBridge.save(textToSave);
De toepassingsinhoud moet de kleinst mogelijke interface toegankelijk maken voor andere sandboxen. Niettoepassingsinhoud moet standaard als onbetrouwbaar worden beschouwd omdat deze inhoud kan blootstaan aan toevallige of kwaadwillige injectie van code. U moet de nodige veiligheidsmaatregelen nemen om misbruik te voorkomen van de interface die u via de bovenliggende sandboxbridge toegankelijk maakt.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 256 Programmeren in HTML en JavaScript
Bovenliggende sandboxbridges benaderen tijdens het laden van een pagina Als een script in een onderliggend document toegang moet hebben tot een bovenliggende sandboxbridge, moet de bridge worden ingesteld voordat het script wordt uitgevoerd. Window-, frame- en iframe-objecten verzenden de gebeurtenis dominitialize nadat een nieuw pagina-DOM is gemaakt maar voordat scripts zijn geparseerd of DOMelementen zijn toegevoegd. U kunt de gebeurtenis dominitialize gebruiken om de bridge al vroeg in de constructiesequentie van de pagina te creëren, zodat alle scripts in het onderliggende document toegang hebben tot de bridge. In het volgende voorbeeld ziet u hoe u een bovenliggende sandboxbridge kunt maken als reactie op de gebeurtenis dominitialize die vanuit het onderliggende frame is verzonden: <script> var bridgeInterface = {}; bridgeInterface.testProperty = "Bridge engaged"; function engageBridge(){ document.getElementById("sandbox").contentWindow.parentSandboxBridge = bridgeInterface; } <iframe id="sandbox" src="http://www.example.com/air/child.html" documentRoot="app:/" sandboxRoot="http://www.example.com/air/" ondominitialize="engageBridge()"/>
Het volgende document, child.html, illustreert hoe onderliggende inhoud de bovenliggende sandboxbridge kan benaderen: <script> document.write(window.parentSandboxBridge.testProperty);
Om zeker te zijn dat u naar de gebeurtenis dominitialize in een onderliggend venster luistert en niet naar een frame, moet u de listener aan het nieuwe onderliggende Window-object toevoegen, dat u creëert met de functie window.open(): var childWindow = window.open(); childWindow.addEventListener("dominitialize", engageBridge()); childWindow.document.location = "http://www.example.com/air/child.html";
In dit geval bestaat er geen mogelijkheid om toepassingsinhoud toe te wijzen aan een niet-toepassingssandbox. Deze techniek is alleen nuttig als child.html van buiten de toepassingsmap wordt geladen. U kunt toepassingsinhoud in het venster nog altijd aan een niet-toepassingssandbox toewijzen, maar in dat geval moet u eerst een tussenpagina laden die zelf frames gebruikt om het onderliggende document te laden, en deze pagina toewijzen aan de gewenste sandbox.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 257 Programmeren in HTML en JavaScript
Als u de functie createRootWindow() van de klasse HTMLLoader gebruikt om een venster te maken, is het nieuwe venster geen onderliggend element van het document waaruit createRootWindow() wordt opgeroepen. U kunt dus geen sandboxbridge maken tussen het oproepende venster en niet-toepassingsinhoud die in het nieuwe venster is geladen. In plaats daarvan moet u in het nieuwe venster een tussenpagina laden die zelf frames gebruikt om het onderliggende document te laden. U kunt vervolgens de bridge creëren tussen het bovenliggende document van het nieuwe venster en het onderliggende document dat in het frame is geladen.
258
Hoofdstuk 22: HTML-gerelateerde gebeurtenissen afhandelen Met een systeem voor gebeurtenisafhandeling kunnen programmeurs op een gemakkelijke manier reageren op gebruikersinvoer en systeemgebeurtenissen. Het Adobe® AIR™-gebeurtenismodel is heel handig in het gebruik en voldoet aan alle standaarden. Het gebeurtenismodel is gebaseerd op de DOM (Document Object Model) Level 3 Events Specification, een industriestandaard voor de gebeurtenisafhandelingsarchitectuur, en bevat een krachtig en toch intuïtief gebeurtenisafhandelingsmechanisme voor programmeurs.
HTMLLoader-gebeurtenissen Een HTMLLoader-object verzendt de volgende Adobe® ActionScript® 3.0-gebeurtenissen: Gebeurtenis
Beschrijving
htmlDOMInitialize
Wordt verzonden wanneer het HTML-document wordt gemaakt, maar voordat scripts worden geparseerd of DOM-knooppunten worden toegevoegd aan de pagina.
complete
Wordt verzonden wanneer het HTML DOM is gemaakt als reactie op een laadbewerking onmiddellijk na de gebeurtenis onload in de HTML-pagina.
htmlBoundsChanged
Wordt verzonden wanneer een van de eigenschappen contentWidth of contentHeight (of allebei) is gewijzigd.
locationChange
Wordt verzonden wanneer de eigenschap location van de HTMLLoader is gewijzigd.
scroll
Wordt altijd verzonden wanneer de HTML-engine de scrollpositie wijzigt. Scrollgebeurtenissen kunnen plaatsvinden vanwege navigatie naar ankerkoppelingen (#koppelingen) op de pagina of vanwege het oproepen van de methode window.scrollTo(). De gebeurtenis scroll kan ook worden veroorzaakt door het invoeren van tekst in een tekstinvoergebied of tekstgebied.
uncaughtScriptException
Wordt verzonden wanneer in de HTMLLoader een JavaScript-uitzondering optreedt waarvoor geen voorziening is getroffen in de JavaScript-code.
U kunt ook een ActionScript-functie registreren voor een JavaScript-gebeurtenis (zoals onClick). Zie “DOMgebeurtenissen afhandelen met ActionScript” op pagina 258 voor meer informatie.
DOM-gebeurtenissen afhandelen met ActionScript U kunt ActionScript-functies registreren zodat ze reageren op JavaScript-gebeurtenissen. Kijk bijvoorbeeld naar de volgende HTML-inhoud: Click me.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 259 HTML-gerelateerde gebeurtenissen afhandelen
U kunt een ActionScript-functie registreren als handler voor een willekeurige gebeurtenis in de pagina. Met de volgende code voegt u bijvoorbeeld de functie clickHandler() toe als listener voor de gebeurtenis onclick van het element testLink in de HTML-pagina: var html:HTMLLoader = new HTMLLoader( ); var urlReq:URLRequest = new URLRequest("test.html"); html.load(urlReq); html.addEventListener(Event.COMPLETE, completeHandler); function completeHandler(event:Event):void { html.window.document.getElementById("testLink").onclick = clickHandler; } function clickHandler():void { trace("You clicked it!"); }
U kunt ook de methode addEventListener() gebruiken om te registreren voor deze gebeurtenissen. U kunt bijvoorbeeld de methode completeHandler() in het vorige voorbeeld vervangen door de volgende code: function completeHandler(event:Event):void { var testLink:Object = html.window.document.getElementById("testLink"); testLink.addEventListener("click", clickHandler); }
Wanneer een listener verwijst naar een specifiek DOM-element, is het aan te raden te wachten totdat de bovenliggende HTMLLoader de gebeurtenis complete heeft verzonden alvorens de gebeurtenislisteners toe te voegen. HTMLpagina's laden vaak meerdere bestanden en het HTML DOM wordt pas volledig samengesteld als alle bestanden zijn geladen en geparseerd. De HTMLLoader verzendt de gebeurtenis complete wanneer alle elementen zijn gemaakt.
Reageren op niet-onderschepte JavaScriptuitzonderingen Bekijk de volgende HTML-code: <script> function throwError() { var x = 400 * melbaToast; } Click me.
Deze bevat de JavaScript-functie throwError(), die verwijst naar de onbekende variabele melbaToast: var x = 400 * melbaToast;
Als een JavaScript-bewerking een ongeldige bewerking tegenkomt die niet in de JavaScript-code wordt onderschept via een try/catch-structuur, verzendt het HTMLLoader-object dat de pagina bevat, de gebeurtenis HTMLUncaughtScriptExceptionEvent. U kunt een handler voor deze gebeurtenis registreren, zoals in de volgende code:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 260 HTML-gerelateerde gebeurtenissen afhandelen
var html:HTMLLoader = new HTMLLoader(); var urlReq:URLRequest = new URLRequest("test.html"); html.load(urlReq); html.width = container.width; html.height = container.height; container.addChild(html); html.addEventListener(HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION, htmlErrorHandler); function htmlErrorHandler(event:HTMLUncaughtJavaScriptExceptionEvent):void { event.preventDefault(); trace("exceptionValue:", event.exceptionValue) for (var i:int = 0; i < event.stackTrace.length; i++) { trace("sourceURL:", event.stackTrace[i].sourceURL); trace("line:", event.stackTrace[i].line); trace("function:", event.stackTrace[i].functionName); } }
Binnen JavaScript kunt u dezelfde gebeurtenis afhandelen via de eigenschap window.htmlLoader: <script language="javascript" type="text/javascript" src="AIRAliases.js"> <script> function throwError() { var x = 400 * melbaToast; } function htmlErrorHandler(event) { event.preventDefault(); var message = "exceptionValue:" + event.exceptionValue + "\n"; for (var i = 0; i < event.stackTrace.length; i++){ message += "sourceURL:" + event.stackTrace[i].sourceURL +"\n"; message += "line:" + event.stackTrace[i].line +"\n"; message += "function:" + event.stackTrace[i].functionName + "\n"; } alert(message); } window.htmlLoader.addEventListener("uncaughtScriptException", htmlErrorHandler); Click me.
De gebeurtenishandler htmlErrorHandler() annuleert het standaardgedrag van de gebeurtenis (dat wil zeggen, het verzenden van een JavaScript-foutbericht naar de AIR trace-output) en genereert een eigen outputbericht. Deze output bevat de waarde van de exceptionValue van het HTMLUncaughtScriptExceptionEvent-object. De output bevat de eigenschappen van ieder object in de stackTrace-array:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 261 HTML-gerelateerde gebeurtenissen afhandelen
Runtimegebeurtenissen afhandelen met JavaScript De runtimeklassen ondersteunen het toevoegen van gebeurtenishandlers met de methode addEventListener(). Om een handlerfunctie voor een gebeurtenis toe te voegen, roept u de methode addEventListener() op van het object dat de gebeurtenis verzendt. U geeft hierbij het gebeurtenistype en de afhandelingsfunctie op. Als u bijvoorbeeld wilt luisteren naar de gebeurtenis closing die wordt verzonden wanneer een gebruiker op het sluitvak van een venster op de titelbalk klikt, gebruikt u de volgende opdracht: window.nativeWindow.addEventListener(air.NativeWindow.CLOSING, handleWindowClosing);
Gebeurtenishandlerfuncties maken Met de volgende code maakt u een eenvoudig HTML-bestand dat informatie weergeeft over de positie van het hoofdvenster. Een handlerfunctie met de naam moveHandler() luistert naar een verplaatsingsgebeurtenis (gedefinieerd door de klasse NativeWindowBoundsEvent) van het hoofdvenster. <script src="AIRAliases.js" /> <script> function init() { writeValues(); window.nativeWindow.addEventListener(air.NativeWindowBoundsEvent.MOVE, moveHandler); } function writeValues() { document.getElementById("xText").value = window.nativeWindow.x; document.getElementById("yText").value = window.nativeWindow.y; } function moveHandler(event) { air.trace(event.type); // move writeValues(); }
Window X:
Window Y:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 262 HTML-gerelateerde gebeurtenissen afhandelen
Wanneer een gebruiker het venster verplaatst, geven de textarea-elementen de bijgewerkte X- en Y-positie van het venster weer: Het gebeurtenisobject wordt als argument doorgegeven aan de methode moveHandler(). Met de parameter event kan uw handlerfunctie het gebeurtenisobject onderzoeken. In dit voorbeeld gebruikt u de eigenschap type van het gebeurtenisobject om te rapporteren dat de gebeurtenis van het type move is.
Gebeurtenislisteners verwijderen U kunt de methode removeEventListener() gebruiken om een gebeurtenislistener te verwijderen die u niet meer nodig hebt. Het is raadzaam om alle listeners die niet meer worden gebruikt, te verwijderen. Vereiste parameters zijn onder meer de parameters eventName en listener. Dit zijn dezelfde vereiste parameters als voor de methode addEventListener().
Gebeurtenislisteners verwijderen in HTML-pagina's die navigeren Wanneer HTML-inhoud navigeert, of wanneer HTML-inhoud wordt verwijderd omdat een venster dat deze inhoud bevat wordt gesloten, worden de gebeurtenislisteners die verwijzen naar objecten op de ongeladen pagina, niet automatisch verwijderd. Wanneer een object een gebeurtenis verzendt naar een handler die al is verwijderd, wordt er een foutmelding weergegeven dat de toepassing heeft geprobeerd te verwijzen naar een JavaScript-object in een HTML-pagina die niet meer is geladen. Om deze fout te voorkomen, verwijdert u JavaScript-gebeurtenislisteners in een HTML-pagina voordat deze verdwijnt. In het geval van paginanavigatie (binnen een HTMLLoader-object) verwijdert u de gebeurtenislistener tijdens de gebeurtenis unload van het window-object. De volgende JavaScript-code verwijdert bijvoorbeeld een gebeurtenislistener voor de gebeurtenis uncaughtScriptException: window.onunload = cleanup; window.htmlLoader.addEventListener('uncaughtScriptException', uncaughtScriptException); function cleanup() { window.htmlLoader.removeEventListener('uncaughtScriptException', uncaughtScriptExceptionHandler); }
Om te voorkomen dat de fout optreedt wanneer vensters met HTML-inhoud worden gesloten, roept u een opschoningsfunctie op als reactie op de gebeurtenis closing van het NativeWindow-object (window.nativeWindow). De volgende JavaScript-code verwijdert bijvoorbeeld een gebeurtenislistener voor de gebeurtenis uncaughtScriptException: window.nativeWindow.addEventListener(air.Event.CLOSING, cleanup); function cleanup() { window.htmlLoader.removeEventListener('uncaughtScriptException', uncaughtScriptExceptionHandler); }
U kunt ook voorkomen dat deze fout optreedt door een gebeurtenislistener te verwijderen zodra deze is uitgevoerd. De volgende JavaScript-code maakt bijvoorbeeld een HTML-venster door de methode createRootWindow() van de klasse HTMLLoader op te roepen; hier wordt een gebeurtenislistener voor de gebeurtenis complete toegevoegd. Wanneer de gebeurtenishandler complete wordt opgeroepen, verwijdert deze zijn eigen gebeurtenislistener met behulp van de functie removeEventListener():
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 263 HTML-gerelateerde gebeurtenissen afhandelen
var html = runtime.flash.html.HTMLLoader.createRootWindow(true); html.addEventListener('complete', htmlCompleteListener); function htmlCompleteListener() { html.removeEventListener(complete, arguments.callee) // handler code.. } html.load(new runtime.flash.net.URLRequest("second.html"));
Door overbodige gebeurtenislisteners te verwijderen, kan de opschoonfunctie van het systeem ook het geheugen vrijmaken dat is gekoppeld aan die listeners.
Controleren op bestaande gebeurtenislisteners Met de methode hasEventListener() kunt u controleren op de aanwezigheid van gebeurtenislisteners op een object.
264
Hoofdstuk 23: Scripts schrijven voor de HTML-container De klasse HTMLLoader fungeert als container voor HTML-inhoud in Adobe® AIR™. De klasse biedt talrijke eigenschappen en methoden, die zijn overgenomen van de klasse Sprite en waarmee u het gedrag en de weergave van het object in de ActionScript® 3.0-weergavelijst kunt bepalen. Daarnaast definieert de klasse eigenschappen en methoden voor taken zoals het laden van en interageren met HTML-inhoud en het beheren van het historisch overzicht. De klasse HTMLHost definieert een set van standaardgedragingen voor een HTMLLoader. Wanneer u een HTMLLoader-object maakt, wordt niet voorzien in HTMLHost-implementatie. Dit betekent dat er niets gebeurt wanneer HTML-inhoud een van de standaardgedragingen activeert, zoals het wijzigen van de vensterlocatie of -titel. U kunt de klasse HTMLHost zo uitbreiden dat deze de gewenste gedragingen voor uw toepassing definieert. Voor HTML-vensters die met AIR worden gemaakt, is voorzien in een standaardimplementatie van de HTMLHost. U kunt deze standaard HTMLHost-implementatie aan een ander HTMLLoader-object toewijzen door de eigenschap htmlHost van het object in te stellen met een nieuw HTMLHost-object dat is gemaakt met de parameter defaultBehavior op true.
Eigenschappen van HTMLLoader-objecten weergeven Een HTMLLoader-object neemt de weergave-eigenschappen van de Adobe® Flash® Player-klasse Sprite. U kunt bijvoorbeeld vergroten, verkleinen, verplaatsen, verbergen en een andere achtergrondkleur selecteren. U kunt ook geavanceerde effecten toepassen, zoals filters, maskers, schaalinstelling en roteren. Houd bij het toepassen van effecten rekening met invloed op de leesbaarheid. SWF- en PDF-inhoud in een HTML-pagina kan niet worden weergegeven bij het toepassen van bepaalde effecten. HTML-vensters bevatten een HTMLLoader-object dat de HTML-inhoud rendert. Aangezien dit object beperkt is tot het venstergebied, heeft het wijzigen van de afmetingen of positie, roteren of schalen niet altijd het gewenste resultaat.
Basisweergave-eigenschappen Met de basisweergave-eigenschappen van de HTMLLoader kunt u het besturingselement binnen het hoofdweergaveobject positioneren, de afmetingen instellen en weergeven/verbergen. U wordt aangeraden deze eigenschappen niet te wijzigen voor het HTMLLoader-object van een HTML-venster. Dit zijn de basiseigenschappen: Eigenschap
Opmerkingen
x, y
Positioneert het object binnen zijn hoofdcontainer.
width, height
Wijzigt de afmetingen van het weergavegebied.
visible
Regelt de zichtbaarheid van het object en eventuele inhoud ervan.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 265 Scripts schrijven voor de HTML-container
Aan de buitenkant van een HTML-venster zijn de eigenschappen width en height van een HTMLLoader-object standaard ingesteld op 0. U moet de breedte en hoogte instellen om de geladen HTML-inhoud zichtbaar te maken. HTML-inhoud is gekoppeld aan de HTMLLoader-afmetingen. De opmaak is afhankelijk van de HTML- en CSSeigenschappen van de inhoud. Wanneer u de HTMLLoader-afmetingen wijzigt, wordt de loop van de inhoud aangepast. Bij het laden van inhoud in een nieuw HTMLLoader-object (waarbij width nog altijd op 0 staat), kan het verleidelijk zijn om de waarden width en height voor de weergave van de HTMLLoader in te stellen met behulp van de eigenschappen contentWidth en contentHeight. Deze techniek werkt bij pagina's met een redelijke minimumbreedte die worden opgemaakt volgens de HTML- en CSS-regels voor de tekstloop. Sommige pagina's hebben echter een lange, smalle loop omdat er geen redelijke breedte is opgegeven door de HTMLLoader. Opmerking: Wanneer u de breedte en hoogte van een HTMLLoader-object wijzigt, veranderen de waarden scaleX en scaleY niet, wat wel het geval is bij de meeste andere typen van weergaveobjecten.
Transparantie van HTMLLoader-inhoud De eigenschap paintsDefaultBackground van een HTMLLoader-object, die standaard op true is ingesteld, bepaalt of het HTMLLoader-object een ondoorzichtige achtergrond heeft. Als paintsDefaultBackground is ingesteld op false, is de achtergrond doorzichtig. De weergaveobjectcontainer of andere weergaveobjecten onder het HTMLLoader-object zijn zichtbaar achter de voorgrondelementen van de HTML-inhoud. Als het hoofdelement of een ander element van het HTML-document een achtergrondkleur opgeeft (bijvoorbeeld via style="background-color:gray"), is de achtergrond van het desbetreffende deel van de HTML-inhoud
ondoorzichtig en wordt het gerenderd met de opgegeven achtergrondkleur. Als u de eigenschap opaqueBackground van het HTMLLoader-object instelt en paintsDefaultBackground op false staat, is de kleur van opaqueBackground zichtbaar. Opmerking: U kunt een transparante afbeelding met PNG-indeling gebruiken om een achtergrond met alfa-overvloeiing te bieden voor een element in een HTML-document. Het instellen van de doorzichtigheidsstijl van een HTML-element wordt niet ondersteund.
HTMLLoader-inhoud schalen Het wordt niet aangeraden een HTMLLoader-object met een factor van meer dan 1,0 te schalen. Tekst in HTMLLoader-inhoud wordt naar een specifieke resolutie gerenderd en vertoont pixels als het HTMLLoader-object te veel wordt geschaald. Als u wilt voorkomen dat het HTMLLoader-object en zijn inhoud worden geschaald bij het vergroten/verkleinen van een venster, stelt u de eigenschap scaleMode van de stage in op StageScaleMode.NO_SCALE.
Belangrijke opmerkingen voor het laden van SWF- of PDF-inhoud in een HTML-pagina In de volgende gevallen verdwijnt SWF- en PDF-inhoud die in een HTMLLoader-object is geladen:
• als u het HTMLLoader-object schaalt met een andere factor dan 1.0; • als u de alfa-eigenschap van het HTMLLoader-object instelt op een andere waarde dan 1,0; • als u de HTMLLoader-inhoud roteert. De inhoud verschijnt weer als u de conflicterende eigenschapinstelling en de actieve filters verwijdert. Opmerking: Het runtime-programma kan geen SWF- of PDF-inhoud in transparante vensters weergeven.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 266 Scripts schrijven voor de HTML-container
Zie “SWF-inhoud insluiten in HTML” op pagina 249en “PDF-inhoud toevoegen” op pagina 278 voor meer informatie over het laden van deze mediatypen in een HTMLLoader.
Geavanceerde weergave-eigenschappen De klasse HTMLLoader neemt verschillende methoden over die voor speciale effecten kunnen worden gebruikt. Normaliter hebben deze effecten weliswaar beperkingen wanneer ze worden gebruikt voor HTMLLoader-weergave, maar ze kunnen nuttig zijn voor overgangen of andere tijdelijke effecten. Als u bijvoorbeeld een dialoogvenster weergeeft om gebruikersinvoer op te halen, kunt u de weergave van het hoofdvenster vaag maken tot de gebruiker het dialoogvenster heeft gesloten. Evenzo kunt u de weergave uitfaden bij het sluiten van een venster. Dit zijn de geavanceerde weergave-eigenschappen: Eigenschap
Beperkingen
alpha
Kan de leesbaarheid van HTML-inhoud verminderen.
filters
In een HTML-venster worden buiteneffecten bijgesneden door de vensterrand.
graphics
Vormen die met grafische opdrachten worden getekend, verschijnen onder HTML-inhoud, inclusief de standaardachtergrond. Als de getekende vormen zichtbaar moeten zijn, moet de eigenschap paintsDefaultBackground op 'false' staan.
opaqueBackground
De kleur van de standaardachtergrond wordt niet gewijzigd. Als deze kleurlaag zichtbaar moet zijn, moet de eigenschap paintsDefaultBackground op 'false' staan.
rotation
De hoeken van het rechthoekige HTMLLoader-gebied kan door de vensterrand worden bijgesneden. SWF- en PDF-inhoud die in de HTMLinhoud wordt geladen, is niet zichtbaar.
scaleX, scaleY
De gerenderde weergave kan pixels vertonen bij een schaalfactor van meer dan 1. SWF- en PDF-inhoud die in de HTML-inhoud wordt geladen, is niet zichtbaar.
transform
Kan de leesbaarheid van HTML-inhoud verminderen. De HTML-weergave kan door de vensterrand worden bijgesneden. SWF- en PDF-inhoud die in de HTML-inhoud wordt geladen, is niet zichtbaar als roteren, schalen of scheeftrekken wordt toegepast tijdens de transformatie.
In het volgende voorbeeld ziet u hoe u de array filters instelt om de volledige HTML-weergave vaag te maken: var html:HTMLLoader = new HTMLLoader(); var urlReq:URLRequest = new URLRequest("http://www.adobe.com/"); html.load(urlReq); html.width = 800; html.height = 600; var blur:BlurFilter = new BlurFilter(8); var filters:Array = [blur]; html.filters = filters;
HTML-inhoud schuiven De klasse HTMLLoader bevat de volgende eigenschappen waarmee u het schuiven van HTML-inhoud kunt bepalen:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 267 Scripts schrijven voor de HTML-container
Eigenschap
Beschrijving
contentHeight
De hoogte van de HTML-inhoud in pixels.
contentWidth
De breedte van de HTML-inhoud in pixels.
scrollH
De horizontale schuifpositie van de HTML-inhoud binnen het HTMLLoader-object.
scrollV
De verticale schuifpositie van de HTML-inhoud binnen het HTMLLoader-object.
De volgende code stelt de eigenschap scrollV zo in dat de HTML-inhoud naar de onderkant van de pagina wordt geschoven: var html:HTMLLoader = new HTMLLoader(); html.addEventListener(Event.HTML_BOUNDS_CHANGE, scrollHTML); const SIZE:Number = 600; html.width = SIZE; html.height = SIZE; var urlReq:URLRequest = new URLRequest("http://www.adobe.com"); html.load(urlReq); this.addChild(html); function scrollHTML(event:Event):void { html.scrollV = html.contentHeight - SIZE; }
Het HTMLLoader-object bevat geen horizontale en verticale schuifbalken. U kunt deze desgewenst toevoegen met ActionScript. U kunt ook de methode HTMLLoader.createRootWindow() gebruiken om een venster te maken dat een HTMLLoader-object met schuifbalken bevat (zie “Vensters met schuivende HTML-inhoud maken” op pagina 276).
Historisch overzicht van HTML openen Wanneer nieuwe pagina's in een HTMLLoader-object worden geladen, worden deze geregistreerd in het historisch overzicht van het object. Dit overzicht komt overeen met het object window.history op de HTML-pagina. De klasse HTMLLoader bevat de volgende eigenschappen en methoden waarmee u met het historisch overzicht van HTML kunt werken: Lid van klasse
Beschrijving
historyLength
De totale lengte van het historisch overzicht, inclusief vooruit- en achteruit-items.
historyPosition
De huidige positie in het historisch overzicht. Items die vóór deze positie in het overzicht staan, vertegenwoordigen navigatie “achteruit”, items na deze positie geven navigatie “vooruit” aan.
getHistoryAt()
Geeft het URLRequest-object weer dat overeenkomt met het item op de opgegeven positie in het historisch overzicht.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 268 Scripts schrijven voor de HTML-container
Lid van klasse
Beschrijving
historyBack()
Keert indien mogelijk terug in het historisch overzicht.
historyForward()
Gaat indien mogelijk verder in het historisch overzicht.
historyGo()
Gaat het opgegeven aantal stappen vooruit of achteruit in het historisch overzicht. Gaat vooruit als de waarde positief is, en keert terug als de waarde negatief is. Wanneer nul wordt bereikt, wordt de pagina opnieuw geladen. Als u een positie verder dan het einde opgeeft, wordt het einde van het overzicht weergegeven.
De items uit het overzicht worden opgeslagen als objecten van het type HistoryListItem. De klasse HistoryListItem heeft de volgende eigenschappen: Eigenschap
Beschrijving
isPost
Zet op true als de HTML-pagina POST-gegevens bevat.
originalUrl
De oorspronkelijke URL van de HTML-pagina, vóór eventueel doorsturen.
title
De titel van de HTML-pagina.
url
De URL van de HTML-pagina.
Gebruikersagent voor het laden van HTML-inhoud instellen De klasse HTMLLoader heeft een eigenschap userAgent, waarmee u de gebruikersagent-tekenreeks kunt instellen die door de HTMLLoader wordt gebruikt. Stel de eigenschap userAgent van het HTMLLoader-object in voordat u de methode load() oproept. Als u deze eigenschap op de HTMLLoader-instantie instelt, wordt de eigenschap userAgent van de URLRequest die wordt verzonden naar de methode load(), niet gebruikt. U kunt de standaard gebruikersagent-tekenreeks die door alle HTMLLoader-objecten in een toepassingsdomein wordt gebruikt, instellen via de eigenschap URLRequestDefaults.userAgent. De statische URLRequestDefaultseigenschappen gelden als standaardinstellingen voor alle URLRequest-objecten, niet alleen voor URLRequests die worden gebruikt met de methode load() van HTMLLoader-objecten. Wanneer u de eigenschap userAgent van een HTMLLoader-object instelt, overschrijft u de standaardinstelling URLRequestDefaults.userAgent. Als u geen gebruikersagent instelt voor de eigenschap userAgent van het HTMLLoader-object of voor URLRequestDefaults.userAgent, wordt de standaardwaarde van de AIR-gebruikersagent gebruikt. Deze standaardwaarde is afhankelijk van het runtime-besturingssysteem (bijvoorbeeld Mac OS of Windows), de runtimetaal en de runtime, zoals in de volgende twee voorbeelden wordt geïllustreerd:
•
"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) AdobeAIR/1.0"
•
"Mozilla/5.0 (Windows; U; en) AppleWebKit/420+ (KHTML, like Gecko) AdobeAIR/1.0"
Tekencodering voor HTML-inhoud instellen Een HTML-pagina kan de te gebruiken tekencodering instellen door de tag meta op te nemen, zoals in het volgende voorbeeld: meta http-equiv="content-type" content="text/html" charset="ISO-8859-1";
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 269 Scripts schrijven voor de HTML-container
Overschrijf de pagina-instelling om te zorgen dat een specifieke tekencodering wordt gebruikt. Stel hiervoor de eigenschap textEncodingOverride van het HTMLLoader-object in: var html:HTMLLoader = new HTMLLoader(); html.textEncodingOverride = "ISO-8859-1";
Geef de tekencodering voor HTMLLoader-inhoud op die moet worden gebruikt wanneer een HTML-pagina geen instelling opgeeft. Stel hiervoor de eigenschap textEncodingFallback van het HTMLLoader-object in: var html:HTMLLoader = new HTMLLoader(); html.textEncodingFallback = "ISO-8859-1";
De eigenschap textEncodingOverride overschrijft de instelling in de HTML-pagina. En de eigenschap textEncodingOverride en de instelling in de HTML-pagina overschrijven de eigenschap textEncodingFallback. Stel de eigenschap textEncodingOverride of de eigenschap textEncodingFallback in voordat de HTML-inhoud wordt geladen.
Gebruikersinterfaces van het type browser definiëren voor HTML-inhoud JavaScript biedt meerdere API's waarmee u bepaalt in welk venster de HTML-inhoud wordt weergegeven. In AIR kunt u deze API's negeren door een aangepaste HTMLHost-klasse te implementeren.
Informatie over het uitbreiden van de klasse HTMLHost Als uw toepassing bijvoorbeeld meerdere HTMLLoader-objecten in een venster met tabbladen weergeeft, kunt u zorgen dat titelwijzigingen door de geladen HTML-pagina's worden doorgevoerd in het label van het tabblad, en niet in de titel van het hoofdvenster. Zo kan uw code bijvoorbeeld op een oproep window.moveTo() reageren door het HTMLLoader-object in de hoofdweergaveobjectcontainer opnieuw te positioneren door het venster met het HTMLLoader-object te verplaatsen, door niets te doen of door iets helemaal anders te doen. De AIR-klasse HTMLHost regelt de volgende JavaScript-eigenschappen en -methoden:
•
window.status
•
window.document.title
•
window.location
•
window.blur()
•
window.close()
•
window.focus()
•
window.moveBy()
•
window.moveTo()
•
window.open()
•
window.resizeBy()
•
window.resizeTo()
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 270 Scripts schrijven voor de HTML-container
Wanneer u een HTMLLoader-object met behulp van new HTMLLoader() maakt, zijn de weergegeven JavaScripteigenschappen of -methoden niet ingeschakeld. De klasse HTMLHost biedt een standaardimplementatie van deze JavaScript-API's in de vorm van een browser. U kunt ook de klasse HTMLHost uitbreiden om het gedrag aan te passen. Als u een HTMLHost-object wilt maken dat het standaardgedrag ondersteunt, stelt u de parameter defaultBehaviors in op 'true' in de HTMLHost-constructor: var defaultHost:HTMLHost = new HTMLHost(true);
Als u in AIR een HTML-venster maakt via de methode createRootWindow() van de klasse HTMLLoader, wordt automatisch een HTMLHost-instantie toegewezen die de standaardgedragingen ondersteunt. U kunt het gedrag van het hostobject wijzigen door een andere HTMLHost-implementatie toe te wijzen aan de eigenschap htmlHost van de HTMLLoader, of u kunt null instellen om de voorzieningen volledig uit te schakelen. Opmerking: AIR wijst een standaard HTMLHost-object toe aan het beginvenster dat voor een op HTML gebaseerde AIRtoepassing is gemaakt, evenals aan alle vensters die zijn gemaakt via de standaardimplementatie van de JavaScriptmethode window.open().
Voorbeeld: de klasse HTMLHost uitbreiden In het volgende voorbeeld ziet u hoe u door het uitbreiden van de klasse HTMLHost de manier wijzigt waarop een HTMLLoader-object de gebruikersinterface beïnvloedt: 1 Maak een Flash-bestand voor AIR. Stel de documentklasse in op CustomHostExample en sla het bestand op als
CustomHostExample.fla. 2 Maak een ActionScript-bestand met de naam CustomHost.as en zorg dat het een klasse bevat die de klasse
HTMLHost uitbreidt (een subklasse). Deze klasse negeert bepaalde methoden van de nieuwe klasse om wijzigingen in de instellingen van de gebruikersinterface te verwerken. De volgende klasse, CustomHost, definieert bijvoorbeeld gedragingen voor oproepen van window.open() en wijzigingen in window.document.title. Oproepen van de methode window.open() openen de HTML-pagina in een nieuw venster en wijzigingen in de eigenschap window.document.title (zoals de instelling van het element van een HTML-pagina) stellen de titel van het desbetreffende venster in. package { import import import import import import import import import import
public class CustomHost extends HTMLHost { public var statusField:TextField; public function CustomHost(defaultBehaviors:Boolean=true) { super(defaultBehaviors); } override public function windowClose():void {
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 271 Scripts schrijven voor de HTML-container
htmlLoader.stage.nativeWindow.close(); } override public function createWindow( windowCreateOptions:HTMLWindowCreateOptions ):HTMLLoader { var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); var bounds:Rectangle = new Rectangle(windowCreateOptions.x, windowCreateOptions.y, windowCreateOptions.width, windowCreateOptions.height); var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, windowCreateOptions.scrollBarsVisible, bounds); htmlControl.htmlHost = new HTMLHostImplementation(); if(windowCreateOptions.fullscreen){ htmlControl.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE; } return htmlControl; } override public function updateLocation(locationURL:String):void { trace(locationURL); } override public function set windowRect(value:Rectangle):void { htmlLoader.stage.nativeWindow.bounds = value; } override public function updateStatus(status:String):void { statusField.text = status; trace(status); } override public function updateTitle(title:String):void { htmlLoader.stage.nativeWindow.title = title + "- Example Application"; } override public function windowBlur():void { htmlLoader.alpha = 0.5; } override public function windowFocus():void { htmlLoader.alpha = 1; } } }
3 Maak een ander ActionScript-bestand met de naam CustomHostExample.as en zorg dat het de documentklasse
voor de toepassing bevat. Deze klasse maakt een HTMLLoader-object en stelt de hosteigenschap van het object in op een instantie van de klasse CustomHost die u in de vorige stap hebt gedefinieerd:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 272 Scripts schrijven voor de HTML-container
Wijzigingen in de eigenschap window.location verwerken Hef de methode locationChange() op om wijzigingen in de URL van de HTML-pagina te verwerken. De methode locationChange() wordt opgeroepen wanneer JavaScript in een pagina de waarde van window.location wijzigt. In het volgende voorbeeld wordt gewoon de gevraagde URL geladen: override public function updateLocation(locationURL:String):void { htmlLoader.load(new URLRequest(locationURL)); }
Opmerking: U kunt de eigenschap htmlLoader van het HTMLHost-object gebruiken om naar het huidige HTMLLoaderobject te verwijzen.
JavaScript-oproepen van window.moveBy(), window.moveTo(), window.resizeTo() of window.resizeBy() afhandelen Hef de methode set windowRect() op om wijzigingen in de grenzen van de HTML-inhoud af te handelen. De methode set windowRect() wordt opgeroepen wanneer JavaScript in een pagina window.moveBy(), window.moveTo(), window.resizeTo() of window.resizeBy() oproept. In het volgende voorbeeld worden gewoon de grenzen van het bureaubladvenster bijgewerkt: override public function set windowRect(value:Rectangle):void { htmlLoader.stage.nativeWindow.bounds = value; }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 274 Scripts schrijven voor de HTML-container
JavaScript-oproepen van window.open() afhandelen Hef de methode createWindow() op om JavaScript-oproepen van window.open() af te handelen. Implementaties van de methode createWindow() zijn verantwoordelijk voor het maken en retourneren van een nieuw HTMLLoader-object. U geeft de HTMLLoader doorgaans in een nieuw venster weer maar het is niet nodig om een venster te maken. In het volgende voorbeeld ziet u hoe u de functie createWindow() implementeert met behulp van HTMLLoader.createRootWindow() om zowel het venster als het HTMLLoader-object te maken. U kunt ook afzonderlijk een NativeWindow-object maken en het HTMLLoader-object toevoegen aan de vensterfase. override public function createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader{ var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); var bounds:Rectangle = new Rectangle(windowCreateOptions.x, windowCreateOptions.y, windowCreateOptions.width, windowCreateOptions.height); var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, windowCreateOptions.scrollBarsVisible, bounds); htmlControl.htmlHost = new HTMLHostImplementation(); if(windowCreateOptions.fullscreen){ htmlControl.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE; } return htmlControl; }
Opmerking: In dit voorbeeld wordt de aangepaste HTMLHost-implementatie toegewezen aan eventuele nieuwe vensters die met window.open() zijn gemaakt. U kunt desgewenst ook een andere implementatie gebruiken of de eigenschap htmlHost op 'null' instellen voor nieuwe vensters. Het object dat als een parameter aan de methode createWindow() wordt toegewezen, is een HTMLWindowCreateOptions-object. De klasse HTMLWindowCreateOptions bevat eigenschappen die de waarden rapporteren die zijn ingesteld in de parametertekenreeks features voor het oproepen van window.open(): HTMLWindowCreateOptions -eigenschap
Overeenkomstige instelling in de functietekenreeks in de JavaScriptoproep van window.open()
fullscreen
fullscreen
height
height
locationBarVisible
location
menuBarVisible
menubar
resizeable
resizable
scrollBarsVisible
scrollbars
statusBarVisible
status
toolBarVisible
toolbar
width
width
x
left of screenX
y
top of screenY
De klasse HTMLLoader implementeert niet alle functies die in de functietekenreeks kunnen worden opgegeven. Uw toepassing moet wanneer nodig schuif-, locatie-, menu-, status- en werkbalken definiëren.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 275 Scripts schrijven voor de HTML-container
De overige argumenten voor de methode JavaScript window.open() worden door het systeem verwerkt. Een implementatie van createWindow() laadt normaliter geen inhoud in het HTMLLoader-object en stelt de venstertitel niet in.
JavaScript-oproepen van window.close() afhandelen Hef windowClose() op om JavaScript-oproepen van de methode window.close() af te handelen. In het volgende voorbeeld wordt het bureaubladvenster gesloten wanneer de methode window.close() wordt opgeroepen: override public function windowClose():void { htmlLoader.stage.nativeWindow.close(); }
JavaScript-oproepen van window.close() hoeven het inhoudsvenster niet te sluiten. U kunt bijvoorbeeld het HTMLLoader-object uit de weergavelijst verwijderen zonder het venster (dat nog andere inhoud kan bevatten) te sluiten. Dit wordt geïllustreerd door de volgende code: override public function windowClose():void { htmlLoader.parent.removeChild(htmlLoader); }
Wijzigingen in de eigenschap window.status verwerken Hef de methode updateStatus() op om JavaScript-wijzigingen in de waarde van window.status te verwerken. In het volgende voorbeeld wordt de statuswaarde getraceerd: override public function updateStatus(status:String):void { trace(status); }
De gevraagde status wordt als een tekenreeks verzonden naar de methode updateStatus(). Het HTMLLoader-object zorgt niet voor een statusbalk.
Wijzigingen in de eigenschap window.document.title verwerken Hef de methode updateTitle() op om JavaScript-wijzigingen in de waarde van window.document.title te verwerken. In het volgende voorbeeld wordt de venstertitel gewijzigd en de tekenreeks "Sample," toegevoegd aan de titel: override public function updateTitle(title:String):void { htmlLoader.stage.nativeWindow.title = title + " - Sample"; }
Als document.title is ingesteld op een HTML-pagina, wordt de gevraagde titel als een tekenreeks verzonden naar de methode updateTitle(). Wijzigingen in document.title hoeven de titel van het venster met het HTMLLoader-object niet te wijzigen. U kunt bijvoorbeeld een ander interface-element wijzigen, zoals een tekstveld.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 276 Scripts schrijven voor de HTML-container
JavaScript-oproepen van window.blur() en window.focus() afhandelen Hef de methoden windowBlur() en windowFocus() op om JavaScript-oproepen van window.blur() en window.focus() af te handelen, zoals in het volgende voorbeeld wordt geïllustreerd: override public function windowBlur():void { htmlLoader.alpha = 0.5; } override public function windowFocus():void { htmlLoader.alpha = 1.0; NativeApplication.nativeApplication.activate(htmlLoader.stage.nativeWindow); }
Opmerking: AIR biedt geen API voor het uitschakelen van een venster of toepassing.
Vensters met schuivende HTML-inhoud maken De klasse HTMLLoader bevat de statische methode HTMLLoader.createRootWindow(), waarmee u een nieuw venster (vertegenwoordigd door een NativeWindow-object) kunt openen dat een HTMLLoader-object bevat en waarmee u bepaalde gebruikersinterface-instellingen voor het desbetreffende venster kunt definiëren. De methode vereist het instellen van vier parameters, waarmee u de gebruikersinterface kunt definiëren: Parameter
Beschrijving
visible
Een Booleaanse waarde die bepaalt of het venster in eerste instantie zichtbaar is (true) of niet (false).
windowInitOptions
Een NativeWindowInitOptions-object. De klasse NativeWindowInitOptions definieert initialisatieopties voor een NativeWindow-object, zoals de volgende opties: of het venster kan worden geminimaliseerd/gemaximaliseerd of vergroot/verkleind, of het venster de systeeminterface of een aangepaste interface gebruikt, of het venster transparant is (bij vensters die niet de systeeminterface gebruiken), en het type van het venster.
scrollBarsVisible
Bepaalt of er schuifbalken zijn (true) of niet (false).
bounds
Een rechthoekig object dat de positie en afmetingen van het nieuwe venster definieert.
De volgende code bijvoorbeeld gebruikt de methode HTMLLoader.createRootWindow() om een venster te maken dat schuifbalken gebruikt en HTMLLoader-inhoud bevat: var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); var bounds:Rectangle = new Rectangle(10, 10, 600, 400); var html2:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, true, bounds); var urlReq2:URLRequest = new URLRequest("http://www.example.com"); html2.load(urlReq2); html2.stage.nativeWindow.activate();
Opmerking: Vensters die zijn gemaakt door het rechtstreeks in JavaScript oproepen van createRootWindow(), blijven onafhankelijk van het HTML-venster dat wordt geopend. De JavaScript-venstereigenschappen opener en parent bijvoorbeeld staan op null. Als u createRootWindow() echter onrechtstreeks oproept door de HTMLHost-methode createWindow() op te heffen om createRootWindow() op te roepen, verwijzen opener en parent naar het HTMLvenster dat wordt geopend.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 277 Scripts schrijven voor de HTML-container
Subklassen van de klasse HTMLLoader maken U kunt een subklasse van de klasse HTMLLoader maken om nieuwe gedragingen te creëren. U kunt bijvoorbeeld een subklasse maken die standaardlisteners voor HTMLLoader-gebeurtenissen definieert (zoals de gebeurtenissen die worden verzonden bij het renderen van HTML of wanneer de gebruiker op een koppeling klikt). In het volgende voorbeeld wordt de klasse HTMLHost uitgebreid om normaal gedrag te vertonen wanneer de JavaScript-methode window.open() wordt opgeroepen. Vervolgens wordt in het voorbeeld een subklasse van HTMLLoader gedefinieerd die de aangepaste HTMLHost-implementatieklasse gebruikt: package { import flash.html.HTMLLoader; public class MyHTMLHost extends HTMLHost { public function MyHTMLHost() { super(false); } override public function createWindow(opts:HTMLWindowCreateOptions):void { var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); var bounds:Rectangle = new Rectangle(opts.x, opts.y, opts.width, opts.height); var html:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, opts.scrollBarsVisible, bounds); html.stage.nativeWindow.orderToFront(); return html } }
De volgende code definieert een subklasse van de klasse HTMLLoader die een MyHTMLHost-object toewijst aan zijn eigenschap htmlHost: package { import flash.html.HTMLLoader; import MyHTMLHost; import HTMLLoader; public class MyHTML extends HTMLLoader { public function MyHTML() { super(); htmlHost = new MyHTMLHost(); } } }
Zie Gebruikersinterfaces van het type browser definiëren voor HTML-inhoud voor meer informatie over de klasse HTMLHost en de methode “Gebruikersinterfaces van het type browser definiëren voor HTML-inhoud” op pagina 269die in dit voorbeeld wordt gebruikt.
278
Hoofdstuk 24: PDF-inhoud toevoegen Toepassingen die in Adobe® AIR™ worden uitgevoerd, kunnen niet alleen SWF- en HTML-inhoud renderen, maar ook PDF-inhoud. AIR-toepassingen renderen PDF-inhoud met behulp van de klasse HTMLLoader, de WebKit-engine en de Adobe® Reader® plug-in voor de browser. In een AIR-toepassing kan PDF-inhoud gelden voor de volledige hoogte en breedte van uw toepassing of slechts voor een deel van de interface. De Adobe Reader plug-in voor de browser regelt de weergave van PDF-bestanden in een AIR-toepassing, zodat wijzigingen in de werkbalkinterface van Adobe Reader (bijvoorbeeld voor positionering, verankering en zichtbaarheid) ook gelden wanneer de PDF-bestanden later in AIRtoepassingen en in de browser worden bekeken. Belangrijk: Om PDF-inhoud in AIR te renderen, moet Adobe Reader of Adobe® Acrobat® versie 8.1 of hoger op de computer van de gebruiker zijn geïnstalleerd.
PDF-mogelijkheden detecteren Als Adobe Reader of Adobe Acrobat 8.1 of hoger niet op de computer van de gebruiker is geïnstalleerd, wordt PDFinhoud niet weergegeven in een AIR-toepassing. Om na te gaan of een gebruiker PDF-inhoud kan renderen, moet u eerst de eigenschap HTMLLoader.pdfCapability controleren. Deze eigenschap is ingesteld op een van de volgende constanten uit de klasse HTMLPDFCapability. Constante
Beschrijving
HTMLPDFCapability.STATUS_OK
Een geschikte versie (8.1 of hoger) van Adobe Reader is gedetecteerd en PDF-inhoud kan in een HTMLLoader-object worden geladen.
Geen versie van Adobe Reader gedetecteerd. HTMLLoader-objecten kunnen geen PDF-inhoud weergeven.
HTMLPDFCapability.ERROR_INSTALLED_READER_TOO_OLD
Adobe Reader is gedetecteerd maar de versie is te oud. HTMLLoaderobjecten kunnen geen PDF-inhoud weergeven.
HTMLPDFCapability.ERROR_PREFERRED_READER_TOO_OLD
Een geschikte versie (8.1 of hoger) van Adobe Reader is gedetecteerd maar de versie van Adobe Reader die is ingesteld om PDF-inhoud af te handelen, is ouder dan Reader 8.1. HTMLLoader-objecten kunnen geen PDF-inhoud weergeven.
Als Adobe Acrobat of Adobe Reader versie 7.x of hoger momenteel op het Windows-systeem van de gebruiker wordt uitgevoerd, wordt die versie gebruikt, zelfs als een recentere versie is geïnstalleerd die het laden van PDF-inhoud ondersteunt. Als in dit geval de waarde van de eigenschap pdfCampability is ingesteld op HTMLPDFCapability.STATUS_OK en een AIR-toepassing PDF-inhoud probeert te laden, geeft de oudere versie van Acrobat of Reader een waarschuwing weer (er wordt geen uitzondering gegenereerd in de AIR-toepassing). Als deze situatie zich bij uw eindgebruikers kan voordoen, kunt u instructies opgeven om Acrobat te sluiten terwijl uw toepassing wordt uitgevoerd. U wordt aangeraden deze instructies weer te geven als de PDF-inhoud niet binnen een aanvaardbare tijd wordt geladen. Bij Linux zoekt AIR naar Adobe Reader op het pad (PATH) dat door de gebruiker is geëxporteerd (als het de opdracht acroread bevat) en in de map /opt/Adobe/Reader. De volgende code controleert of een gebruiker PDF-inhoud in een AIR-toepassing kan weergeven. Als dit niet het geval is, wordt de foutcode getraceerd die overeenkomt met het HTMLPDFCapability-foutobject:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 279 PDF-inhoud toevoegen
if(HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK) { trace("PDF content can be displayed"); } else { trace("PDF cannot be displayed. Error code:", HTMLLoader.pdfCapability); }
PDF-inhoud laden U kunt een PDF toevoegen aan een AIR-toepassing door een HTMLLoader-instantie te maken, de afmetingen ervan in te stellen en het pad van een PDF te laden. In het volgende voorbeeld ziet u hoe u een PDF vanaf een externe site laadt. Vervang de URLRequest door het pad naar een beschikbare externe PDF. var request:URLRequest = new URLRequest("http://www.example.com/test.pdf"); pdf = new HTMLLoader(); pdf.height = 800; pdf.width = 600; pdf.load(request); container.addChild(pdf);
U kunt ook inhoud laden vanaf bestands-URL's en AIR-specifieke URL-schema's, zoals app en app-storage. Voorbeeld: de volgende code laadt het bestand test.pdf naar de PDF-submap van de toepassingsmap: app:/js_api_reference.pdf Zie “URL-schema's van AIR gebruiken in URL's” op pagina 314 voor meer informatie over URL-schema's van AIR.
Scripting van PDF-inhoud U kunt JavaScript gebruiken om PDF-inhoud te besturen, net zoals in een webpagina in de browser. JavaScript-extensies voor Acrobat bieden onder andere de volgende mogelijkheden:
• Paginanavigatie en vergroting regelen • Formulieren in het document verwerken • Multimediagebeurtenissen besturen Meer informatie over JavaScript-extensies voor Adobe Acrobat vindt u in Adobe Acrobat Developer Connection op http://www.adobe.com/devnet/acrobat/javascript.html.
Basisinformatie over PDF-communicatie in HTML JavaScript in een HTML-pagina kan een bericht naar JavaScript in PDF-inhoud versturen door de methode postMessage() op te roepen van het DOM-object dat de PDF-inhoud voorstelt. U hebt bijvoorbeeld de volgende ingesloten PDF-inhoud:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 280 PDF-inhoud toevoegen
De volgende JavaScript-code in de bevattende HTML-inhoud verstuurt een bericht naar de JavaScript-code in het PDF-bestand: pdfObject = document.getElementById("PDFObj"); pdfObject.postMessage(["testMsg", "hello"]);
Het PDF-bestand kan JavaScript bevatten om dit bericht te ontvangen. U kunt in bepaalde contexten JavaScript-code aan PDF-bestanden toevoegen, zoals context op document-, map-, pagina-, veld- en batchniveau. Alleen context op documentniveau, die scripts definieert die worden geëvalueerd wanneer het PDF-document wordt geopend, wordt hier beschreven. Een PDF-bestand kan de eigenschap messageHandler toevoegen aan het hostContainer-object. De eigenschap messageHandler is een object dat de afhandelingsfuncties definieert waarmee op berichten wordt gereageerd. Voorbeeld: de volgende code definieert de functie om berichten af te handelen die het PDF-bestand ontvangt van de hostcontainer (dit is de HTML-inhoud die is ingesloten in het PDF-bestand): this.hostContainer.messageHandler = {onMessage: myOnMessage}; function myOnMessage(aMessage) { if(aMessage[0] == "testMsg") { app.alert("Test message: " + aMessage[1]); } else { app.alert("Error"); } }
JavaScript-code in de HTML-pagina kan de methode postMessage() oproepen van het PDF-object dat zich in de pagina bevindt. Door het oproepen van deze methode wordt het bericht "Hello from HTML" naar de JavaScript-code op documentniveau in het PDF-bestand verzonden:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 281 PDF-inhoud toevoegen
PDF Test <script> function init() { pdfObject = document.getElementById("PDFObj"); try { pdfObject.postMessage(["alert", "Hello from HTML"]); } catch (e) { alert( "Error: \n name = " + e.name + "\n message = " + e.message ); } }
Zie Cross-scripting van PDF-inhoud in Adobe AIR voor een meer geavanceerd voorbeeld en informatie over het gebruik van Acrobat 8 om JavaScript aan een PDF-bestand toe te voegen.
Scripting van PDF-inhoud vanuit ActionScript ActionScript-code (in SWF-inhoud) kan niet rechtstreeks communiceren met JavaScript in PDF-inhoud. ActionScript kan echter wel communiceren met de JavaScript-code in de HTML-pagina die is geladen in het HTMLLoader-object waarmee de PDF-inhoud wordt geladen, en die JavaScript-code kan communiceren met de JavaScript-code in het geladen PDF-bestand. Zie “Programmeren in HTML en JavaScript” op pagina 238 voor meer informatie.
Bekende beperkingen voor PDF-inhoud in AIR PDF-inhoud in Adobe AIR is onderworpen aan de volgende beperkingen:
• PDF-inhoud wordt niet weergegeven in een venster (een NativeWindow-object) dat transparant is (waarbij de eigenschap transparent is ingesteld op true).
• De weergavevolgorde van een PDF-bestand is anders dan bij andere weegaveobjecten in een AIR-toepassing. Hoewel PDF-inhoud correct wordt weergegeven volgens de HTML-weergavevolgorde, bevindt deze zich altijd boven inhoud in de weergavevolgorde van de AIR-toepassing.
• PDF-inhoud wordt niet weergegeven in een schermvullend venster (als de eigenschap displayState van de stage is ingesteld op StageDisplayState.FULL_SCREEN of StageDisplayState.FULL_SCREEN_INTERACTIVE).
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 282 PDF-inhoud toevoegen
• Als bepaalde visuele eigenschappen van een HTMLLoader-object dat een PDF-document bevat worden gewijzigd, wordt het PDF-document onzichtbaar. Het betreft hierbij onder andere de eigenschappen filters, alpha, rotation en scaling. Als deze worden gewijzigd, wordt het PDF-bestand onzichtbaar totdat de eigenschappen opnieuw worden ingesteld. Dit is ook het geval als u deze eigenschappen wijzigt bij weergaveobjectcontainers die het HTMLLoader-object bevatten.
• PDF-inhoud is alleen zichtbaar wanneer de eigenschap scaleMode van het Stage-object van het NativeWindowobject dat de PDF-inhoud bevat, is ingesteld op StageScaleMode.NO_SCALE. Wanneer deze eigenschap is ingesteld op een andere waarde, is de PDF-inhoud niet zichtbaar.
• Wanneer de gebruiker op koppelingen naar inhoud in het PDF-bestand klikt, wordt de schuifpositie van de PDFinhoud bijgewerkt. Wanneer de gebruiker op koppelingen naar inhoud buiten het PDF-bestand klikt, wordt het HTMLLoader-object omgeleid waarin de PDF-inhoud zich bevindt (zelfs als het doel van een koppeling een nieuw venster is).
• Workflows voor PDF-commentaar werken niet in AIR.
283
Hoofdstuk 25: Digitaal rechtenbeheer gebruiken Met een Adobe® Flash® Media Rights Management Server (FMRMS) kunnen media-uitgevers inhoud verspreiden, met name FLV- en MP4-bestanden, en de productiekosten terugwinnen via directe vergoeding (betaald door de gebruiker) of indirecte vergoeding (betaald door publiciteit). De uitgevers verspreiden media in de vorm van gecodeerde FLV's, die kunnen worden gedownload en weergegeven in Adobe® Media Player™ of een willekeurige AIR-toepassing die gebruikmaakt van de API voor digitaal rechtenbeheer (DRM - Digital Rights Management). Met een FMRMS kunnen leveranciers van inhoud gebruikmaken van een op de identiteit gebaseerd licentiesysteem om hun inhoud te beschermen door middel van gebruikersgegevens. Voorbeeld: een consument wil een tvprogramma bekijken maar niet de bijbehorende advertenties zien. Daartoe registreert de consument zich en betaalt hij de uitgever van de inhoud een bepaalde prijs. De gebruiker kan dan met zijn autorisatiegegevens het programma oproepen en dit zonder de advertenties bekijken. Een andere consument wil bijvoorbeeld de inhoud offline bekijken terwijl hij onderweg is en geen toegang heeft tot internet. Nadat hij zich heeft geregistreerd en de uitgever van de inhoud voor deze service heeft betaald, krijgt hij met zijn autorisatiegegevens toegang tot het programma en kan hij het downloaden van de website van de uitgever. De gebruiker kan de inhoud vervolgens offline bekijken tijdens de toegestane periode. De inhoud is ook beveiligd door de gebruikersgegevens en kan dus niet met andere gebruikers worden gedeeld. Als een gebruiker een DRM-gecodeerd bestand probeert weer te geven, neemt de toepassing contact op met de FMRMS, die op zijn beurt contact opneemt met het systeem van de uitgever om via zijn SPI (Service Provider Interface) de gebruiker te autoriseren en de licentie op te halen. Deze bon bepaalt of de gebruiker toegang heeft tot de inhoud en voor hoe lang. De bon bepaalt ook of de gebruiker de inhoud offline kan openen en voor hoe lang. De gebruikersgegevens regelen dus de toegang tot de gecodeerde inhoud. Het licentiesysteem op basis van de identiteit ondersteunt ook anonieme toegang. Anonieme toegang kan bijvoorbeeld door de leverancier worden aangeboden om inhoud met advertenties te verspreiden of om gedurende een bepaald aantal dagen gratis toegang tot de inhoud te verlenen. Mogelijk wordt het archiefmateriaal tegen betaling aangeboden. In dit geval zijn de gebruikersgegevens vereist. De leverancier van de inhoud kan ook het type en de versie van de speler opgeven en beperken die voor het afspelen van de inhoud vereist is. Hier wordt beschreven hoe u met uw AIR-toepassing inhoud kunt weergeven die met DRM-codering is beveiligd is. U hoeft niet te begrijpen hoe inhoud met behulp van DRM wordt gecodeerd. We gaan er alleen van uit dat u toegang hebt tot DRM-gecodeerde inhoud en dat u met een FMRMS communiceert om de gebruiker te autoriseren en de bon op te vragen. Een overzicht van het gebruik van een FMRMS, inclusief het creëren van een beleid, vindt u in de documentatie bij FMRMS. Voor meer informatie over Adobe Media Player raadpleegt u de Help in Adobe Media Player.
Aanvullende online informatie over digitaal rechtenbeheer Op de volgende bronnen kunt u terecht voor meer informatie over digitaal rechtenbeheer:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 284 Digitaal rechtenbeheer gebruiken
Language Reference • AuthenticationMethod
• DRMAuthenticationCompleteEvent • DRMAuthenticationErrorEvent • DRMAuthenticateEvent • DRMContentData • DRMErrorEvent • DRMManager • DRMPlaybackTimeWindow • DRMStatusEvent • DRMVoucher • LoadVoucherSetting • NetStream Adobe Developer Connection - Artikels en voorbeelden • Adobe AIR Developer Connection for Flash (zoek naar ‘digital rights management’ of ‘drm’)
Gecodeerde FLV-workflows begrijpen Er zijn vier soorten gebeurtenissen: StatusEvent, DRMAuthenticateEvent, DRMErrorEvent en DRMStatusEvent, die kunnen worden verzonden wanneer een AIR-toepassing een DRM-gecodeerd bestand probeert af te spelen. Om deze bestanden te ondersteunen, moet de toepassing gebeurtenislisteners toevoegen om de DRM-gebeurtenissen af te handelen. Hierna wordt beschreven hoe de AIR-toepassing inhoud kan ophalen en afspelen die met DRM-codering is beveiligd: 1 De toepassing probeert met behulp van een NetStream-object een FLV- of MP4-bestand af te spelen. Als de inhoud
gecodeerd is, wordt de gebeurtenis events.StatusEvent samen met de code DRM.encryptedFLV verzonden om aan te geven dat de FLV gecodeerd is. Opmerking: Als een toepassing het DRM-gecodeerde bestand niet wil afspelen, kan deze naar de verzonden statusgebeurtenis luisteren als gecodeerde inhoud wordt aangetroffen. Vervolgens laat de toepassing de gebruiker weten dat het bestand niet wordt ondersteund en wordt de verbinding verbroken. 2 Als het bestand anoniem gecodeerd is, zodat alle gebruikers de inhoud kunnen bekijken zonder autorisatiegegevens
in te voeren, gaat de AIR-toepassing naar de laatste stap van deze workflow. Als het bestand echter een licentie op basis van identiteit nodig heeft, wat betekent dat gebruikersreferenties vereist zijn, verzendt het NetStream-object een DRMAuthenticateEvent-object. De gebruiker moet zijn autorisatiegegevens opgeven om het afspelen te starten. 3 De AIR-toepassing moet over een mechanisme beschikken om de vereiste autorisatiegegevens te verzamelen. Met
de eigenschappen usernamePrompt, passwordPrompt en urlPrompt van de klasse DRMAuthenticationEvent, die door de inhoudsserver worden geleverd, kunt u de eindgebruiker informatie bieden over de vereiste gegevens. U kunt deze eigenschappen gebruiken in een gebruikersinterface waarmee de vereiste gebruikersgegevens worden opgevraagd. Voorbeeld: de tekenreeks usernamePrompt kan aangeven dat de gebruikersnaam de vorm moet hebben van een e-mailadres.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 285 Digitaal rechtenbeheer gebruiken
Opmerking: AIR heeft geen standaard gebruikersinterface om autorisatiegegevens te verzamelen. De ontwikkelaar moet de gebruikersinterface schrijven en de DRMAuthenticateEvent-gebeurtenissen afhandelen. Als de toepassing geen gebeurtenislistener biedt voor DRMAuthenticateEvent-objecten, blijft het DRM-gecodeerde object in de toestand "wachten op gegevens" en is de inhoud dus niet beschikbaar. 4 Nadat de toepassing de gebruikersgegevens heeft ontvangen, worden deze met de methode setDRMAuthenticationCredentials() doorgestuurd naar het NetStream-object. Hierdoor weet het NetStreamobject dat het de gebruiker bij de volgende gelegenheid moet proberen te autoriseren. AIR stuurt de gegevens vervolgens voor verificatie naar de FMRMS. Als de gebruiker wordt geautoriseerd, gaat de toepassing naar de volgende stap.
Als verificatie is mislukt, verzendt het NetStream-object een nieuw DRMAuthenticateEvent-object en keert de toepassing terug naar stap 3. Dit proces wordt eindeloos herhaald. De toepassing moet over een mechanisme beschikken om de herhaalde autorisatiepogingen af te handelen en te beperken. De toepassing kan bijvoorbeeld de gebruiker de mogelijkheid bieden zijn poging te annuleren, waardoor de NetStream-verbinding kan worden gesloten. 5 Wanneer de gebruiker is geverifieerd, of als anonieme codering wordt gebruikt, haalt het DRM-subsysteem de
voucher op. Op basis van de bon wordt gecontroleerd of de gebruiker de inhoud mag bekijken. De informatie in de bon kan zowel voor geautoriseerde als voor anonieme gebruikers gelden. Voorbeeld: zowel geautoriseerde als anonieme gebruikers hebben slechts gedurende een bepaalde tijd toegang tot de inhoud. Het is ook mogelijk dat ze geen toegang hebben tot de inhoud omdat de leverancier van de inhoud de versie van de weergavetoepassing niet ondersteunt. Als er geen fout is opgetreden en de gebruiker is geautoriseerd om de inhoud weer te geven, verzendt het NetStreamobject een DRMStatusEvent-object en begint de AIR-toepassing het afspelen. Het DRMStatusEvent-object bevat de gerelateerde bongegevens die het beleid en de toegangsrechten voor de gebruiker identificeren. Voorbeeld: deze informatie geeft aan of de inhoud offline toegankelijk mag worden gemaakt, of wanneer de bon vervalt en de inhoud niet langer mag worden bekeken. De toepassing kan deze gegevens gebruiken om de gebruiker zijn status mee te delen. Voorbeeld: de toepassing kan in een statusbalk aangeven hoeveel dagen de gebruiker de inhoud nog kan bekijken. Als de gebruiker offline toegang heeft, wordt de bon in een cache geplaatst. De gecodeerde inhoud wordt naar het toestel van de gebruiker gedownload en toegankelijk gemaakt voor de gedefinieerde offline huurperiode. De eigenschap detail in de gebeurtenis bevat "DRM.voucherObtained". De toepassing bepaalt waar de inhoud lokaal wordt opgeslagen om deze vervolgens offline toegankelijk te maken. In AIR 1.5 kunt u vouchers ook vooraf laden met de klasse DRMManager. Alle DRM-gerelateerde fouten hebben tot gevolg dat de toepassing een DRMErrorEvent-gebeurtenisobject verzendt. AIR handelt de verificatieproblemen die zijn opgetreden tijdens het gebruik van de NetStream-methode setDRMAuthenticationCredentials() af door het DRMAuthenticationEvent-object opnieuw te verzenden. Alle andere foutgebeurtenissen moet expliciet worden afgehandeld door de toepassing. Bijvoorbeeld als de gebruiker geldige gegevens invoert maar de bon die de gecodeerde inhoud beveiligt, de toegang tot de inhoud beperkt. Voorbeeld: een geautoriseerde gebruiker heeft nog altijd geen toegang tot de inhoud omdat de rechten nog niet zijn betaald. Dit kan zich ook voordoen als twee gebruikers, die allebei geregistreerde leden van dezelfde media-uitgever zijn, inhoud proberen te delen waarvoor slechts een van de leden heeft betaald. De toepassing moet de gebruiker op de hoogte stellen van de fout, bijvoorbeeld beperkingen op de inhoud, en een alternatief bieden, zoals instructies om zich te registreren en te betalen om de inhoud te bekijken.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 286 Digitaal rechtenbeheer gebruiken
Bonnen voor offline afspelen vooraf laden U kunt de bonnen die nodig zijn om via DRM beschermde inhoud af te spelen, vooraf laden. Als gebruikers beschikken over vooraf geladen bonnen, kunnen ze de inhoud ook weergeven wanneer ze geen actieve internetverbinding hebben. (Voor het vooraf laden is uiteraard wel een internetverbinding vereist.) Gebruik de methode preloadEmbeddedMetadata() van de NetStream-klasse en de klasse AIR 1.5 DRMManager om vouchers op voorhand te laden. In de volgende stappen wordt de workflow beschreven voor het vooraf laden van een bon voor een via DRM beschermd mediabestand: 1 Download het mediabestand en sla het op. (DRM-metagegevens kunnen alleen vooraf worden geladen uit lokaal
opgeslagen bestanden.) 2 Maak de NetConnection- en NetStream-objecten en geef hierbij implementaties op voor de callback-functies onDRMContentData() en onPlayStatus() van het NetStream-clientobject.
3 Maak een NetStreamPlayOptions-object en stel de waarde van de eigenschap stream in op de URL van het lokale
mediabestand. 4 Roep de methode preloadEmbeddedMetadata() van NetStream aan en geef het NetStreamPlayOptions-object
door waarin het mediabestand wordt geïdentificeerd dat moet worden geparseerd. 5 Als het mediabestand DRM-metagegevens bevat, wordt de callback-functie onDRMContentData() aangeroepen.
De metagegevens worden doorgegeven naar deze functie in de vorm van een DRMContentData-object. 6 Gebruik het DRMContentData-object om de bon te verkrijgen met behulp van de methode loadVoucher() van
DRMManager. Als de eigenschap authenticationMethod van het DRMContentData-object de waarde userNameAndPassword heeft, moet u de gebruiker verifiëren op de mediarechtenserver voordat u de bon laadt. De eigenschappen serverURL en domain van het DRMContentData-object kunnen samen met de gebruikersreferenties worden doorgegeven aan de DRMManager-methode authenticate(). 7 De callback-functie onPlayStatus() wordt geactiveerd wanneer de bestandsparsering is voltooid. Als de functie onDRMContentData() niet wordt aangeroepen, bevat het bestand niet de vereiste metagegevens om een voucher te
verkrijgen (en is het mogelijk niet met DRM beveiligd). In de volgende code wordt geïllustreerd hoe u een DRM-bon vooraf kunt laden voor een lokaal mediabestand:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 287 Digitaal rechtenbeheer gebruiken
package { import flash.display.Sprite; import flash.events.DRMAuthenticationCompleteEvent; import flash.events.DRMAuthenticationErrorEvent; import flash.events.DRMErrorEvent; import flash.ev ents.DRMStatusEvent; import flash.events.NetStatusEvent; import flash.net.NetConnection; import flash.net.NetStream; import flash.net.NetStreamPlayOptions; import flash.net.drm.AuthenticationMethod; import flash.net.drm.DRMContentData; import flash.net.drm.DRMManager; import flash.net.drm.LoadVoucherSetting; public class DRMPreloader extends Sprite { private var videoURL:String = "app-storage:/video.flv"; private var userName:String = "user"; private var password:String = "password"; private var preloadConnection:NetConnection; private var preloadStream:NetStream; private var drmManager:DRMManager = DRMManager.getDRMManager(); private var drmContentData:DRMContentData; public function DRMPreloader():void { drmManager.addEventListener( DRMAuthenticationCompleteEvent.AUTHENTICATION_COMPLETE, onAuthenticationComplete ); drmManager.addEventListener( DRMAuthenticationErrorEvent.AUTHENTICATION_ERROR,onAuthenticationError ); drmManager.addEventListener(DRMStatusEvent.DRM_STATUS, onDRMStatus); drmManager.addEventListener(DRMErrorEvent.DRM_ERROR, onDRMError); preloadConnection = new NetConnection(); preloadConnection.addEventListener(NetStatusEvent.NET_STATUS, onConnect); preloadConnection.connect(null); } private function onConnect( event:NetStatusEvent ):void { preloadMetadata(); } private function preloadMetadata():void { preloadStream = new NetStream( preloadConnection ); preloadStream.client = this; var options:NetStreamPlayOptions = new NetStreamPlayOptions(); options.streamName = videoURL; preloadStream.preloadEmbeddedData( options ); } public function onDRMContentData( drmMetadata:DRMContentData ):void { drmContentData = drmMetadata; if ( drmMetadata.authenticationMethod == AuthenticationMethod.USERNAME_AND_PASSWORD ) { authenticateUser(); } else {
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 288 Digitaal rechtenbeheer gebruiken
Leden en gebeurtenissen van de klasse NetStream die betrekking hebben op DRM De klasse NetStream vormt een streamingverbinding in één richting tussen enerzijds Flash Player of een AIRtoepassing en anderzijds de Flash Media Server of het lokale bestandssysteem. (De klasse NetStream ondersteunt ook progressief downloaden.) Een NetStream-object is een kanaal binnen een NetConnection-object. In een AIRtoepassing verzendt de klasse NetStream vier gebeurtenissen die betrekking hebben op DRM:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 289 Digitaal rechtenbeheer gebruiken
Gebeurtenis
Beschrijving
drmAuthenticate
Deze gebeurtenis, die in de klasse DRMAuthenticateEvent is gedefinieerd, wordt verzonden als een NetStream-object inhoud met DRM-codering probeert weer te geven terwijl gebruikersgegevens voor de autorisatie vereist zijn om het afspelen te starten. De eigenschappen van deze gebeurtenissen zijn header, usernamePrompt, passwordPrompt en urlPrompt, waarmee de gebruikersgegevens kunnen worden verkregen en ingesteld. Deze gebeurtenis wordt herhaald tot het NetStream-object geldige gebruikersgegevens ontvangt.
drmError
Gedefinieerd in de klasse DRMErrorEvent en verzonden wanneer een NetStream-object dat probeert een DRM-gecodeerd bestand weer te geven, een DRM-gerelateerde fout aantreft. Voorbeeld: er wordt een gebeurtenisobject voor de DRM-fout verzonden als de gebruikersautorisatie mislukt. De reden hiervoor kan zijn dat de gebruiker geen rechten heeft gekocht om de inhoud te bekijken of dat de leverancier van de inhoud de weergavetoepassing niet ondersteunt.
drmStatus
Gedefinieerd in de klasse DRMStatusEvent en verzonden wanneer het afspelen van de DRM-gecodeerde inhoud begint (als de gebruiker geautoriseerd is om de inhoud af te spelen). Het DRMStatusEvent-object bevat informatie betreffende de bon, bijvoorbeeld of de inhoud offline toegankelijk mag worden gemaakt, of wanneer de bon vervalt en de inhoud niet langer mag worden bekeken.
status
Gedefinieerd in events.StatusEvent en alleen verzonden wanneer de toepassing DRM-gecodeerde inhoud probeert af te spelen door de methode NetStream.play() op te roepen. De waarde van de statuscodeeigenschap is "DRM.encryptedFLV".
De klasse NetStream bevat de volgende DRM-specifieke methoden: Methode
Beschrijving
resetDRMVouchers()
Verwijdert alle lokaal in de cache geplaatste DRM-bongegevens. De toepassing moet de bonnen opnieuw downloaden, anders kan de gebruiker de gecodeerde inhoud niet openen. De volgende code verwijdert bijvoorbeeld alle vouchers uit de cache: NetStream.resetDRMVouchers();
setDRMAuthenticationCredentials()
Geeft een reeks autorisatiegegevens, zoals gebruikersnaam, wachtwoord en autorisatietype, voor verificatie door aan het NetStream-object. Geldige autorisatietypen zijn "drm" en "proxy". Bij het autorisatietype "drm" worden de gegevens geverifieerd op de FMRMS. Bij het autorisatietype "proxy" worden de gegevens geverifieerd op de proxyserver. Ze moeten overeenkomen met de gegevens die door de proxyserver worden vereist. Voorbeeld: met de optie "proxy" kan de toepassing op een proxyserver verifiëren of een onderneming een dergelijke stap vereist vóór de gebruiker toegang verkrijgt tot internet. Tenzij anonieme autorisatie wordt gebruikt, moet de gebruiker na de proxy-autorisatie nog steeds door de FMRMS worden geautoriseerd om de bon te verkrijgen en de inhoud af te spelen. U kunt nogmaals setDRMAuthenticationcredentials() gebruiken (nu met de optie "drm") om te verifiëren op de FMRMS.
preloadEmbeddedMetadata()
Parseert een lokaal mediabestand op ingesloten metagegevens. Wanneer metagegevens worden gevonden die betrekking hebben op DRM, roept AIR de callback-functie onDRMContentData() aan.
Verder roept een NetStream-object de callback-functies onDRMContentData() en onPlayStatus() aan als resultaat van de aanroep naar de methode preloadEmbeddedMetaData(). De functie onDRMContentData() wordt aangeroepen wanneer DRM-metagegevens worden aangetroffen in een mediabestand. De functie onPlayStatus() wordt aangeroepen wanneer het bestand geheel geparseerd is. De functies onDRMContentData() en onPlayStatus() moeten worden gedefinieerd op het client-object dat is toegewezen aan de NetStream-instantie. Als u hetzelfde NetStream-object gebruikt om metagegevens op voorhand te laden en om inhoud af te spelen, moet u met het afspelen wachten op de aanroep van onPlayStatus() die door preloadEmbeddedMetaData() wordt gegenereerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 290 Digitaal rechtenbeheer gebruiken
In de volgende code zijn de gebruikersnaam (“administrator”), het wachtwoord (“password”) en het autorisatietype “drm” ingesteld om de gebruiker te autoriseren. De methode setDRMAuthenticationCredentials() moet gegevens bieden die overeenkomen met bekende gegevens en zijn aanvaard door de leverancier van de inhoud (dezelfde gebruikersgegevens die toestemming verlenen om de inhoud te bekijken). De code om de video af te spelen en het controleren of een verbinding met de videostroom tot stand is gebracht, is hier niet opgenomen. var connection:NetConnection = new NetConnection(); connection.connect(null); var videoStream:NetStream = new NetStream(connection); videoStream.addEventListener(DRMAuthenticateEvent.DRM_AUTHENTICATE, drmAuthenticateEventHandler) private function drmAuthenticateEventHandler(event:DRMAuthenticateEvent):void { videoStream.setDRMAuthenticationCredentials("administrator", "password", "drm"); }
De klasse DRMStatusEvent gebruiken Een NetStream-object verzendt een DRMStatusEvent-object wanneer de inhoud die met DRM is beveiligd, met succes begint af te spelen (als de bon en de gebruiker zijn geverifieerd en de gebruiker is geautoriseerd om de inhoud te bekijken). Het DRMStatusEvent-object wordt ook voor anonieme gebruikers verzonden als deze toegang mogen hebben. In de bongegevens wordt gecontroleerd of anonieme gebruikers, die geen autorisatie nodig hebben, toegang mogen hebben om de inhoud af te spelen. Om uiteenlopende redenen kan anonieme gebruikers de toegang worden geweigerd. Voorbeeld: een anonieme gebruiker heeft mogelijk geen toegang tot de inhoud omdat de weergaveperiode verstreken is. Het DRMStatusEvent-object bevat informatie betreffende de bon, bijvoorbeeld of de inhoud offline toegankelijk mag worden gemaakt, of wanneer de bon vervalt en de inhoud niet langer mag worden bekeken. De toepassing kan deze gegevens gebruiken om de beleidsstatus en de toestemmingen van de gebruiker door te geven.
DRMStatusEvent-eigenschappen De klasse DRMStatusEvent bevat de volgende eigenschappen: Eigenschap
Beschrijving
contentData
Een DRMContentData-object dat de DRM-metagegevens bevat die in de inhoud zijn ingesloten.
detail
Een tekenreeks die de context van de statusgebeurtenis verklaart. In DRM 1.0 is DRM.voucherObtained de enige geldige waarde.
isAnonymous
Geeft aan of de inhoud die met DRM-codering is beveiligd, toegankelijk is zonder dat de autorisatiegegevens van de gebruiker hoeven te worden opgevraagd (true) of dat deze wel moeten worden opgevraagd (false). De waarde "false" betekent dat de gebruiker een gebruikersnaam en wachtwoord moet opgeven die overeenkomen met de gebruikersnaam en het wachtwoord die bij de leverancier van de inhoud bekend zijn en door deze worden verwacht.
isAvailableOffline
Geeft aan of de inhoud die met DRM-codering is beveiligd, offline (true) of niet (false) toegankelijk mag worden gemaakt. Om digitaal beveiligde inhoud offline toegankelijk te kunnen maken, moet de bijbehorende bon in een cache worden geplaatst op het lokale toestel van de gebruiker.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 291 Digitaal rechtenbeheer gebruiken
Eigenschap
Beschrijving
isLocal
Geeft aan of de voucher die nodig is om de inhoud af te spelen, in de lokale cache is opgeslagen.
offlineLeasePeriod
Het resterende aantal dagen dat de inhoud offline mag worden bekeken.
policies
Een aangepast object dat aangepaste DRM-eigenschappen kan bevatten.
voucher
De DRMVoucher.
voucherEndDate
De absolute datum waarop de bon vervalt en de inhoud dus niet langer mag worden bekeken.
DRMStatusEvent-handlers maken In het volgende voorbeeld ziet u hoe u een gebeurtenishandler maakt die de statusinformatie van de DRM-inhoud doorstuurt naar het NetStream-object dat de gebeurtenis heeft gestart. Voeg deze gebeurtenishandler toe aan een NetStream-object dat naar de DRM-gecodeerde inhoud wijst. function drmStatusEventHandler(event:DRMStatusEvent):void { trace(event); } function drmStatusEventHandler(event:DRMStatusEvent):void { trace(event); }
De klasse DRMAuthenticateEvent gebruiken Het DRMAuthenticateEvent-object wordt verzonden wanneer een NetStream-object DRM-gecodeerde inhoud probeert af te spelen hoewel gebruikersgegevens voor autorisatie vereist zijn om het afspelen te kunnen starten. De DRMAuthenticateEvent-handler verzamelt de vereiste gegevens (gebruikersnaam, wachtwoord en type) en geeft deze waarden voor verificatie door aan de methode NetStream.setDRMAuthenticationCredentials(). Elke AIRtoepassing moet over een mechanisme beschikken om de gebruikersgegevens te verkrijgen. Voorbeeld: de toepassing kan een eenvoudige gebruikersinterface bieden om de gebruikersnaam en het wachtwoord in te voeren, en optioneel ook de typewaarde. De AIR-toepassing moet ook over een mechanisme beschikken om de herhaalde autorisatiepogingen af te handelen en te beperken.
DRMAuthenticateEvent-eigenschappen De klasse DRMAuthenticateEvent bevat de volgende eigenschappen: Eigenschap
Beschrijving
authenticationType
Geeft aan of de geleverde gegevens bedoeld zijn voor verificatie op de FMRMS ("drm") of op een proxyserver ("proxy"). Voorbeeld: met de optie "proxy" kan de toepassing op een proxyserver verifiëren of een onderneming een dergelijke stap vereist vóór de gebruiker toegang verkrijgt tot internet. Tenzij anonieme autorisatie wordt gebruikt, moet de gebruiker na de proxy-autorisatie nog steeds door de FMRMS worden geautoriseerd om de bon te verkrijgen en de inhoud af te spelen. U kunt nogmaals setDRMAuthenticationcredentials() gebruiken (nu met de optie "drm") om te verifiëren op de FMRMS.
header
De bestandsheader van de gecodeerde inhoud, geleverd door de server. Bevat informatie over de context van de gecodeerde inhoud.
netstream
Het NetStream-object dat deze gebeurtenis heeft geactiveerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 292 Digitaal rechtenbeheer gebruiken
Eigenschap
Beschrijving
passwordPrompt
Een prompt voor wachtwoordgegevens, geleverd door de server. De tekenreeks kan een instructie bevatten voor het vereiste type wachtwoord.
urlPrompt
Een prompt voor een URL-tekenreeks, geleverd door de server. De tekenreeks kan de locatie aangeven waarnaar de gebruikersnaam en het wachtwoord worden verzonden.
usernamePrompt
Een prompt voor gebruikersnaamgegevens, geleverd door de server. De tekenreeks kan een instructie bevatten voor het vereiste type gebruikersnaam. Voorbeeld: een leverancier van inhoud kan een e-mailadres als gebruikersnaam vereisen.
DRMAuthenticateEvent-handlers maken In het volgende voorbeeld ziet u hoe u een gebeurtenishandler maakt die een reeks hard-gecodeerde autorisatiegegevens doorgeeft aan het NetStream-object dat de gebeurtenis heeft gestart. (De code om de video af te spelen en het controleren of een verbinding met de videostroom tot stand is gebracht, is hier niet opgenomen.) var connection:NetConnection = new NetConnection(); connection.connect(null); var videoStream:NetStream = new NetStream(connection); videoStream.addEventListener(DRMAuthenticateEvent.DRM_AUTHENTICATE, drmAuthenticateEventHandler) private function drmAuthenticateEventHandler(event:DRMAuthenticateEvent):void { videoStream.setDRMAuthenticationCredentials("administrator", "password", "drm"); }
Interfaces maken om gebruikersgegevens op te vragen Als gebruikersautorisatie vereist is voor DRM-inhoud, moet de AIR-toepassing de autorisatiegegevens van de gebruiker doorgaans via een gebruikersinterface opvragen.
De klasse DRMErrorEvent gebruiken AIR verstuurt een DRMErrorEvent-object wanneer een NetStream-object dat een DRM-gecodeerd bestand probeert af te spelen, een DRM-gerelateerde fout aantreft. Als de gebruikersgegevens ongeldig zijn, handelt het DRMAuthenticateEvent-object de fout af door herhaaldelijk te verzenden tot de gebruiker geldige gegevens invoert of de AIR-toepassing geen nieuwe pogingen meer toestaat. De toepassing moet naar eventuele andere DRMfoutgebeurtenissen luisteren om de DRM-gerelateerde fouten te detecteren, te identificeren en af te handelen. Als een gebruiker geldige gegevens invoert, is het mogelijk dat deze de gecodeerde inhoud nog altijd niet mag bekijken, afhankelijk van de voorwaarden van de DRM-bon. Voorbeeld: als de gebruiker de inhoud probeert te bekijken in een niet-geautoriseerde toepassing, met andere woorden een toepassing die niet is goedgekeurd door de uitgever van de gecodeerde inhoud. In dat geval wordt een DRMErrorEvent-object verzonden. De foutgebeurtenissen kunnen ook worden gegenereerd als de inhoud beschadigd is of als de versie van de toepassing niet overeenkomt met de versie die door de bon is opgegeven. De toepassing moet over een mechanisme beschikken om fouten af te handelen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 293 Digitaal rechtenbeheer gebruiken
DRMErrorEvent-eigenschappen De volgende tabel beschrijft de fouten die door het DRMErrorEvent-object worden gemeld: Code grote fout
Code kleine fout
Foutdetails
1001
niet gebruikt
Gebruikersverificatie mislukt.
1002
niet gebruikt
De FMRMS (Flash Media Rights Management Server) biedt geen ondersteuning voor SSL (Secure Sockets Layer).
1003
niet gebruikt
De weergaveperiode voor de inhoud is verstreken en de inhoud kan niet langer worden bekeken.
1004
niet gebruikt
Probleem met gebruikersautorisatie. Dit probleem doet zich bijvoorbeeld voor als de gebruiker de inhoud niet heeft gekocht en dus geen rechten heeft om de inhoud te bekijken.
1005
niet gebruikt
1006
niet gebruikt
Een update van de client is vereist, met andere woorden voor de FMRMS is een nieuwe DRMengine (Digital Rights Management) vereist.
1007
niet gebruikt
Algemene interne fout.
1008
Gedetailleerde decoderingsfoutcode
Verkeerde licentiesleutel.
1009
niet gebruikt
FLV-inhoud is beschadigd.
1010
niet gebruikt
1011
niet gebruikt
De versie van de toepassing komt niet overeen met de versie die in het beleid is opgegeven.
1012
niet gebruikt
Verificatie van de bon voor de gecodeerde inhoud is mislukt. Mogelijk is de inhoud beschadigd.
1013
niet gebruikt
De bon voor de gecodeerde inhoud kan niet worden opgeslagen.
1014
niet gebruikt
Verificatie van de integriteit van de FLV-header is mislukt. Mogelijk is de inhoud beschadigd.
Code grote fout
Code kleine fout
3300
Foutcode Adobe Policy Server
De toepassing heeft een ongeldige bon voor de inhoud gedetecteerd.
3301
niet gebruikt
Gebruikersverificatie mislukt.
3302
niet gebruikt
De FMRMS (Flash Media Rights Management Server) biedt geen ondersteuning voor SSL (Secure Sockets Layer).
3303
niet gebruikt
De weergaveperiode voor de inhoud is verstreken en de inhoud kan niet langer worden bekeken.
Server URL
publisherID:applicationID
Foutdetails
Beschrijving
Kan geen verbinding maken met de server.
De id van de weergavetoepassing is geen geldige id die door de uitgever van de inhoud wordt ondersteund.
Beschrijving
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 294 Digitaal rechtenbeheer gebruiken
Code grote fout
Code kleine fout
Foutdetails
Beschrijving
3304
niet gebruikt
3305
niet gebruikt
3306
niet gebruikt
Een update van de client is vereist, met andere woorden voor de FMRMS is een nieuwe DRMengine (Digital Rights Management) vereist.
3307
niet gebruikt
Algemeen intern DRM-probleem.
3308
Gedetailleerde decoderingsfoutcode
Verkeerde licentiesleutel.
3309
niet gebruikt
Flash-video-inhoud is beschadigd.
3310
niet gebruikt
publisherID:applicationID
De id van de weergavetoepassing is geen geldige id die door de uitgever van de inhoud wordt ondersteund. Met andere woorden de weergavetoepassing wordt niet ondersteund door de leverancier van de inhoud.
3311
niet gebruikt
min=x:max=y
De versie van de toepassing komt niet overeen met de versie die in de bon is opgegeven.
3312
niet gebruikt
Verificatie van de bon voor de gecodeerde inhoud is mislukt. Mogelijk is de inhoud beschadigd.
3313
niet gebruikt
De bon voor de gecodeerde inhoud kan niet worden opgeslagen in Microsafe.
3314
niet gebruikt
Verificatie van de integriteit van de FLV-header is mislukt. Mogelijk is de inhoud beschadigd.
3315
niet gebruikt
Extern afspelen van de DRM-beveiligde inhoud is niet toegestaan.
3316
niet gebruikt
Ontbrekende AdobeCP-module.
3317
niet gebruikt
Laden van AdobeCP-module is mislukt.
3318
niet gebruikt
Niet-compatibele AdobeCP-versie gevonden.
3319
niet gebruikt
Ontbrekend AdobeCP API-ingangspunt.
3320
niet gebruikt
AdobeCP-module is niet geverifieerd.
Probleem met gebruikersautorisatie. Kan zich ook voordoen als de gebruiker geautoriseerd is, bijvoorbeeld als de gebruiker geen rechten heeft gekocht om de inhoud te bekijken. Server URL
Kan geen verbinding maken met de server.
DRMErrorEvent-handlers maken In het volgende voorbeeld ziet u hoe u een gebeurtenishandler maakt voor het NetStream-object dat de gebeurtenis heeft gestart. Deze gebeurtenishandler wordt opgeroepen als de NetStream een fout aantreft wanneer wordt geprobeerd DRM-gecodeerde inhoud af te spelen. Als een toepassing een fout aantreft, probeert deze normaal gesproken een aantal opschoningstaken uit te voeren, wordt de gebruiker op de hoogte gebracht van de fout en biedt de toepassing keuzemogelijkheden om het probleem op te lossen. private function drmErrorEventHandler(event:DRMErrorEvent):void { trace(event.toString()); }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 295 Digitaal rechtenbeheer gebruiken
De klasse DRMManager gebruiken Gebruik de klasse DRMManager voor het beheer van bonnen en mediarechtenserver-sessies in een AIR-toepassing. De klasse DRMManager is beschikbaar in AIR versie 1.5 of hoger. Beheer van bonnen Wanneer een gebruiker online een via DRM beschermd mediabestand afspeelt, haalt AIR de licentiebon op die nodig is om de inhoud weer te geven; deze bon wordt opgeslagen in de cache. Als de toepassing het bestand lokaal opslaat en de bon offline afspelen toestaat, kan de gebruiker de inhoud ook afspelen als er geen verbinding met de mediarechtenserver beschikbaar is. Door gebruik te maken van de methode preloadEmbeddedMetadata() van DRMManager en NetStream, kunt u de bon vooraf in de cache opslaan zodat de toepassing niet het afspelen hoeft op te starten om de licentie te verkrijgen die nodig is om de inhoud weer te geven. Uw toepassing zou bijvoorbeeld het mediabestand kunnen downloaden en dan de bon ophalen terwijl de gebruiker nog online is. Om een bon vooraf te laden, gebruikt u de methode preloadEmbeddedMetadata() van NetStream om een DRMContentData-object te verkrijgen. Het DRMContentData-object bevat de URL en het domein van de mediarechtenserver die de licentie kan verstrekken. Verder wordt in dit object aangegeven of verificatie van de gebruiker vereist is. Met deze informatie kunt u de methode loadVoucher() van DRMManager aanroepen om de bon te verkrijgen en in de cache op te slaan. De workflow voor het vooraf laden van bonnen wordt gedetailleerd beschreven in “Bonnen voor offline afspelen vooraf laden” op pagina 286. Sessiebeheer U kunt de DRMManager ook gebruiken om de gebruiker te verifiëren bij een mediarechtenserver en om blijvende sessies te beheren. Roep de methode authenticate() van DRMManager aan om een sessie met de mediarechtenserver tot stand te brengen. Wanneer de verificatie voltooid is, verzendt de DRMManager een DRMAuthenticationCompleteEventobject. Dit object bevat een sessietoken. U kunt dit token opslaan om toekomstige sessies mee tot stand te brengen zodat de gebruiker niet zijn accountdetails hoeft op te geven. Geef het token door aan de methode setAuthenticationToken() om een nieuwe geverifieerde sessie tot stand te brengen. (Het verlopen van het token en andere attributen worden bepaald door de instellingen van de server die het token genereert. De gegevensstructuur van het token is niet bedoeld om te worden geïnterpreteerd door de AIR-toepassingscode en kan in toekomstige AIRupdates worden gewijzigd.) Verificatietokens kunnen worden overgebracht naar andere computers. Om tokens te beschermen kunt u ze opslaan in de door AIR gecodeerde lokale opslag. Zie “Gecodeerde gegevens opslaan” op pagina 220 voor meer informatie.
DRMStatus-gebeurtenissen De DRMManager verzendt een DRMStatusEvent-object wanneer een aanroep naar de methode loadVoucher() met succes wordt voltooid. Als een voucher is verkregen, heeft de eigenschap detail van het gebeurtenisobject de volgende waarde: "DRM.voucherObtained", en bevat de eigenschap voucher het DRMVoucher-object. Als geen voucher is verkregen, heeft de eigenschap detail nog steeds de volgende waarde: "DRM.voucherObtained"; de eigenschap voucher is dan echter null. Een bon wordt bijvoorbeeld niet verkregen als u de LoadVoucherSetting van localOnly gebruikt en er geen bon lokaal in de cache is opgeslagen. Als de aanroep naar loadVoucher() niet met succes is voltooid, bijvoorbeeld vanwege een verificatie- of communicatiefout, verzendt de DRMManager in plaats daarvan een DRMErrorEvent-object.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 296 Digitaal rechtenbeheer gebruiken
DRMAuthenticationComplete-gebeurtenissen De DRMManager verzendt een DRMAuthenticationCompleteEvent-object wanneer een gebruiker met succes is verifieerd middels een aanroep van de methode authenticate(). In AIR 1.5 bevat het DRMAuthenticationCompleteEvent-object een herbruikbare token waarmee gebruikersverificatie tijdens toepassingsessies bewaard kan blijven. Geef deze token door aan de DRMManagermethode setAuthenticationToken() als u een sessie opnieuw tot stand wilt brengen. (Tokenkenmerken, zoals vervaldatum, worden ingesteld door de maker van de token. AIR heeft geen API om tokenkenmerken te controleren.)
DRMAuthenticationError-gebeurtenissen De DRMManager verzendt een DRMAuthenticationErrorEvent-object wanneer een gebruiker niet kan worden geverifieerd via een aanroep naar de methode authenticate() of setAuthenticationToken().
De klasse DRMContentData gebruiken Het DRMContentData-object bevat de eigenschap metadata van een via DRM beschermd mediabestand. De DRMContentData-eigenschappen bevatten de informatie die nodig is om een licentiebon voor het weergeven van de inhoud te verkrijgen.
297
Hoofdstuk 26: Opties voor het starten en sluiten van toepassingen In deze sectie worden opties en overwegingen voor het starten van een geïnstalleerde Adobe® AIR™-toepassing en voor het sluiten van een actieve toepassing besproken.
Toepassingen oproepen Een AIR-toepassing wordt opgeroepen wanneer de gebruiker (of het besturingssysteem):
• de toepassing start vanaf het bureaublad; • de toepassing gebruikt als een opdracht op een opdrachtregel; • een type bestand opent waarvoor de toepassing de standaardtoepassing is; • (Mac OS X) op het toepassingspictogram in de dock-balk klikt (ongeacht of de toepassing is gestart); • de toepassing start vanuit het installatieprogramma (aan het einde van een nieuw installatieproces of na het dubbelklikken op het AIR-bestand voor een geïnstalleerde toepassing);
• een AIR-toepassing begint te updaten wanneer de geïnstalleerde versie heeft aangegeven dat deze zelf toepassingsupdates verwerkt (door <customUpdateUI>true op te nemen in het descriptorbestand van de toepassing);
• een webpagina bezoekt waarop zich een Flash-badge of -toepassing bevindt die de methode com.adobe.air.AIR launchApplication() oproept met de identificatiegegevens voor de AIR-toepassing. (Oproepen vanuit de
browser is alleen mogelijk als in de toepassingsdescriptor ook de declaratie true is opgenomen.) Zie “Geïnstalleerde AIRtoepassingen starten vanuit de browser” op pagina 327. Wanneer een AIR-toepassing wordt opgeroepen, wordt een InvokeEvent-object van het type invoke verzonden via het NativeApplication-singletonobject. Om een toepassing tijd te geven zichzelf te starten en een gebeurtenislistener te registreren, worden gebeurtenissen van het type invoke in de wachtrij geplaatst in plaats van verzonden. Zodra een listener is geregistreerd, worden alle gebeurtenissen in de wachtrij afgeleverd. Opmerking: Wanneer een toepassing wordt opgeroepen met de browseroproepfunctie, verzendt het NativeApplicationobject de gebeurtenis van het type invoke alleen als de toepassing nog niet wordt uitgevoerd. Zie “Geïnstalleerde AIRtoepassingen starten vanuit de browser” op pagina 327. Roep de methode addEventListener() van het NativeApplication-object (NativeApplication.nativeApplication) op om gebeurtenissen van het type invoke te ontvangen. Wanneer een gebeurtenislistener een gebeurtenis van het type invoke heeft geregistreerd, ontvangt deze ook alle gebeurtenissen van het type invoke die vóór de registratie zijn opgetreden. Gebeurtenissen van het type invoke in de wachtrij worden een voor een, kort na elkaar verzonden nadat het oproepen van addEventListener() is uitgevoerd. Als er een nieuwe gebeurtenis van het type invoke optreedt tijdens dit proces, kan deze worden verzonden voordat een of meer gebeurtenissen in de wachtrij zijn verzonden. Omdat gebeurtenissen in een wachtrij worden opgeslagen, kunt u alle opgetreden gebeurtenissen van het type invoke verwerken voordat uw initialisatiecode wordt uitgevoerd. Denk eraan dat als u later tijdens de uitvoering (na het initialiseren van de toepassing) een gebeurtenislistener toevoegt, deze nog steeds alle gebeurtenissen van het type invoke ontvangt die zijn opgetreden sinds de toepassing is gestart.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 298 Opties voor het starten en sluiten van toepassingen
Er wordt slechts één instantie van een AIR-toepassing gestart. Wanneer een toepassing die al is gestart opnieuw wordt opgeroepen, wordt een nieuwe gebeurtenis van het type invoke verzonden naar de gestarte instantie. Het is de verantwoordelijkheid van een AIR-toepassing om te reageren op een gebeurtenis van het type invoke en de juiste actie uit te voeren (zoals het openen van een nieuw documentvenster). Een InvokeEvent-object bevat alle argumenten die aan de toepassing worden doorgegeven en ook de map van waaruit de toepassing is opgeroepen. Als de toepassing is opgeroepen via een gekoppeld bestandstype, wordt het volledige pad naar het bestand opgenomen in de opdrachtregelargumenten. Als de toepassing is opgeroepen via een toepassingsupdate, wordt het volledige pad naar het AIR-updatebestand opgenomen. Wanneer meer bestanden in één bewerking worden geopend, wordt een enkel InvokeEvent-object verzonden op Mac OS X. Elk bestand is opgenomen in de array arguments. In Windows en Linux wordt voor elk bestand een afzonderlijk InvokeEvent-object verzonden. Uw toepassing kan gebeurtenissen van het type invoke verwerken door een listener te registreren met het NativeApplication-object: NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvokeEvent); air.NativeApplication.nativeApplication.addEventListener(air.InvokeEvent.INVOKE, onInvokeEvent);
En een gebeurtenislistener te definiëren: var arguments:Array; var currentDir:File; public function onInvokeEvent(invocation:InvokeEvent):void { arguments = invocation.arguments; currentDir = invocation.currentDirectory; }
Opdrachtregelargumenten vastleggen De opdrachtregelargumenten die bij het oproepen van een AIR-toepassing horen, worden afgeleverd in de gebeurtenis invoke die wordt verzonden door het NativeApplication-object. De eigenschap InvokeEvent.arguments bevat een array met de argumenten die door het besturingssysteem worden doorgegeven wanneer een AIR-toepassing wordt opgeroepen. Als de argumenten relatieve bestandspaden bevatten, kunt u de paden gewoonlijk omzetten met de eigenschap currentDirectory. De argumenten die aan een AIR-programma worden doorgegeven, worden behandeld als met spaties gescheiden tekenreeksen, tenzij ze tussen dubbele aanhalingstekens staan: Argumenten
Array
tik tak
{tik,tak}
tik "tik tak"
{tik,tik tak}
"tik" “tak”
{tik,tak}
\"tik\" \"tak\"
{"tik","tak"}
De eigenschap InvokeEvent.currentDirectory bevat een File-object dat de map vertegenwoordigt van waaruit de toepassing is gestart.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 299 Opties voor het starten en sluiten van toepassingen
Wanneer een toepassing wordt opgeroepen omdat een bestandstype wordt geopend dat door de toepassing is geregistreerd, wordt het oorspronkelijke pad naar het bestand als een tekenreeks opgenomen in de opdrachtregelargumenten. (Uw toepassing is verantwoordelijk voor het openen van het bestand of het uitvoeren van de gewenste bewerking.) Wanneer een toepassing is geprogrammeerd om zichzelf te updaten (en niet afhankelijk is van de standaard gebruikersinterface voor AIR-updates), wordt het oorspronkelijke pad naar het AIR-bestand opgenomen wanneer een gebruiker dubbelklikt op een AIR-bestand dat een toepassing met een overeenkomende toepassings-id bevat. U kunt het bestand openen met de methode resolve() van het File-object currentDirectory: if((invokeEvent.currentDirectory != null)&&(invokeEvent.arguments.length > 0)){ dir = invokeEvent.currentDirectory; fileToOpen = dir.resolvePath(invokeEvent.arguments[0]); }
U moet ook controleren of een argument inderdaad een pad naar een bestand is.
Voorbeeld: logboek met oproepgebeurtenissen In het volgende voorbeeld ziet u hoe u listeners voor de invoke-gebeurtenis registreert en deze verwerkt. In het voorbeeld worden alle ontvangen oproepgebeurtenissen in het logboek geregistreerd en worden de huidige map en opdrachtregelargumenten weergegeven. Opmerking: Als u het volgende voorbeeld wilt maken met Adobe® Flash® CS3 Professional of Adobe® Flash® CS4 Professional, maakt u eerst een Flash-bestand (Adobe AIR). Voer in het deelvenster Instellingen van ActionScript 3.0 (Bestand > Publicatie-instellingen... > knop Instellingen) in het veld Documentklasse de naam InvokeEventLogExample in. Sla het FLA-bestand op met de naam InvokeEventLogExample.fla. Maak vervolgens een ActionScript-bestand in dezelfde map. Voer de volgende code in het ActionScript-bestand in en sla het bestand op met de naam InvokeEventLogExample.as. package { import import import import
public class InvokeEventLogExample extends Sprite { public var log:TextField; public function InvokeEventLogExample() { log = new TextField(); log.x = 15; log.y = 15; log.width = 520; log.height = 370; log.background = true; addChild(log); NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke); } public function onInvoke(invokeEvent:InvokeEvent):void
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 300 Opties voor het starten en sluiten van toepassingen
{ var now:String = new Date().toTimeString(); logEvent("Invoke event received: " + now); if (invokeEvent.currentDirectory != null) { logEvent("Current directory=" + invokeEvent.currentDirectory.nativePath); } else { logEvent("--no directory information available--"); } if (invokeEvent.arguments.length > 0) { logEvent("Arguments: " + invokeEvent.arguments.toString()); } else { logEvent("--no arguments--"); } } public function logEvent(entry:String):void { log.appendText(entry + "\n"); trace(entry); } } }
Starten bij aanmelden Een AIR-toepassing kan automatisch worden gestart wanneer de huidige gebruiker zich aanmeldt, door NativeApplication.nativeApplication.startAtLogin=true in te stellen. Wanneer dit is ingesteld, wordt de toepassing automatisch gestart wanneer de gebruiker zich aanmeldt. Dit blijft zo totdat de instelling in false wordt gewijzigd, de gebruiker de instelling handmatig wijzigt via het besturingssysteem of de toepassing wordt verwijderd. Starten bij aanmelden is een runtime-instelling. Opmerking: De toepassing wordt niet gestart wanneer de computer wordt opgestart. De toepassing wordt gestart wanneer de gebruiker zich aanmeldt. De instelling geldt alleen voor de huidige gebruiker. De toepassing moet ook zijn geïnstalleerd voordat de eigenschap startAtLogin op true kan worden ingesteld. Er wordt een fout gemeld als de eigenschap wordt ingesteld wanneer een toepassing niet is geïnstalleerd (bijvoorbeeld als deze wordt gestart met ADL).
Oproepen vanuit browser Met de browseroproepfunctie kan een website een geïnstalleerde AIR-toepassing starten vanuit de browser. Oproepen vanuit de browser is alleen toegestaan als allowBrowserInvocation op true is ingesteld in het descriptorbestand van de toepassing: true
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 301 Opties voor het starten en sluiten van toepassingen
Zie “Eigenschappen van AIR-toepassingen instellen” op pagina 45 voor meer informatie over het descriptorbestand van de toepassing. Wanneer de toepassing wordt opgeroepen vanuit de browser, verzendt het NativeApplication-object van de toepassing een BrowserInvokeEvent-object. Als u BrowserInvokeEvent-gebeurtenissen wilt ontvangen, roept u de methode addEventListener() van het NativeApplication-object (NativeApplication.nativeApplication) op in de AIR-toepassing. Wanneer een gebeurtenislistener een BrowserInvokeEvent-gebeurtenis heeft geregistreerd, ontvangt deze ook alle BrowserInvokeEvent-gebeurtenissen die vóór de registratie zijn opgetreden. Deze gebeurtenissen worden verzonden nadat addEventListener() is uitgevoerd, maar niet noodzakelijkerwijs vóór andere BrowserInvokeEventgebeurtenissen die na de registratie zijn ontvangen. Zo kunt u BrowserInvokeEvent-gebeurtenissen verwerken die zijn opgetreden voordat uw initialisatiecode is uitgevoerd (bijvoorbeeld wanneer de toepassing is opgeroepen vanuit de browser). Denk eraan dat als u later tijdens de uitvoering (na het initialiseren van de toepassing) een gebeurtenislistener toevoegt, deze nog steeds alle BrowserInvokeEvent-gebeurtenissen ontvangt die zijn opgetreden sinds de toepassing is gestart. Het BrowserInvokeEvent-object bevat de volgende eigenschappen: Eigenschap
Beschrijving
arguments
Een array van argumenten (tekenreeksen) die worden doorgegeven aan de toepassing.
isHTTPS
Geeft aan of de inhoud in de browser gebruikmaakt van het URL-schema HTTPS (true) of niet (false).
isUserEvent
Geeft aan of de browseroproep heeft geleid tot een gebruikersgebeurtenis (zoals een muisklik). In AIR 1.0 wordt deze eigenschap altijd ingesteld op true; in AIR is een gebruikersgebeurtenis vereist voor de browseroproepfunctie.
sandboxType
Het sandboxtype voor de inhoud in de browser. Geldige waarden zijn dezelfde waarden die kunnen worden gebruikt in de eigenschap Security.sandboxType en dit zijn:
•
Security.APPLICATION: de inhoud bevindt zich in de toepassingsbeveiligingssandbox.
•
Security.LOCAL_TRUSTED: de inhoud bevindt zich in de lokaal-vertrouwde beveiligingssandbox.
•
Security.LOCAL_WITH_FILE: de inhoud bevindt zich in de lokaal-met-bestandssysteem
beveiligingssandbox.
•
Security.LOCAL_WITH_NETWORK: de inhoud bevindt zich in de lokaal-met-netwerk
beveiligingssandbox.
• securityDomain
Security.REMOTE: de inhoud bevindt zich in een extern (netwerk)domein.
Het beveiligingsdomein voor de inhoud van de browser, zoals "www.adobe.com" of "www.voorbeeld.org". Deze eigenschap wordt alleen ingesteld voor de inhoud van de externe beveiligingssandbox (voor inhoud afkomstig van een netwerkdomein). De eigenschap wordt niet ingesteld voor de inhoud van een lokale of een toepassingsbeveiligingssandbox.
Als u de browseroproepfunctie gebruikt, moet u rekening houden met de gevolgen voor de beveiliging. Wanneer een website een AIR-toepassing start, kan deze gegevens verzenden via de eigenschap arguments van het BrowserInvokeEvent-object. Wees voorzichtig wanneer u deze gegevens gebruikt bij gevoelige bewerkingen, zoals API's die bestanden of code laden. Het risico is afhankelijk van wat de toepassing met de gegevens doet. Als u verwacht dat alleen een bepaalde website de toepassing oproept, moet de toepassing de eigenschap securityDomain van het BrowserInvokeEvent-object controleren. U kunt ook eisen dat de website die de toepassing oproept, gebruikmaakt van HTTPS. Dit kunt u controleren met de eigenschap isHTTPS van het BrowserInvokeEvent-object. De toepassing moet de doorgegeven gegevens valideren. Als een toepassing bijvoorbeeld verwacht dat URL's naar een bepaald domein worden doorgegeven, moet de toepassing controleren of de URL's echt naar dat domein verwijzen. Dit kan voorkomen dat een aanvaller de toepassing ertoe overhaalt vertrouwelijke gegevens te verzenden.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 302 Opties voor het starten en sluiten van toepassingen
Een toepassing moet geen BrowserInvokeEvent-argumenten gebruiken die naar lokale bronnen verwijzen. Een toepassing moet bijvoorbeeld geen File-objecten maken die zijn gebaseerd op een pad dat vanuit de browser is doorgegeven. Als wordt verwacht dat externe paden vanuit de browser worden doorgegeven, moet de toepassing ervoor zorgen dat in de paden niet het protocol file:// wordt gebruikt in plaats van een extern protocol. Zie “Geïnstalleerde AIR-toepassingen starten vanuit de browser” op pagina 327 voor meer informatie over het oproepen van een toepassing vanuit de browser.
Toepassingen beëindigen U kunt een toepassing het snelst beëindigen door NativeApplication.nativeApplication.exit() op te roepen. Dit werkt prima als uw toepassing geen gegevens hoeft op te slaan of externe bronnen hoeft op te ruimen. Als u exit() oproept, worden alle vensters gesloten en wordt de toepassing beëindigd. Als vensters of andere componenten van de toepassing echter het beëindigingsproces mogen onderbreken, bijvoorbeeld om essentiële gegevens op te slaan, moet u de juiste waarschuwingsgebeurtenissen verzenden voordat u exit() oproept. Een toepassing kan ook netjes worden afgesloten door een enkel uitvoeringspad op te geven dat onafhankelijk is van de manier waarop het afsluitingsproces is gestart. De gebruiker (of het besturingssysteem) kan het beëindigen van de toepassing op de volgende manieren activeren:
• door het laatste toepassingsvenster te sluiten wanneer NativeApplication.nativeApplication.autoExit op true is ingesteld;
• door de opdracht Afsluiten van de toepassing te selecteren vanuit het besturingssysteem, bijvoorbeeld wanneer de gebruiker de opdracht Afsluiten kiest in het standaardmenu. Dit gebeurt alleen in Mac OS. Windows en Linux beschikken niet over een opdracht om de toepassing af te sluiten via de systeeminterface.
• door de computer af te sluiten. Wanneer op een van deze manieren een afsluitopdracht wordt overgebracht via het besturingssysteem, verzendt NativeApplication de gebeurtenis exiting. Als geen enkele listener de gebeurtenis exiting annuleert, worden alle geopende vensters gesloten. Elk venster verzendt de gebeurtenis closing en de gebeurtenis close. Als een van de vensters de gebeurtenis closing annuleert, stopt het afsluitproces. Als de volgorde waarin vensters worden gesloten belangrijk is voor de toepassing, luistert u naar de gebeurtenis exiting van NativeApplication en sluit u de vensters zelf in de juiste volgorde. Dit is bijvoorbeeld het geval als u een documentvenster met gereedschapspaletten hebt. Het kan lastig, of erger, zijn als de paletten door het systeem worden gesloten maar de gebruiker besluit de afsluitopdracht te annuleren om gegevens op te slaan. In Windows ontvangt u de gebeurtenis exiting alleen nadat het laatste venster is gesloten (wanneer de eigenschap autoExit van het NativeApplication-object is ingesteld op true). Houd u aan de volgende aanbevolen procedures voor het afsluiten van een toepassing, zodat het gedrag consistent is voor alle platformen, of de afsluitopdracht nu wordt geactiveerd via de interface van het besturingssysteem, menuopdrachten of logica in de toepassing: 1 Verzend altijd de gebeurtenis exiting via het NativeApplication-object voordat exit() wordt opgeroepen in de
code van de toepassing en controleer of geen andere component van de toepassing de gebeurtenis annuleert. public function applicationExit():void { var exitingEvent:Event = new Event(Event.EXITING, false, true); NativeApplication.nativeApplication.dispatchEvent(exitingEvent); if (!exitingEvent.isDefaultPrevented()) { NativeApplication.nativeApplication.exit(); } }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 303 Opties voor het starten en sluiten van toepassingen
2 Luister naar de gebeurtenis exiting van de toepassing vanuit het NativeApplication.nativeApplication-
object en sluit in de handler alle vensters (verzend eerst de gebeurtenis closing). Voer alle benodigde opruimtaken uit, zoals het opslaan van toepassingsgegevens of het verwijderen van tijdelijke bestanden, nadat alle vensters zijn gesloten. Gebruik tijdens het opruimen alleen synchrone methoden, zodat u zeker weet dat deze zijn voltooid voordat de toepassing wordt afgesloten. Als de volgorde waarin de vensters worden gesloten niet belangrijk is, kunt u de array NativeApplication.nativeApplication.openedWindows doorlopen en elk venster achtereenvolgens sluiten. Als de volgorde wel belangrijk is, moet u zorgen dat de vensters in de juiste volgorde worden gesloten. private function onExiting(exitingEvent:Event):void { var winClosingEvent:Event; for each (var win:NativeWindow in NativeApplication.nativeApplication.openedWindows) { winClosingEvent = new Event(Event.CLOSING,false,true); win.dispatchEvent(winClosingEvent); if (!winClosingEvent.isDefaultPrevented()) { win.close(); } else { exitingEvent.preventDefault(); } } if (!exitingEvent.isDefaultPrevented()) { //perform cleanup } }
3 Vensters moeten altijd hun eigen opruimtaken uitvoeren door te luisteren naar hun eigen closing-gebeurtenissen. 4 Gebruik slechts één exiting-listener in uw toepassing, omdat handlers die eerder zijn opgeroepen niet kunnen
weten of volgende handlers de gebeurtenis exiting zullen annuleren (en het zou onverstandig zijn om te vertrouwen op de volgorde van uitvoering).
Zie ook “Eigenschappen van AIR-toepassingen instellen” op pagina 45 “Aangepaste gebruikersinterfaces voor toepassingsupdates presenteren” op pagina 338
304
Hoofdstuk 27: Toepassingsinstellingen lezen Tijdens de runtime kunt u eigenschappen van het descriptorbestand van de toepassing evenals de uitgevers-id voor een toepassing ophalen. Deze zijn ingesteld in de eigenschappen applicationDescriptor en publisherID van het NativeApplication-object.
Het descriptorbestand van de toepassing lezen U kunt het descriptorbestand van de toepassing die momenteel wordt uitgevoerd, lezen als een XML-object door de eigenschap applicationDescriptor van het NativeApplication-object op te halen, zoals hieronder wordt geïllustreerd: var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor;
U hebt daarna als volgt toegang tot de gegevens van het descriptorbestand van de toepassing in de vorm van een XMLobject (E4X): var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor; var ns:Namespace = appXml.namespace(); var appId = appXml.ns::id[0]; var appVersion = appXml.ns::version[0]; var appName = appXml.ns::filename[0]; air.trace("appId:", appId); air.trace("version:", appVersion); air.trace("filename:", appName); var xmlString = air.NativeApplication.nativeApplication.applicationDescriptor;
Zie “De structuur van het descriptorbestand van de toepassing” op pagina 45 voor meer informatie.
Toepassings- en uitgevers-id's ophalen De toepassings- en uitgevers-id's identificeren samen op unieke wijze een AIR-toepassing. U kunt de toepassings-id opgeven in het element van de toepassingsdescriptor. De uitgevers-id wordt afgeleid van het certificaat waarmee het AIR-installatiepakket is ondertekend. De toepassings-id kan uit de eigenschap id van het NativeApplication-object worden gelezen, zoals geïllustreerd in de volgende code: trace(NativeApplication.nativeApplication.applicationID);
De uitgevers-id kan uit de eigenschap publisherID van het NativeApplication-object worden gelezen: trace(NativeApplication.nativeApplication.publisherID);
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 305 Toepassingsinstellingen lezen
Opmerking: Als een AIR-toepassing met ADL wordt uitgevoerd, beschikt deze niet over een uitgevers-id, tenzij een dergelijke identificatie tijdelijk wordt toegewezen met de vlag -pubID op de opdrachtregel van ADL. De uitgevers-id van een geïnstalleerde toepassing is ook vermeld in het bestand META-INF/AIR/publisherid in de installatiemap van de toepassing. Zie “Informatie over uitgevers-id's voor AIR” op pagina 329 voor meer informatie.
306
Hoofdstuk 28: Werken met runtime- en besturingssysteeminformatie In deze sectie wordt beschreven hoe een AIR-toepassing bestandskoppelingen van het besturingssysteem kan beheren, gebruikersactiviteit kan detecteren en informatie kan ophalen over de Adobe® AIR™-runtime.
Bestandskoppelingen beheren Koppelingen tussen uw toepassing en een bestandstype moeten worden geregistreerd in de toepassingsdescriptor. Tijdens het installatieproces koppelt het installatieprogramma de AIR-toepassing als de standaard openingstoepassing aan elk geregistreerd bestandstype, tenzij er standaard al een andere toepassing is toegewezen. Het installatieproces van de AIR-toepassing wijzigt een bestaande bestandstypekoppeling niet. Om de koppeling van een andere toepassing over te nemen, dient u de methode NativeApplication.setAsDefaultApplication() op te roepen tijdens de runtime. U controleert het best of de verwachte bestandskoppelingen aanwezig zijn wanneer uw toepassing opstart. De reden hiervoor is dat het installatieprogramma van de AIR-toepassing de bestaande bestandskoppelingen niet wijzigt. Bovendien kunnen de bestandskoppelingen op het systeem van de gebruiker altijd veranderen. Als een andere toepassing de huidige bestandskoppeling heeft, is het ook een kwestie van beleefdheid dit aan de gebruiker te vragen voordat een bestaande koppeling wordt overgenomen. Met de volgende methoden van de klasse NativeApplication kan een toepassing de bestandskoppelingen beheren. Elke methode gebruikt de bestandstype-extensie als parameter: Methode
Beschrijving
isSetAsDefaultApplication()
Is true (waar) als de AIR-toepassing momenteel aan het opgegeven bestandstype is gekoppeld.
setAsDefaultApplication()
Maakt de koppeling tussen de AIR-toepassing en de openingsactie van het bestandstype.
removeAsDefaultApplication()
Verwijdert de koppeling tussen de AIR-toepassing en het bestandstype.
getDefaultApplication()
Toont het pad van de toepassing die momenteel aan het bestandstype is gekoppeld.
AIR kan alleen koppelingen beheren voor de bestandstypen die oorspronkelijk zijn geregistreerd in de toepassingsdescriptor. U kunt geen informatie ophalen over de koppelingen van een niet-geregistreerd bestandstype, zelfs als een gebruiker handmatig de koppeling heeft gemaakt tussen dat bestandstype en uw toepassing. Als een van de beheermethoden voor bestandskoppelingen wordt opgeroepen met de extensie voor een bestandstype dat niet is geregistreerd in de toepassingsdescriptor, genereert de toepassing een runtime-uitzondering. Zie “Koppelingen van bestandstypen registreren” op pagina 54 voor meer informatie over het registreren van bestandstypen in de toepassingsdescriptor.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 307 Werken met runtime- en besturingssysteeminformatie
De runtimeversie en het patchniveau ophalen Het NativeApplication-object heeft de eigenschap runtimeVersion; dit is de versie van de runtime waarin de toepassing wordt uitgevoerd (een tekenreeks, bijvoorbeeld "1.0.5"). Het NativeApplication-object heeft ook de eigenschap runtimePatchLevel; dit is het patchniveau van de runtime (een getal, bijvoorbeeld 2960). De volgende code maakt gebruik van deze eigenschappen: trace(NativeApplication.nativeApplication.runtimeVersion); trace(NativeApplication.nativeApplication.runtimePatchLevel);
AIR-mogelijkheden detecteren Voor een bestand dat bij de Adobe AIR-toepassing gebundeld zit, wordt de eigenschap Security.sandboxType ingesteld op de waarde die is gedefinieerd door de constante Security.APPLICATION. U kunt inhoud (die al dan niet API's bevat die specifiek zijn voor AIR) laden op basis van het feit of het bestand zich in de Adobe AIRbeveiligingssandbox bevindt, zoals geïllustreerd in de volgende code: if (Security.sandboxType == Security.APPLICATION) { // Load SWF that contains AIR APIs } else { // Load SWF that does not contain AIR APIs }
Alle bronnen die niet samen met de AIR-toepassing zijn geïnstalleerd, worden aan dezelfde beveiligingssandboxen toegewezen die door Adobe® Flash® Player in een webbrowser zouden worden toegewezen. Externe bronnen worden in sandboxen geplaatst op basis van hun brondomeinen, terwijl lokale bronnen in de lokaal-met-netwerk, lokaal-metbestandssysteem of lokaal-vertrouwde sandbox worden geplaatst. U kunt nagaan of de statische eigenschap Capabilities.playerType is ingesteld op "Desktop" om te controleren of inhoud wordt uitgevoerd in de runtime (en niet in Flash Player in een browser). Zie “Beveiliging in AIR” op pagina 24 voor meer informatie.
Gebruikersaanwezigheid bijhouden Het NativeApplication-object verzendt twee gebeurtenissen waarmee u kunt controleren of een gebruiker actief een computer gebruikt. Als er geen muis- of toetsenbordactiviteit wordt vastgesteld tijdens de periode die is bepaald met de eigenschap NativeApplication.idleThreshold, verzendt NativeApplication de gebeurtenis userIdle. De volgende keer dat het toetsenbord of de muis wordt gebruikt, verzendt het NativeApplication-object de gebeurtenis userPresent. Het interval idleThreshold wordt gemeten in seconden en heeft standaard de waarde 300 (5 minuten). U kunt met de eigenschap NativeApplication.nativeApplication.lastUserInput ook het aantal seconden sinds de laatste gebruikersinvoer opvragen. De volgende code stelt de drempel voor inactiviteit in op 2 minuten en luistert naar de gebeurtenissen userIdle en userPresent :
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 308 Werken met runtime- en besturingssysteeminformatie
Opmerking: Tussen twee userPresent-gebeurtenissen wordt slechts één userIdle-gebeurtenis verzonden.
309
Hoofdstuk 29: Netwerkconnectiviteit bewaken Adobe® AIR™ kan nagaan of er zich wijzigingen hebben voorgedaan in de netwerkconnectiviteit van de computer waarop een AIR-toepassing geïnstalleerd is. Deze informatie is handig als een toepassing gegevens gebruikt die via het netwerk zijn verkregen. Een toepassing kan ook de beschikbaarheid van een netwerkservice controleren.
Wijzigingen in de netwerkconnectiviteit detecteren Uw AIR-toepassing kan worden uitgevoerd in omgevingen met een onzekere of veranderende netwerkconnectiviteit. Om de verbindingen met online bronnen beter te kunnen beheren, verstuurt Adobe AIR de gebeurtenis network change wanneer een netwerkverbinding beschikbaar of onbeschikbaar wordt. Het NativeApplication-object van de toepassing verstuurt de gebeurtenis network change. Om op deze gebeurtenis te kunnen reageren, voegt u een listener toe: NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetworkChange);
Vervolgens definieert u een gebeurtenishandlerfunctie: function onNetworkChange(event:Event) { //Check resource availability }
De gebeurtenis Event.NETWORK_CHANGE geeft geen wijziging in alle netwerkactiviteit aan, maar alleen dat een netwerkverbinding is gewijzigd. AIR probeert niet om de betekenis van de netwerkwijziging te interpreteren. Een computer in een netwerk kan vele reële en virtuele verbindingen hebben. Het verlies van een verbinding betekent dus niet noodzakelijk dat een bron verloren is gegaan. Anderzijds waarborgen nieuwe verbindingen ook geen betere beschikbaarheid van de bronnen. Soms kan een nieuwe verbinding zelfs de toegang blokkeren tot bronnen die voordien beschikbaar waren (bijvoorbeeld wanneer verbinding wordt gemaakt met een VPN). Een toepassing kan alleen bepalen of deze verbinding kan maken met een externe bron door dit daadwerkelijk te proberen. Daarom kunnen AIR-toepassingen dankzij de frameworks voor servicebewaking in het pakket air.net op basis van gebeurtenissen reageren op wijzigingen in de netwerkconnectiviteit met een specifieke host. Opmerking: Het framework voor servicebewaking detecteert of een server op een aanvaardbare wijze reageert op een aanvraag. Dit waarborgt niet de volledige connectiviteit. Schaalbare webservices maken vaak gebruik van cachevoorzieningen en systemen om de belasting te verdelen, ten einde verkeer om te leiden naar een cluster van webservers. In deze situatie zorgen serviceproviders slechts voor een gedeeltelijke diagnose van de netwerkconnectiviteit.
Basisbeginselen van servicebewaking Het framework voor servicebewaking staat los van het AIR-framework en bevindt zich in het bestand servicemonitor.swc. Om het framework te kunnen gebruiken, moet het bestand servicemonitor.swc zijn opgenomen in uw constructieproces.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 310 Netwerkconnectiviteit bewaken
Belangrijk: Als u klassen in Adobe® Flash® CS3 Professional wilt gebruiken, moet u eerst de component ServiceMonitorShim vanuit het deelvenster Componenten naar de Bibliotheek slepen en daarna de volgende instructie import aan uw ActionScript 3.0-code toevoegen: import air.net.*;
Ga als volgt te werk om deze klassen te gebruiken Adobe ® Flash ® CS4 Professional: 1 Kies de opdracht Bestand > Instellingen publiceren. 2 Klik op de knop Instellingen voor ActionScript 3.0. Selecteer Bibliotheekpad. 3 Klik op de knop Bladeren naar SWC-bestand en blader naar Adobe Flash
CS4/AIK1.1/frameworks/libs/air/servicemoniter.swc. 4 Klik op de knop OK. 5 Voeg de volgende import-instructie toe aan de ActionScript 3.0-code: import air.net.*;
De klasse ServiceMonitor implementeert het framework voor de bewaking van netwerkservices en levert de basisfunctionaliteit voor de servicebewaking. Een instantie van de klasse ServiceMonitor verstuurt standaard gebeurtenissen met betrekking tot de netwerkconnectiviteit. Het ServiceMonitor-object verstuurt deze gebeurtenissen wanneer de instantie wordt gemaakt en telkens wanneer Adobe AIR een netwerkwijziging vaststelt. Bovendien kunt u de eigenschap pollInterval van een ServiceMonitor-instantie instellen om de connectiviteit in een bepaald interval (in milliseconden) te controleren, ongeacht algemene gebeurtenissen betreffende de netwerkconnectiviteit. Een ServiceMonitor-object controleert de netwerkconnectiviteit pas als de methode start() is opgeroepen. De klasse URLMonitor, een subklasse van de klasse ServiceMonitor, detecteert wijzigingen in de HTTP-connectiviteit voor een opgegeven URLRequest. De klasse SocketMonitor, eveneens een subklasse van de klasse ServiceMonitor, detecteert wijzigingen in de connectiviteit met een opgegeven host op een opgegeven poort.
HTTP-connectiviteit detecteren De klasse URLMonitor bepaalt of HTTP-aanvragen kunnen worden ingediend via een bepaald adres op poort 80 (de typische poort voor HTTP-communicatie). De volgende code gebruikt een instantie van de klasse URLMonitor om connectiviteitswijzigingen in de Adobe-website te detecteren: import air.net.URLMonitor; import flash.net.URLRequest; import flash.events.StatusEvent; var monitor:URLMonitor; monitor = new URLMonitor(new URLRequest('http://www.adobe.com')); monitor.addEventListener(StatusEvent.STATUS, announceStatus); monitor.start(); function announceStatus(e:StatusEvent):void { trace("Status change. Current status: " + monitor.available); }
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 311 Netwerkconnectiviteit bewaken
Socketconnectiviteit detecteren AIR-toepassingen kunnen ook socketverbindingen gebruiken voor push-model connectiviteit. Om veiligheidsredenen beperken firewalls en netwerkrouters doorgaans de netwerkcommunicatie via ongeoorloofde poorten. Daarom moeten ontwikkelaars er rekening mee houden dat de gebruiker geen socketverbindingen tot stand kan brengen. Net zoals bij het voorbeeld van URLMonitor gebruikt de volgende code een instantie van de klasse SocketMonitor om connectiviteitswijzigingen te detecteren in een socketverbinding op poort 6667, een klassieke poort voor IRC: import air.net.ServiceMonitor; import flash.events.StatusEvent; socketMonitor = new SocketMonitor('www.adobe.com',6667); socketMonitor.addEventListener(StatusEvent.STATUS, socketStatusChange); socketMonitor.start(); function announceStatus(e:StatusEvent):void { trace("Status change. Current status: " + socketMonitor.available); }
312
Hoofdstuk 30: URL-aanvragen en netwerken De nieuwe functionaliteit van Adobe AIR die betrekking heeft op het opgeven van URL-aanvragen, is niet beschikbaar voor SWF-inhoud die in de browser wordt uitgevoerd. Deze functionaliteit is alleen beschikbaar voor inhoud in de toepassingsbeveiligingssandbox. In deze sectie worden de URLRequest-functies in de runtime beschreven en worden de wijzigingen in de API voor netwerken besproken. Voor meer informatie over het gebruik van de netwerk- en communicatiemogelijkheden van Adobe® ActionScript® 3.0 raadpleegt u Adobe ActionScript 3.0 programmeren.
De klasse URLRequest gebruiken Met de klasse URLRequest kunt u meer definiëren dan alleen de URL-tekenreeks. AIR voegt een paar nieuwe eigenschappen toe aan de klasse URLRequest, die alleen beschikbaar zijn voor de AIR-inhoud die in de toepassingsbeveiligingssandbox wordt uitgevoerd. Inhoud in de runtime kan URL's definiëren met behulp van nieuwe URL-schema's (die een aanvulling vormen op de standaardschema's zoals file en http).
URLRequest-eigenschappen De klasse URLRequest bevat de volgende eigenschappen, die alleen beschikbaar zijn voor inhoud in de beveiligingssandbox van de AIR-toepassing: Eigenschap
Beschrijving
followRedirects
Hiermee geeft u aan of omleidingen moeten worden gevolgd (true, de standaardwaarde) of niet (false). Deze eigenschap wordt alleen ondersteund in de runtime.
manageCookies
Hiermee geeft u voor deze aanvraag aan of de HTTP-protocolstack cookies moet beheren (true, de standaardwaarde) of niet (false). Deze eigenschap wordt alleen ondersteund in de runtime.
authenticate
Hiermee geeft u aan of verificatieverzoeken voor deze aanvraag moeten worden afgehandeld (true). Deze eigenschap wordt alleen ondersteund in de runtime. Aanvragen worden standaard geverifieerd. Dit betekent dat er mogelijk een dialoogvenster voor verificatie wordt weergegeven als de server vereist dat er gebruikersgegevens worden weergegeven. U kunt ook de gebruikersnaam en het wachtwoord instellen. Zie “Standaardwaarden van URLRequest instellen” op pagina 313.
cacheResponse
Hiermee geeft u aan of succesvolle antwoordgegevens voor deze aanvraag in de cache moeten worden geplaatst. Deze eigenschap wordt alleen ondersteund in de runtime. Het antwoord wordt standaard in de cache geplaatst (true).
useCache
Hiermee geeft u aan of de lokale cache moet worden geraadpleegd voordat gegevens worden opgehaald door deze URLRequest. Deze eigenschap wordt alleen ondersteund in de runtime. Als de standaardwaarde (true) wordt aangehouden, wordt de lokale versie in de cache gebruikt, indien deze beschikbaar is.
userAgent
Hiermee geeft u de tekenreeks van de gebruikersagent op die in de HTTP-aanvraag moet worden gebruikt.
De volgende eigenschappen van een URLRequest-object kunnen worden ingesteld door inhoud in een willekeurige sandbox (niet alleen de beveiligingssandbox van de AIR-toepassing):
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 313 URL-aanvragen en netwerken
Eigenschap
Beschrijving
contentType
Dit is het MIME-inhoudstype van alle gegevens die met de URL-aanvraag worden verzonden.
data
Een object dat gegevens bevat die met de URL-aanvraag moeten worden verzonden.
digest
Dit is een veilige 'digest' voor een bestand in de cache om de cache van Adobe® Flash® Player op te sporen.
method
Hiermee bepaalt u welke HTTP-aanvraagmethode wordt gebruikt, zoals een GET- of POST-bewerking. (Inhoud die in het beveiligingsdomein van de AIR-toepassing wordt uitgevoerd, kan andere tekenreeksen opgeven dan "GET" of "POST" voor de eigenschap method. Elke HTTP-term is toegestaan en "GET" is de standaardmethode. Zie “Beveiliging in AIR” op pagina 24.)
requestHeaders
De array van HTTP-aanvraagheaders die aan de HTTP-aanvraag moet worden toegevoegd.
url
Hiermee geeft u de URL op die moet worden aangevraagd.
Opmerking: De klasse HTMLLoader heeft verwante eigenschappen voor instellingen die betrekking hebben op inhoud die wordt geladen door een HTMLLoader-object. Zie “Informatie over de klasse HTMLLoader” op pagina 238 voor meer informatie.
Standaardwaarden van URLRequest instellen Met de klasse URLRequestDefaults kunt u de standaardwaarden van URLRequest-objecten definiëren. Met de volgende code worden bijvoorbeeld de standaardwaarden van de eigenschappen manageCookies en useCache ingesteld: URLRequestDefaults.manageCookies = false; URLRequestDefaults.useCache = false; air.URLRequestDefaults.manageCookies = false; air.URLRequestDefaults.useCache = false;
De klasse URLRequestDefaults bevat de methode setLoginCredentialsForHost(), waarmee u een standaard gebruikersnaam en een standaardwachtwoord kunt opgeven die moeten worden gebruikt voor een specifieke host. De host, die wordt gedefinieerd met de parameter hostname van de methode, kan bestaan uit een domein, zoals "www.example.com", of uit een domein en een poortnummer, zoals "www.example.com:80". Houd er rekening mee dat "example.com", "www.example.com" en "sales.example.com" elk als een unieke host worden beschouwd. Deze gebruikersgegevens worden alleen gebruikt als de server deze vereist. Als de gebruiker al is geautoriseerd (bijvoorbeeld via het dialoogvenster voor verificatie), kunt u de geautoriseerde gebruiker niet wijzigen door de methode setLoginCredentialsForHost() op te roepen. Met de volgende code worden bijvoorbeeld de standaard gebruikersnaam en het standaardwachtwoord van de gebruiker ingesteld die moeten worden gebruikt voor www.example.com: URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X"); air.URLRequestDefaults.setLoginCredentialsForHost("www.example.com", "Ada", "love1816$X");
Elke eigenschap van URLRequestDefaults-instellingen is alleen van toepassing op het toepassingsdomein van de inhoud die de eigenschap instelt. De methode setLoginCredentialsForHost() is echter van toepassing op inhoud in alle toepassingsdomeinen binnen een AIR-toepassing. Op deze manier kan een toepassing zich aanmelden bij een host en zorgen dat alle inhoud binnen de toepassing wordt aangemeld met de opgegeven gebruikersgegevens. Raadpleeg het onderwerp over de klasse URLRequestDefaults in ActionScript 3.0 Language and Components Reference (http://www.adobe.com/go/learn_air_aslr_nl).
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 314 URL-aanvragen en netwerken
URL-schema's van AIR gebruiken in URL's De standaard URL-schema's, zoals de volgende schema's, zijn beschikbaar wanneer u URL's definieert in een willekeurige beveiligingssandbox in AIR: http: en https: Gebruik deze schema's zoals u ze zou gebruiken in een webbrowser. file: Gebruik dit schema om een pad op te geven op basis van de hoofdmap van het bestandssysteem. Bijvoorbeeld: file:///c:/AIR Test/test.txt
U kunt ook de volgende schema's gebruiken wanneer u een URL definieert voor inhoud die in de toepassingsbeveiligingssandbox wordt uitgevoerd: app: Gebruik dit schema om een pad op te geven op basis van de hoofdmap van de geïnstalleerde toepassing (de map die het descriptorbestand van de geïnstalleerde toepassing bevat). Het volgende pad verwijst bijvoorbeeld naar de submap resources van de map met de geïnstalleerde toepassing: app:/resources
Wanneer de toepassing wordt uitgevoerd in ADL, wordt de map resource van de toepassing ingesteld op de map die het descriptorbestand van de toepassing bevat. app-storage: Gebruik dit schema om een pad op te geven op basis van de opslagmap van de toepassing. Voor elke geïnstalleerde toepassing definieert AIR een unieke opslagmap voor iedere gebruiker. Deze map is een handige locatie voor het opslaan van gegevens die specifiek zijn voor die toepassing. Het volgende pad verwijst bijvoorbeeld naar het bestand prefs.xml in de submap settings van de opslagmap van een toepassing: app-storage:/settings/prefs.xml
De locatie van de opslagmap van de toepassing is gebaseerd op de gebruikersnaam, de toepassings-id en de uitgevers-id:
• In Mac OS, in: /Users/gebruikersnaam/Library/Preferences/toepassings-id.uitgevers-id/Local Store/
Bijvoorbeeld: /Users/babbage/Library/Preferences/com.example.TestApp.02D88EEED35F84C264A183921344EEA353 A629FD.1/Local Store
• In Windows, in de map Documents and Settings in: gebruikersnaam/Application Data/toepassings-id.uitgevers-id/Local Store/ Bijvoorbeeld: C:\Documents and Settings\babbage\Application Data\com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Local Store
• Op Linux—In: /home/gebruikersnaam/.appdata/toepassings-ID.uitgevers-id/Local Store/
Bijvoorbeeld:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 315 URL-aanvragen en netwerken
/home/babbage/.appdata/com.example.TestApp.02D88EEED35F84C264A183921344EEA353A629FD.1\Loc al Store
Voor de URL (en de eigenschap url) voor een File-object dat met File.applicationStorageDirectory is gemaakt, wordt het URL-schema app-storage gebruikt, zoals hierna wordt geïllustreerd: var dir:File = File.applicationStorageDirectory; dir = dir.resolvePath("preferences"); trace(dir.url); // app-storage:/preferences var dir = air.File.applicationStorageDirectory; dir = dir.resolvePath("prefs.xml"); air.trace(dir.url); // app-storage:/preferences
mailto: U kunt het mailto-schema gebruiken in URLRequest-objecten die worden doorgegeven naar de functie navigateToURL(). Zie “URL's openen in de standaard webbrowser van het systeem” op pagina 316.
URL-schema's gebruiken in AIR U kunt een URLRequest-object dat een van deze URL-schema's gebruikt, gebruiken om de URL-aanvraag te definiëren voor een aantal verschillende objecten, zoals een FileStream- of Sound-object. U kunt deze schema's ook gebruiken in HTML-inhoud die in AIR wordt uitgevoerd. Zo kunt u de schema's gebruiken in het kenmerk src van de tag img. U kunt deze AIR-specifieke URL-schema's (app: en app-storage:) echter alleen gebruiken in inhoud in de toepassingsbeveiligingssandbox. Zie “Beveiliging in AIR” op pagina 24 voor meer informatie.
Verboden URL-schema's Sommige API's stellen u in staat inhoud in een webbrowser te starten. Bepaalde URL-schema's zijn uit veiligheidsoverwegingen verboden wanneer deze API's in AIR worden gebruikt. De lijst van verboden schema's is afhankelijk van de beveiligingssandbox van de code waardoor de API wordt gebruikt. Zie “URL's openen in de standaard webbrowser van het systeem” op pagina 316 voor meer informatie.
Wijzigingen in de klasse URLStream De klasse URLStream biedt toegang op laag niveau voor het downloaden van gegevens vanuit URL's. In de runtime bevat de klasse URLStream een nieuwe gebeurtenis: httpResponseStatus. In tegenstelling tot de gebeurtenis httpStatus wordt de gebeurtenis httpResponseStatus afgeleverd vóór eventuele antwoordgegevens. De gebeurtenis httpResponseStatus (die is gedefinieerd in de klasse HTTPStatusEvent) bevat de eigenschap responseURL. Dit is de URL van waaruit het antwoord is geretourneerd. De gebeurtenis bevat ook de eigenschap responseHeaders. Dit is een array van URLRequestHeader-objecten die de antwoordheaders vertegenwoordigen die door het antwoord zijn geretourneerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 316 URL-aanvragen en netwerken
URL's openen in de standaard webbrowser van het systeem U kunt de functie navigateToURL() gebruiken om een URL te openen in de standaard webbrowser van het systeem. Voor het URLRequest-object geeft u de parameter request van deze functie door. Alleen de eigenschap url wordt gebruikt. var url = "http://www.adobe.com"; var urlReq = new air.URLRequest(url); air.navigateToURL(urlReq);
Opmerking: Wanneer u de functie navigateToURL() gebruikt, behandelt de runtime een URLRequest-object dat de methode POST gebruikt (een object waarvoor de eigenschap method is ingesteld op URLRequestMethod.POST) op dezelfde manier als het gebruik van de methode GET. Wanneer u de functie navigateToURL() gebruikt, zijn URL-schema's toegestaan op basis van de beveiligingssandbox van de code die de functie navigateToURL() oproept. Sommige API's stellen u in staat inhoud in een webbrowser te starten. Bepaalde URL-schema's zijn uit veiligheidsoverwegingen verboden wanneer deze API's in AIR worden gebruikt. De lijst van verboden schema's is afhankelijk van de beveiligingssandbox van de code waardoor de API wordt gebruikt. (Zie “Beveiliging in AIR” op pagina 24 voor meer informatie over beveiligingssandboxen.) Toepassingssandbox De volgende schema's zijn toegestaan. Gebruik deze schema's zoals u ze zou gebruiken in een webbrowser.
•
http:
•
https:
•
file:
•
mailto: - AIR leidt deze aanvragen naar de geregistreerde e-mailtoepassing van het systeem
•
app:
•
app-storage:
Alle andere URL-schema's zijn verboden. Externe sandbox De volgende schema's zijn toegestaan. Gebruik deze schema's zoals u ze zou gebruiken in een webbrowser.
•
http:
•
https:
•
mailto: - AIR leidt deze aanvragen naar de geregistreerde e-mailtoepassing van het systeem
Alle andere URL-schema's zijn verboden. Lokaal-met-bestandssysteem sandbox De volgende schema's zijn toegestaan. Gebruik deze schema's zoals u ze zou gebruiken in een webbrowser.
•
file:
•
mailto: - AIR leidt deze aanvragen naar de geregistreerde e-mailtoepassing van het systeem
Alle andere URL-schema's zijn verboden.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 317 URL-aanvragen en netwerken
Lokaal-met-netwerk sandbox De volgende schema's zijn toegestaan. Gebruik deze schema's zoals u ze zou gebruiken in een webbrowser.
•
http:
• https: •
mailto: - AIR leidt deze aanvragen naar de geregistreerde e-mailtoepassing van het systeem
Alle andere URL-schema's zijn verboden. Lokaal-vertrouwde sandbox De volgende schema's zijn toegestaan. Gebruik deze schema's zoals u ze zou gebruiken in een webbrowser.
•
file:
•
http:
• https: •
mailto: - AIR leidt deze aanvragen naar de geregistreerde e-mailtoepassing van het systeem
Alle andere URL-schema's zijn verboden.
318
Hoofdstuk 31: Communicatie tussen toepassingen De klasse LocalConnection maakt communicatie mogelijk tussen Adobe® AIR™-toepassingen en tussen AIRtoepassingen en SWF-inhoud die in de browser draait. De methode connect() van de klasse LocalConnection identificeert toepassingen met behulp van de parameter connectionName. In inhoud die in de beveiligingssandbox van de AIR-toepassing draait (inhoud samen met de AIRtoepassing geïnstalleerd), gebruikt AIR de tekenreeks app#, gevolgd door de toepassings-id, gevolgd door een punt (.), gevolgd door de uitgevers-id voor de AIR-toepassing (gedefinieerd in het descriptorbestand van de toepassing) in de plaats van het domein dat wordt gebruikt door de SWF-inhoud die in de browser draait. Voorbeeld: een connectionName voor een toepassing met de toepassings-id com.example.air.MyApp, de connectionName en de uitgevers-id B146A943FBD637B68C334022D304CEA226D129B4 wordt omgezet naar "app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4:connectionName". (Zie Basisinformatie van toepassingen definiëren en “Toepassings- en uitgevers-id's ophalen” op pagina 304 voor meer informatie.) Als u toestaat dat een andere AIR-toepassing via de lokale verbinding met uw toepassing communiceert, dient u de waarde allowDomain() van het LocalConnection-object op te roepen en de domeinnaam van de lokale verbinding door te geven. Voor een AIR-toepassing wordt deze domeinnaam gevormd op basis van de toepassings- en uitgeversid, net zoals bij de verbindingstekenreeks. Voorbeeld: als de verzendende AIR-toepassing de toepassings-id com.example.air.FriendlyApp en de uitgevers-id 214649436BD677B62C33D02233043EA236D13934, heeft, gebruikt u de volgende domeintekenreeks om deze toepassing toestemming te geven om te verbinden: app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934. Opmerking: Als u uw toepassing met ADL uitvoert (of met een hulpprogramma zoals Flash CS3, Flex Builder of Dreamweaver), is de uitgevers-id null en moet deze worden weggelaten uit de domeintekenreeks. Wanneer u uw toepassing installeert en uitvoert, moet de uitgevers-id zijn opgenomen in de domeintekenreeks. U kunt een tijdelijke uitgevers-id toewijzen met behulp van argumenten op de ADL-opdrachtregel. Gebruik een tijdelijke uitgevers-id om de syntaxis van de verbindingstekenreeks en de domeinnaam te testen.
319
Hoofdstuk 32: AIR-toepassingen distribueren, installeren en uitvoeren AIR-toepassingen worden gedistribueerd in één AIR-installatiebestand dat de toepassingscode en alle assets van de toepassing bevat. U kunt dit bestand op elke gebruikelijke wijze distribueren, zoals via downloaden, e-mail of een fysiek medium zoals een cd-rom. Gebruikers kunnen de toepassing installeren door te dubbelklikken op het AIRbestand. U kunt de functie voor naadloze installatie gebruiken, waarmee gebruikers uw AIR-toepassing (en Adobe® AIR™ als dat nodig is) kunnen installeren door op één koppeling op een webpagina te klikken. Voordat een AIR-installatiebestand kan worden gedistribueerd, moet het in een pakket worden geplaatst, en worden ondertekend met een certificaat voor ondertekening van programmacode en een persoonlijke sleutel. Als het installatiebestand digitaal is ondertekend, wordt gegarandeerd dat uw toepassing niet is gewijzigd sinds deze werd ondertekend. Bovendien kunnen uw gebruikers uw identiteit als uitgever en ondergetekende identiferen als een vertrouwde certificeringsinstantie het digitale certificaat heeft uitgegeven. Het AIR-bestand wordt ondertekend wanneer de toepassing in een pakket wordt geplaatst met ADT (AIR Developer Tool). Zie “AIR-toepassings- en installerbestanden aanmaken” op pagina 16 voor meer informatie over het plaatsen van een toepassing in een AIR-bestand met de AIR-update voor Flash. Zie “AIR-installatiebestanden in een pakket plaatsen met ADT (AIR Developer Tool)” op pagina 365 voor meer informatie over het plaatsen van een toepassing in een AIR-bestand met de SDK van Adobe® AIR™.
AIR-toepassingen vanaf de desktop installeren en uitvoeren U kunt het AIR-bestand eenvoudig naar de geadresseerde verzenden. U kunt het AIR-bestand bijvoorbeeld verzenden als een e-mailbijlage of als een koppeling op een webpagina. Een gebruiker die de AIR-toepassing downloadt, moet de volgende stappen uitvoeren om de toepassing te installeren: 1 Dubbelklik op het AIR-bestand.
Adobe AIR moet al op de computer zijn geïnstalleerd. 2 Laat de standaardinstellingen geselecteerd in het installatievenster en klik op Doorgaan.
In Windows voert AIR automatisch de volgende bewerkingen uit:
• De toepassing wordt geïnstalleerd in de map Program Files. • Op het bureaublad wordt een snelkoppeling voor de toepassing gemaakt. • In het menu Start wordt een snelkoppeling gemaakt. • De toepassing wordt toegevoegd aan het onderdeel Software in het Configuratiescherm. In Mac OS wordt de toepassing standaard toegevoegd aan de map Programma’s. Als de toepassing al is geïnstalleerd, kan de gebruiker in het installatieprogramma de bestaande versie van de toepassing openen of de toepassing updaten naar de versie in het gedownloade AIR-bestand. In het installatieprogramma wordt de toepassing geïdentificeerd met de toepassings-id en de uitgevers-id in het AIRbestand.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 320 AIR-toepassingen distribueren, installeren en uitvoeren
3 Klik op Voltooien wanneer de installatie is voltooid.
Als een gebruiker in Mac OS een recentere versie van een toepassing wil installeren, moet de gebruiker over voldoende toegangsrechten beschikken om te installeren in de toepassingsmap. In Windows en Linux heeft een gebruiker beheerdersrechten nodig. Een nieuwe versie van een toepassing kan ook worden geïnstalleerd via ActionScript of JavaScript. Zie “AIRtoepassingen updaten” op pagina 336 voor meer informatie. Nadat de AIR-toepassing is geïnstalleerd, dubbelklikt de gebruiker op het pictogram van de toepassing om de toepassing uit te voeren, net als bij een andere desktoptoepassing.
• Dubbelklik in Windows op het pictogram van de toepassing (die op het bureaublad of in een map is geïnstalleerd) of selecteer de toepassing in het menu Start.
• Dubbelklik in Linux op het pictogram van de toepassing (die op het bureaublad of in een map is geïnstalleerd) of selecteer de toepassing in het menu van de toepassing.
• Dubbelklik in Mac OS op de toepassing in de map waarin deze is geïnstalleerd. De standaard installatiemap is /Applications. Met de AIR-functie voor naadloze installatie kan een gebruiker een AIR-toepassing installeren door op een koppeling op een webpagina te klikken. Met de AIR-functie voor oproepen vanuit de browser kan een gebruiker een geïnstalleerde AIR-toepassing uitvoeren door op een koppeling op een webpagina te klikken. Deze functies worden beschreven in de volgende sectie.
AIR-toepassingen installeren en uitvoeren vanaf een webpagina Met de functie voor naadloze installatie kunt u in een webpagina een SWF-bestand insluiten waarmee de gebruiker een AIR-toepassing kan installeren vanuit de browser. Als de runtime niet is geïnstalleerd, wordt deze geïnstalleerd via de functie voor naadloze installatie. Met de functie voor naadloze installatie kunnen gebruikers de AIR-toepassing installeren zonder het AIR-bestand op hun computer op te slaan. In de SDK van AIR is het bestand badge.swf opgenomen waarmee u de functie voor naadloze installatie eenvoudig kunt gebruiken. Zie “AIR-toepassingen installeren met het bestand badge.swf” op pagina 321 voor meer informatie. Voor een demonstratie van het gebruik van de naadloze installatiefunctie raadpleegt u het artikel met snelstartvoorbeelden Een AIR-toepassing distribueren via het web (http://www.adobe.com/go/learn_air_qs_seamless_install_nl).
Informatie over het aanpassen van het bestand voor naadloze installatie badge.swf Naast het bestand badge.swf in de SDK kunt u ook zelf een SWF-bestand voor gebruik in een browserpagina maken. Uw aangepaste SWF-bestand kan op de volgende manieren interageren met de runtime:
• Een AIR-toepassing installeren. Zie “AIR-toepassingen installeren vanuit de browser” op pagina 326. • Controleren of een bepaalde AIR-toepassing is geïnstalleerd. Zie “Vanuit een webpagina controleren of een AIRtoepassing is geïnstalleerd” op pagina 325.
• Controleren of de runtime is geïnstalleerd. Zie “Controleren of de runtime is geïnstalleerd” op pagina 324.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 321 AIR-toepassingen distribueren, installeren en uitvoeren
• Een geïnstalleerde AIR-toepassing op het systeem van de gebruiker starten. Zie “Geïnstalleerde AIR-toepassingen starten vanuit de browser” op pagina 327. Deze functies worden mogelijk gemaakt door het oproepen van API's in een SWF-bestand op adobe.com: air.swf. In deze sectie wordt beschreven hoe u het bestand badge.swf gebruikt en aanpast en hoe u de API's van air.swf oproept vanuit uw eigen SWF-bestand. Een SWF-bestand dat in de browser wordt uitgevoerd, kan ook met een gestarte AIR-toepassing communiceren met behulp van de klasse LocalConnection. Zie “Communicatie tussen toepassingen” op pagina 318 voor meer informatie. Belangrijk: De eindgebruiker kan de functies die in deze sectie worden beschreven (en de API's in het bestand air.swf) alleen gebruiken als Adobe® Flash® Player 9 update 3 is geïnstalleerd in de webbrowser op Windows of Mac OS. Op Linux vereist de naadloze installatiefunctie Flash Player 10 (versie 10,0,12,36 of hoger). U kunt code schrijven om de geïnstalleerde versie van Flash Player te controleren en de gebruiker een alternatieve interface bieden als de vereiste versie van Flash Player niet is geïnstalleerd. Als er bijvoorbeeld een oudere versie van Flash Player is geïnstalleerd, kunt u een koppeling naar de downloadversie van het AIR-bestand opgeven (in plaats van de toepassing te installeren met het bestand badge.swf of de API van air.swf).
AIR-toepassingen installeren met het bestand badge.swf In de SDK van AIR is het bestand badge.swf opgenomen waarmee u de functie voor naadloze installatie eenvoudig kunt gebruiken. Met badge.swf kunt u de runtime en een AIR-toepassing installeren via een koppeling op een webpagina. Het bestand badge.swf en de broncode worden geleverd voor distributie op uw website. In de instructies in deze sectie vindt u informatie over het instellen van parameters voor het bestand badge.swf van Adobe. U kunt ook beschikken over de broncode van het bestand badge.swf en deze aanpassen. Het bestand badge.swf insluiten in een webpagina 1 Zoek de volgende bestanden in de map samples/badge van de SDK van AIR en voeg deze toe aan uw webserver.
• badge.swf • default_badge.html • AC_RunActiveContent.js 2 Open de pagina default_badge.html in een teksteditor. 3 Pas in de pagina default_badge.html in de JavaScript-functie AC_FL_RunContent() de FlashVars-parameters als
volgt aan: Parameter
Beschrijving
appname
De naam van de toepassing. Deze wordt door het SWF-bestand weergegeven wanneer de runtime niet is geïnstalleerd.
appurl
(Vereist.) De URL van het AIR-bestand dat moet worden gedownload. U moet een absolute en geen relatieve URL opgeven.
airversion
(Vereist.) Voor versie 1.0 van de runtime stelt u deze in op 1.0.
imageurl
De URL van de afbeelding (optioneel) die wordt weergegeven in de badge.
buttoncolor
De kleur van de downloadknop (opgegeven als een hexadecimale waarde, zoals FFCC00).
messagecolor
De kleur van het tekstbericht dat onder de knop wordt weergegeven als de runtime niet is geïnstalleerd (opgegeven als een hexadecimale waarde, zoals FFCC00).
4 De minimale grootte van het bestand badge.swf file is 217 pixels breed en 180 pixels hoog. Pas de waarden van de
parameters width en height van de functie AC_FL_RunContent() aan uw wensen aan.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 322 AIR-toepassingen distribueren, installeren en uitvoeren
5 Wijzig de naam van het bestand default_badge.html en pas de code aan uw wensen aan (of neem deze op in een
andere HTML-pagina). U kunt het bestand badge.swf ook bewerken en opnieuw compileren. Zie “Het bestand badge.swf wijzigen” op pagina 322 voor meer informatie.
AIR-toepassingen installeren via een koppeling voor naadloze installatie op een webpagina Wanneer u de koppeling voor naadloze installatie aan een pagina hebt toegevoegd, kan de gebruiker de AIRtoepassing installeren door op de koppeling in het SWF-bestand te klikken. 1 Navigeer naar de HTML-pagina in een webbrowser waarin Flash Player (versie 9 update 3 of hoger op Windows
en Mac OS, of versie 10 op Linux) is geïnstalleerd. 2 Klik op de webpagina op de koppeling in het bestand badge.swf.
• Als u de runtime hebt geïnstalleerd, gaat u verder met de volgende stap. • Als u de runtime niet hebt geïnstalleerd, wordt een dialoogvenster geopend met de vraag of u deze wilt installeren. Installeer de runtime (zie “Adobe AIR installeren” op pagina 1) en ga verder met de volgende stap. 3 Laat de standaardinstellingen geselecteerd in het installatievenster en klik op Doorgaan.
Op een Windows-computer voert AIR automatisch de volgende bewerkingen uit:
• De toepassing wordt geïnstalleerd in C:\Program Files\. • Op het bureaublad wordt een snelkoppeling voor de toepassing gemaakt. • In het menu Start wordt een snelkoppeling gemaakt. • De toepassing wordt toegevoegd aan het onderdeel Software in het Configuratiescherm. In Mac OS wordt de toepassing toegevoegd aan de programmamap (bijvoorbeeld in de map /Applications in Mac OS). Op een Linux-computer voert AIR automatisch de volgende bewerkingen uit:
• Installeert de toepassing in /opt. • Op het bureaublad wordt een snelkoppeling voor de toepassing gemaakt. • In het menu Start wordt een snelkoppeling gemaakt. • Voegt een item voor de toepassing toe in het systeempakketbeheer 4 Selecteer de gewenste opties en klik op de knop Installeren. 5 Klik op Voltooien wanneer de installatie is voltooid.
Het bestand badge.swf wijzigen De SDK van AIR bevat de bronbestanden voor het bestand badge.swf. Deze bestanden zijn te vinden in de map samples/badge van de SDK: Bronbestanden
Beschrijving
badge.fla
Het Flash -bronbestand om het bestand badge.swf te compileren. Het bestand badge.fla wordt gecompileerd naar een SWF 9-bestand (dat kan worden geladen in Flash Player).
AIRBadge.as
Een ActionScript 3.0-klasse waarin de klasse base is gedefinieerd die in het bestand badge.fla wordt gebruikt.
Met Flash CS3 of Flash CS4 kunt u de visuele interface van het bestand badge.fla opnieuw ontwerpen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 323 AIR-toepassingen distribueren, installeren en uitvoeren
Met de constructorfunctie AIRBadge(), die in de klasse AIRBadge is gedefinieerd, laadt u het bestand air.swf dat zich bevindt op http://airdownload.adobe.com/air/browserapi/air.swf. Het bestand air.swf bevat code voor het gebruik van de functie voor naadloze installatie. De methode onInit() (in de klasse AIRBadge) wordt opgeroepen nadat het bestand air.swf file is geladen: private function onInit(e:Event):void { _air = e.target.content; switch (_air.getStatus()) { case "installed" : root.statusMessage.text = ""; break; case "available" : if (_appName && _appName.length > 0) { root.statusMessage.htmlText = "
In order to run " + _appName + ", this installer will also set up Adobe® AIR™.
"; } else { root.statusMessage.htmlText = "
In order to run this application, " + "this installer will also set up Adobe® AIR™.
"; } break; case "unavailable" : root.statusMessage.htmlText = "
Adobe® AIR™ is not available for your system.
"; root.buttonBg_mc.enabled = false; break; } }
Met de code wordt de globale variabele _air ingesteld op de hoofdklasse van het geladen bestand air.swf. In deze klasse zijn de volgende openbare methoden opgenomen, die in het bestand badge.swf worden gebruikt om de functionaliteit voor naadloze installatie op te roepen: Methode
Beschrijving
getStatus()
Hiermee wordt bepaald of de runtime is geïnstalleerd (of kan worden geïnstalleerd) op de computer. Zie “Controleren of de runtime is geïnstalleerd” op pagina 324 voor meer informatie.
installApplication() Hiermee wordt de opgegeven toepassing geïnstalleerd op de computer van de gebruiker. Zie “AIR-
toepassingen installeren vanuit de browser” op pagina 326 voor meer informatie.
•
url: een tekenreeks waarmee de URL wordt gedefinieerd. U moet een absoluut en geen relatief URL-pad
opgeven.
•
runtimeVersion: een tekenreeks die de versie van de runtime bevat (bijvoorbeeld "1.0.M6") die is
vereist voor de toepassing die wordt geïnstalleerd.
•
arguments: argumenten die aan de toepassing worden doorgegeven als deze na de installatie wordt gestart. De toepassing wordt na de installatie gestart als het element allowBrowserInvocation op true is ingesteld in het descriptorbestand van de toepassing. (Zie “Eigenschappen van AIR-toepassingen
instellen” op pagina 45 voor meer informatie over het descriptorbestand van de toepassing.) Als de toepassing wordt gestart als gevolg van een naadloze installatie vanuit de browser (en de gebruiker de toepassing na de installatie start), verzendt het NativeApplication-object van de toepassing alleen een BrowserInvokeEvent-object als er argumenten zijn doorgegeven. Houd rekening met de gevolgen voor de beveiliging van gegevens die u aan de toepassing doorgeeft. Zie “Geïnstalleerde AIR-toepassingen starten vanuit de browser” op pagina 327 voor meer informatie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 324 AIR-toepassingen distribueren, installeren en uitvoeren
De instellingen voor url en runtimeVersion worden aan het SWF-bestand doorgegeven via de FlashVarsinstellingen in de HTML-containerpagina. Als de toepassing na de installatie automatisch wordt gestart, kunt u via communicatie met LocalConnection de geïnstalleerde toepassing bij het oproepen contact laten opnemen met het bestand badge.swf. Zie “Communicatie tussen toepassingen” op pagina 318 voor meer informatie. U kunt ook de methode getApplicationVersion() van het bestand air.swf oproepen om te controleren of een toepassing is geïnstalleerd. U kunt deze methode oproepen voordat de toepassing wordt geïnstalleerd of nadat de installatie is gestart. Zie “Vanuit een webpagina controleren of een AIR-toepassing is geïnstalleerd” op pagina 325 voor meer informatie.
Het bestand air.swf laden U kunt zelf een SWF-bestand maken waarin u de API's van het bestand air.swf gebruikt voor de interactie met de runtime en AIR-toepassingen vanuit een webpagina in een browser. Het bestand air.swf bevindt zich op http://airdownload.adobe.com/air/browserapi/air.swf. Als u vanuit uw SWF-bestand wilt verwijzen naar de API's van air.swf, laadt u het bestand air.swf in hetzelfde toepassingsdomein als uw SWF-bestand. In het volgende voorbeeld ziet u code voor het laden van het bestand air.swf in het toepassingsdomein van het SWF-bestand: var airSWF:Object; // This is the reference to the main class of air.swf var airSWFLoader:Loader = new Loader(); // Used to load the SWF var loaderContext:LoaderContext = new LoaderContext(); // Used to set the application domain loaderContext.applicationDomain = ApplicationDomain.currentDomain; airSWFLoader.contentLoaderInfo.addEventListener(Event.INIT, onInit); airSWFLoader.load(new URLRequest("http://airdownload.adobe.com/air/browserapi/air.swf"), loaderContext); function onInit(e:Event):void { airSWF = e.target.content; }
Nadat het bestand air.swf is geladen (wanneer het contentLoaderInfo-object van het Loader-object de initgebeurtenis verzendt), kunt u elke API van air.swf oproepen. Deze API's worden in de volgende secties beschreven:
• “Controleren of de runtime is geïnstalleerd” op pagina 324 • “Vanuit een webpagina controleren of een AIR-toepassing is geïnstalleerd” op pagina 325 • “AIR-toepassingen installeren vanuit de browser” op pagina 326 • “Geïnstalleerde AIR-toepassingen starten vanuit de browser” op pagina 327 Opmerking: Met het bestand badge.swf, dat aanwezig is in de SDK van AIR, wordt het bestand air.swf automatisch geladen. Zie “AIR-toepassingen installeren met het bestand badge.swf” op pagina 321. De instructies in deze sectie zijn van toepassing wanneer u zelf een SWF-bestand maakt waarmee het bestand air.swf wordt geladen.
Controleren of de runtime is geïnstalleerd Een SWF-bestand kan controleren of de runtime is geïnstalleerd door de methode getStatus() op te roepen in het bestand air.swf dat is geladen vanaf http://airdownload.adobe.com/air/browserapi/air.swf. Zie “Het bestand air.swf laden” op pagina 324 voor meer informatie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 325 AIR-toepassingen distribueren, installeren en uitvoeren
Nadat het bestand air.swf is geladen, kunt u vanuit het SWF-bestand de methode getStatus() van het bestand air.swf als volgt oproepen: var status:String = airSWF.getStatus();
De methode getStatus() retourneert een van de volgende tekenreekswaarden, afhankelijk van de status van de runtime op de computer: Tekenreekswaarde
Beschrijving
"available"
De runtime kan op deze computer worden geïnstalleerd, maar is momenteel niet geïnstalleerd.
"unavailable"
De runtime kan niet op deze computer worden geïnstalleerd.
"installed"
De runtime is op deze computer geïnstalleerd.
De methode getStatus() meldt een fout als de vereiste versie van Flash Player (versie 9 upgrade 3 op Windows en Mac OS, of versie 10 op Linux) niet in de browser is geïnstalleerd.
Vanuit een webpagina controleren of een AIR-toepassing is geïnstalleerd Een SWF-bestand kan controleren of een AIR-toepassing (met een overeenkomstige toepassings-id en uitgevers-id) is geïnstalleerd door de methode getApplicationVersion() op te roepen in het bestand air.swf dat is geladen vanaf http://airdownload.adobe.com/air/browserapi/air.swf. Zie “Het bestand air.swf laden” op pagina 324 voor meer informatie. Nadat het bestand air.swf is geladen, kunt u vanuit het SWF-bestand de methode getApplicationVersion() van het bestand air.swf als volgt oproepen: var appID:String = "com.example.air.myTestApplication"; var pubID:String = "02D88EEED35F84C264A183921344EEA353A629FD.1"; airSWF.getApplicationVersion(appID, pubID, versionDetectCallback); function versionDetectCallback(version:String):void { if (version == null) { trace("Not installed."); // Take appropriate actions. For instance, present the user with // an option to install the application. } else { trace("Version", version, "installed."); // Take appropriate actions. For instance, enable the // user interface to launch the application. } }
De methode getApplicationVersion() heeft de volgende parameters:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 326 AIR-toepassingen distribueren, installeren en uitvoeren
Parameters
Beschrijving
appID
De toepassings-id voor de toepassing. Zie “De toepassingsidentiteit definiëren” op pagina 48 voor meer informatie.
pubID
De uitgevers-id voor de toepassing. Zie “Informatie over uitgevers-id's voor AIR” op pagina 329 voor meer informatie.
callback
Een callbackfunctie die optreedt als de handlerfunctie. De methode getApplicationVersion() werkt asynchroon en wanneer de geïnstalleerde versie is aangetroffen (of juist ontbreekt), wordt deze callbackmethode opgeroepen. In de definitie van de callbackmethode moet één parameter zijn opgenomen: een tekenreeks die de versie van de geïnstalleerde toepassing bevat. Als de toepassing niet is geïnstalleerd, wordt de waarde null doorgegeven aan de functie, zoals in het vorige codevoorbeeld.
De methode getApplicationVersion() meldt een fout als de vereiste versie van Flash Player (versie 9 upgrade 3 op Windows en Mac OS, of versie 10 op Linux) niet in de browser is geïnstalleerd.
AIR-toepassingen installeren vanuit de browser Een SWF-bestand kan een AIR-toepassing installeren door de methode installApplication() op te roepen in het bestand air.swf dat is geladen vanaf http://airdownload.adobe.com/air/browserapi/air.swf. Zie “Het bestand air.swf laden” op pagina 324 voor meer informatie. Nadat het bestand air.swf is geladen, kunt u vanuit het SWF-bestand de methode installApplication() van het bestand air.swf als volgt oproepen: var url:String = "http://www.example.com/myApplication.air"; var runtimeVersion:String = "1.0"; var arguments:Array = ["launchFromBrowser"]; // Optional airSWF.installApplication(url, runtimeVersion, arguments);
Met de methode installApplication() wordt de opgegeven toepassing geïnstalleerd op de computer van de gebruiker. Deze methode heeft de volgende parameters: Parameter
Beschrijving
url
Een tekenreeks die de URL bevat van het AIR-bestand dat wordt geïnstalleerd. U moet een absoluut en geen relatief URL-pad opgeven.
runtimeVersion
Een tekenreeks die de versie van de runtime bevat (bijvoorbeeld "1.0") die is vereist voor de toepassing die wordt geïnstalleerd.
arguments
Een array met argumenten die aan de toepassing worden doorgegeven als deze na de installatie wordt gestart. Alle alfanumerieke tekens worden in de argumenten herkend. Als u andere waarden moet doorgeven, kunt u het gebruik van een coderingsschema overwegen. De toepassing wordt na de installatie gestart als het element allowBrowserInvocation op true is ingesteld in het descriptorbestand van de toepassing. (Zie “Eigenschappen van AIR-toepassingen instellen” op pagina 45 voor meer informatie over het descriptorbestand van de toepassing.) Als de toepassing wordt gestart als gevolg van een naadloze installatie vanuit de browser (en de gebruiker de toepassing na de installatie start), verzendt het NativeApplication-object van de toepassing alleen een BrowserInvokeEventobject als er argumenten zijn doorgegeven. Zie “Geïnstalleerde AIR-toepassingen starten vanuit de browser” op pagina 327 voor meer informatie.
De methode installApplication() werkt alleen wanneer deze wordt opgeroepen in de gebeurtenishandler voor een gebruikersgebeurtenis, zoals een muisklik. De methode installApplication() meldt een fout als de vereiste versie van Flash Player (versie 9 upgrade 3 op Windows en Mac OS, of versie 10 op Linux) niet in de browser is geïnstalleerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 327 AIR-toepassingen distribueren, installeren en uitvoeren
Als een gebruiker in Mac OS een recentere versie van een toepassing wil installeren, moet de gebruiker over voldoende toegangsrechten beschikken om te installeren in de toepassingsmap (en over beheerdersrechten als de toepassing de runtime bijwerkt). In Windows moet de gebruiker over beheerdersrechten beschikken. U kunt ook de methode getApplicationVersion() van het bestand air.swf oproepen om te controleren of een toepassing al is geïnstalleerd. U kunt deze methode oproepen voordat het installatieproces van de toepassing begint of nadat de installatie is gestart. Zie “Vanuit een webpagina controleren of een AIR-toepassing is geïnstalleerd” op pagina 325 voor meer informatie. Wanneer de toepassing is gestart, kan deze met de SWF-inhoud in de browser communiceren via de klasse LocalConnection. Zie “Communicatie tussen toepassingen” op pagina 318 voor meer informatie.
Geïnstalleerde AIR-toepassingen starten vanuit de browser Als u de browseroproepfunctie wilt gebruiken (zodat een toepassing kan worden gestart vanuit de browser), moet in het descriptorbestand van de doeltoepassing de volgende instelling zijn opgenomen: true
Zie “Eigenschappen van AIR-toepassingen instellen” op pagina 45 voor meer informatie over het descriptorbestand van de toepassing. Een SWF-bestand in de browser kan een AIR-toepassing starten door de methode launchApplication() op te roepen in het bestand air.swf dat is geladen vanaf http://airdownload.adobe.com/air/browserapi/air.swf. Zie “Het bestand air.swf laden” op pagina 324 voor meer informatie. Nadat het bestand air.swf is geladen, kunt u vanuit het SWF-bestand de methode launchApplication() van het bestand air.swf als volgt oproepen: var appID:String = "com.example.air.myTestApplication"; var pubID:String = "02D88EEED35F84C264A183921344EEA353A629FD.1"; var arguments:Array = ["launchFromBrowser"]; // Optional airSWF.launchApplication(appID, pubID, arguments);
De methode launchApplication() is gedefinieerd op het hoogste niveau van het bestand air.swf (dat is geladen in het toepassingsdomein van het SWF-bestand van de gebruikersinterface). Als u deze methode oproept, wordt de opgegeven toepassing gestart (als deze is geïnstalleerd en oproepen via de browser is toegestaan via de instelling van allowBrowserInvocation in het descriptorbestand van de toepassing). De methode heeft de volgende parameters: Parameter
Beschrijving
appID
De toepassings-id voor de toepassing die moet worden gestart. Zie “De toepassingsidentiteit definiëren” op pagina 48 voor meer informatie.
pubID
De uitgevers-id voor de toepassing die moet worden gestart. Zie “Informatie over uitgevers-id's voor AIR” op pagina 329 voor meer informatie.
arguments
Een array met argumenten die worden doorgegeven aan de toepassing. Het NativeApplication-object van de toepassing verzendt een BrowserInvokeEvent-gebeurtenis waarvoor de eigenschap arguments is ingesteld op deze array. Alle alfanumerieke tekens worden in de argumenten herkend. Als u andere waarden moet doorgeven, kunt u het gebruik van een coderingsschema overwegen.
De methode launchApplication() werkt alleen wanneer deze wordt opgeroepen in de gebeurtenishandler voor een gebruikersgebeurtenis, zoals een muisklik. De methode launchApplication() meldt een fout als de vereiste versie van Flash Player (versie 9 upgrade 3 op Windows en Mac OS, of versie 10 op Linux) niet in de browser is geïnstalleerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 328 AIR-toepassingen distribueren, installeren en uitvoeren
Als het element allowBrowserInvocation op false is ingesteld in het descriptorbestand van de toepassing, heeft het oproepen van de methode launchApplication() geen effect. Voordat u de gebruikersinterface weergeeft om de toepassing te starten, kunt u het best de methode getApplicationVersion() in het bestand air.swf oproepen. Zie “Vanuit een webpagina controleren of een AIRtoepassing is geïnstalleerd” op pagina 325 voor meer informatie. Wanneer de toepassing wordt opgeroepen via de browseroproepfunctie, verzendt het NativeApplication-object van de toepassing een BrowserInvokeEvent-object. Zie “Oproepen vanuit browser” op pagina 300 voor meer informatie. Als u de browseroproepfunctie gebruikt, moet u rekening houden met de gevolgen voor de beveiliging die in “Oproepen vanuit browser” op pagina 300 worden beschreven. Wanneer de toepassing is gestart, kan deze met de SWF-inhoud in de browser communiceren via de klasse LocalConnection. Zie “Communicatie tussen toepassingen” op pagina 318 voor meer informatie.
Implementatie in ondernemingen IT-beheerders kunnen de Adobe AIR-runtime en AIR-toepassingen zonder toezicht installeren met behulp van standaard implementatieprogramma's. IT-beheerders kunnen het volgende doen:
• de Adobe AIR-runtime zonder toezicht installeren met hulpprogramma's zoals Microsoft SMS, IBM Tivoli of een implementatieprogramma waarmee installaties met een bootstrapper zonder toezicht mogelijk zijn;
• de AIR-toepassing zonder toezicht installeren met hetzelfde hulpprogramma waarmee de runtime is geïmplementeerd. Zie de Adobe AIR Administrator’s Guide (Beheerdershandleiding voor Adobe AIR) (http://www.adobe.com/go/learn_air_admin_guide_nl) voor meer informatie.
AIR-bestanden digitaal ondertekenen Als u uw AIR-installatiebestanden digitaal ondertekent met een certificaat dat is uitgegeven door een erkende certificeringsinstantie (CA), hebben uw gebruikers een goede garantie dat de toepassing die zij installeren niet per ongeluk of met boze opzet is gewijzigd en weten zij dat u de ondertekenaar (uitgever) bent. De uitgeversnaam wordt tijdens de installatie weergegeven wanneer de AIR-toepassing is ondertekend met een certificaat dat wordt vertrouwd of dat via een certificaatketen is gekoppeld aan een certificaat dat wordt vertrouwd op de installatiecomputer. Anders wordt de uitgeversnaam weergegeven als “Onbekend”. Belangrijk: Een kwaadwillende entiteit kan uw identiteit in een AIR-bestand vervalsen als deze op een of andere manier uw sleutelarchiefbestand voor ondertekening in handen krijgt of uw persoonlijke sleutel ontdekt.
Informatie over certificaten voor ondertekening van programmacode De beveiligingsgaranties, beperkingen en wettelijke verplichtingen die betrekking hebben op het gebruik van certificaten voor ondertekening van programmacode worden beschreven in de CPS (Certificate Practice Statements) en gebruiksrechtovereenkomsten die zijn uitgegeven door de certificeringsinstantie. Voor meer informatie over de overeenkomsten voor de certificeringsinstanties die momenteel certificaten voor de ondertekening van AIR-code uitgeven, raadpleegt u: ChosenSecurity (http://www.chosensecurity.com/products/tc_publisher_id_adobe_air.htm)
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 329 AIR-toepassingen distribueren, installeren en uitvoeren
Informatie over ondertekening van AIR-programmacode Wanneer een AIR-bestand wordt ondertekend, wordt een digitale handtekening opgenomen in het installatiebestand. De handtekening bevat een samenvatting van het pakket waarmee wordt geverifieerd of het AIR-bestand niet is gewijzigd sinds het werd ondertekend, en bevat informatie over het handtekeningcertificaat waarmee de identiteit van de uitgever wordt geverifieerd. AIR maakt gebruik van PKI (Public Key Infrastructure, openbare-sleutelinfrastructuur) dat door het certificaatarchief van het besturingssysteem wordt ondersteund, om te bepalen of een certificaat kan worden vertrouwd. Om de gegevens van de uitgever te kunnen verifiëren moet de computer waarop een AIR-toepassing wordt geïnstalleerd het certificaat waarmee de AIR-toepassing wordt ondertekend rechtstreeks vertrouwen of een certificaatketen vertrouwen waarmee het certificaat aan een vertrouwde certificeringsinstantie wordt gekoppeld. Als een AIR-bestand is ondertekend met een certificaat dat niet via een certificaatketen is gekoppeld aan een van de vertrouwde basiscertificaten (en dit betreft alle zelfondertekende certificaten), kunnen de gegevens van de uitgever niet worden geverifieerd. Hoewel AIR kan bepalen of het AIR-pakket niet is gewijzigd sinds het werd ondertekend, is niet bekend wie het bestand heeft gemaakt en ondertekend. Opmerking: Als een gebruiker een zelfondertekend certificaat vertrouwt, geven alle AIR-toepassingen die met het certificaat zijn ondertekend de waarde van de algemene naam (CN) in het certificaat weer als de uitgeversnaam. AIR beschikt niet over mogelijkheden waarmee een gebruiker een certificaat als vertrouwd kan aanmerken. Het certificaat (exclusief de persoonlijke sleutel) moet afzonderlijk aan de gebruiker worden gegeven en de gebruiker moet een van de mechanismen van het besturingssysteem of een geschikt hulpprogramma gebruiken om het certificaat te importeren op de juiste locatie in het certificaatarchief van het systeem.
Informatie over uitgevers-id's voor AIR Tijdens het bouwen van een AIR-bestand met ADT (AIR Developer Tool) wordt een uitgevers-id gegenereerd. Dit is een unieke id voor het certificaat waarmee het AIR-bestand wordt gebouwd. Als u hetzelfde certificaat gebruikt voor meerdere AIR-toepassingen, hebben deze dezelfde uitgevers-id. De uitgevers-id wordt gebruikt om de AIR-toepassing te identificeren via de communicatie met LocalConnection (zie “Communicatie tussen toepassingen” op pagina 318). U kunt de uitgevers-id van een geïnstalleerde toepassing identificeren door de eigenschap NativeApplication.nativeApplication.publisherID te lezen.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 330 AIR-toepassingen distribueren, installeren en uitvoeren
De uitgevers-id wordt bepaald door de volgende velden: Name, CommonName, Surname, GivenName, Initials, GenerationQualifier, DNQualifier, CountryName, localityName, StateOrProvinceName, OrganizationName, OrganizationalUnitName, Title, Email, SerialNumber, DomainComponent, Pseudonym, BusinessCategory, StreetAddress, PostalCode, PostalAddress, DateOfBirth, PlaceOfBirth, Gender, CountryOfCitizenship, CountryOfResidence en NameAtBirth. Als u een certificaat vernieuwt dat door een certificeringsinstantie is uitgegeven of een zelfondertekend certificaat opnieuw genereert, moeten deze velden hetzelfde zijn als de uitgevers-id hetzelfde moet blijven. Bovendien moeten het basiscertificaat van een certificaat dat door een CA is uitgegeven en de openbare sleutel van een zelfondertekend certificaat gelijk zijn.
Informatie over certificaatindelingen De ondertekeningsprogramma's van AIR accepteren alle sleutelarchieven die toegankelijk zijn via JCA (Java Cryptography Architecture). Hiertoe behoren op bestanden gebaseerde sleutelarchieven, zoals PKCS12-bestanden (die gewoonlijk de extensie .pfx of .p12 hebben), .keystore-bestanden van Java, PKCS11-hardwaresleutelarchieven en de sleutelarchieven van het systeem. Welke sleutelarchiefindelingen ADT kan openen, is afhankelijk van de versie en de configuratie van de Java-runtime waarmee ADT wordt uitgevoerd. Voor sommige typen sleutelarchieven, zoals PKCS11-hardwaretokens, moeten mogelijk extra stuurprogramma's en JCA-invoegtoepassingen worden geïnstalleerd en geconfigureerd. Als u AIR-bestanden wilt ondertekenen, kunt u de meeste bestaande certificaten voor ondertekening van code gebruiken, of u kunt een nieuwe verkrijgen die speciaal voor de ondertekening van AIR-toepassingen is uitgegeven. U kunt bijvoorbeeld alle volgende typen certificaten gebruiken van VeriSign, Thawte, GlobalSign of ChosenSecurity:
• ChosenSecurity • TC Publisher ID for Adobe AIR • GlobalSign • ObjectSign Code Signing Certificate • Thawte: • AIR-certificaat voor ontwikkelaars • Apple-certificaat voor ontwikkelaars • JavaSoft-certificaat voor ontwikkelaars • Microsoft Authenticode-certificaat • VeriSign: • Adobe AIR Digital ID • Digitale Microsoft Authenticode-id • Digitale handtekening-id van Sun Java Opmerking: Het certificaat moet zijn gemaakt voor het ondertekenen van code. U kunt geen SSL of ander type certificaat gebruiken om AIR-bestanden te ondertekenen.
Tijdstempels Wanneer u een AIR-bestand ondertekent, wordt bij de server van een tijdstempelinstantie gevraagd om een datum en tijd van ondertekening die onafhankelijk te verifiëren zijn. Het tijdstempel wordt ingesloten in het AIR-bestand. Wanneer het handtekeningcertificaat geldig is op het moment van ondertekenen, kan het AIR-bestand worden geïnstalleerd, zelfs nadat het certificaat is verlopen. Als er geen tijdstempel wordt opgehaald, kan het AIR-bestand niet meer worden geïnstalleerd wanneer het certificaat is verlopen of is ingetrokken.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 331 AIR-toepassingen distribueren, installeren en uitvoeren
Standaard wordt een tijdstempel opgehaald wanneer een AIR-pakket wordt gemaakt. U kunt het ophalen van een tijdstempel echter uitschakelen, zodat u toepassingspakketten kunt maken wanneer de tijdstempelservice niet beschikbaar is. Adobe raadt u aan in alle openbaar gedistribueerde AIR-bestanden een tijdstempel op te nemen. De standaardinstantie voor tijdstempels die voor AIR-pakketten wordt gebruikt, is Geotrust.
Certificaten ophalen Als u een certificaat nodig hebt, gaat u gewoonlijk naar de website van een certificeringsinstantie en voltooit u het aankoopproces van dat bedrijf. Welke hulpprogramma's nodig zijn om het sleutelarchiefbestand te maken, is afhankelijk van het type van het gekochte certificaat, hoe het certificaat op de ontvangende computer wordt opgeslagen en, in sommige gevallen, de browser waarmee het certificaat is opgehaald. Als u bijvoorbeeld een Adobe Developercertificaat wilt verkrijgen en exporteren van Thawte, moet u Mozilla Firefox gebruiken. Het certificaat kan vervolgens rechtstreeks vanuit de gebruikersinterface van Internet Explorer worden geëxporteerd als een .p12- of .pfx-bestand. U kunt een zelfondertekend certificaat genereren met het hulpprogramma ADT (Air Development Tool) waarmee AIR-toepassingsbestanden in een pakket worden geplaatst. U kunt ook sommige hulpprogramma's van derden gebruiken. Zie “AIR-installatiebestanden in een pakket plaatsen met ADT (AIR Developer Tool)” op pagina 365 voor instructies voor het genereren van een zelfondertekend certificaat en het ondertekenen van een AIR-bestand. U kunt AIRbestanden ook exporteren en ondertekenen met Flex Builder, Dreamweaver en de AIR-update voor Flash. In het volgende voorbeeld ziet u hoe u een AIR-certificaat voor ontwikkelaars ophaalt bij de certificeringsinstantie Thawte en dit voorbereidt voor gebruik met ADT.
Voorbeeld: Een AIR-certificaat voor ontwikkelaars ophalen bij Thawte Opmerking: Dit voorbeeld bevat slechts een van de vele manieren waarop u een certificaat voor ondertekening van programmacode kunt ophalen en voorbereiden. Elke certificeringsinstantie heeft zijn eigen beleid en procedures. Als u een AIR-certificaat voor ontwikkelaars wilt aanschaffen, moet u de website van Thawte bezoeken met de browser Mozilla Firefox. De persoonlijke sleutel voor het certificaat wordt opgeslagen in het sleutelarchief van de browser. Zorg ervoor dat het Firefox-sleutelarchief is beveiligd met een hoofdwachtwoord en dat de computer zelf fysiek is beveiligd. (U kunt het certificaat en de persoonlijke sleutel uit het sleutelarchief van de browser exporteren en verwijderen nadat het aankoopproces is voltooid.) Tijdens het certificaatinschrijvingsproces wordt een combinatie van een persoonlijke en een openbare sleutel gegenereerd. De persoonlijke sleutel wordt automatisch opgeslagen in het sleutelarchief van Firefox. Voor het aanvragen en het ophalen van het certificaat op de website van Thawte moet u dezelfde computer en browser gebruiken. 1 Ga op de website van Thawte naar de productpagina voor certificaten voor ondertekening van programmacode. 2 Selecteer Adobe AIR Developer Certificate in de lijst met certificaten voor ondertekening van programmacode. 3 Voltooi de drie stappen van het inschrijvingsproces. U moet gegevens van uw organisatie en een contactpersoon
opgeven. Thawte verifieert vervolgens uw identiteit en kan om aanvullende informatie vragen. Nadat de verificatie is voltooid, stuurt Thawte u een e-mailbericht met instructies voor het ophalen van het certificaat. Opmerking: Meer informatie over het type documentatie dat nodig is, kunt u hier vinden: https://www.thawte.com/ssl-digital-certificates/free-guides-whitepapers/pdf/enroll_codesign_eng.pdf. 4 Haal het uitgegeven certificaat op vanaf de site van Thawte. Het certificaat wordt automatisch opgeslagen in het
sleutelarchief van Firefox.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 332 AIR-toepassingen distribueren, installeren en uitvoeren
5 Exporteer op de volgende manier een sleutelarchiefbestand dat de persoonlijke sleutel en het certificaat uit het
sleutelarchief van Firefox bevat: Opmerking: Wanneer u de persoonlijke sleutel en het certificaat vanuit Firefox exporteert, worden deze geëxporteerd naar een P12-indeling (.pfx) die in ADT, Flex, Flash en Dreamweaver kan worden gebruikt. a Open in Firefox het dialoogvenster Certificatenbeheerder: b In Windows: Open Extra -> Opties -> Geavanceerd -> Codering -> Certificaten weergeven c In Mac OS: Open Firefox-> Voorkeuren-> Geavanceerd -> Codering -> Certificaten weergeven d In Linux: Open Bewerken-> Voorkeuren-> Geavanceerd -> Codering -> Certificaten weergeven e Selecteer het Adobe AIR-certificaat voor ondertekening van programmacode in de lijst met certificaten en klik
op de knop Reservekopie maken. f
Voer een bestandsnaam en een locatie in voor het te exporteren sleutelarchiefbestand en klik op Opslaan.
g Als u het hoofdwachtwoord van Firefox gebruikt, moet u uw wachtwoord voor het softwarebeveiligingsapparaat
invoeren om het bestand te exporteren. (Dit wachtwoord wordt alleen door Firefox gebruikt.) h Maak in het dialoogvenster Wachtwoord voor reservekopie van certificaat kiezen een wachtwoord voor het
sleutelarchiefbestand. Belangrijk: Dit wachtwoord beveiligt het sleutelarchiefbestand en is vereist wanneer het bestand wordt gebruikt voor het ondertekenen van AIR-toepassingen. Kies een veilig wachtwoord. i
Klik op OK. U ontvangt een bericht wanneer de reservekopie is gemaakt. Het sleutelarchiefbestand dat de persoonlijke sleutel en het certificaat bevat, wordt opgeslagen met de extensie .p12 (in de PKCS12-indeling).
6 Gebruik het geëxporteerde sleutelarchiefbestand in ADT, Flex Builder, Flash of Dreamweaver. Het wachtwoord dat
voor het bestand is gemaakt, is vereist wanneer een AIR-toepassing wordt ondertekend. Belangrijk: De persoonlijke sleutel en het certificaat blijven opgeslagen in het sleutelarchief van Firefox. Hoewel u daardoor een extra kopie van het certificaatbestand kunt exporteren, is dit ook een toegangspunt dat u moet beveiligen om de veiligheid van uw certificaat en de persoonlijke sleutel te garanderen.
Certificaten wijzigen Er zijn omstandigheden waarin u het certificaat moet wijzigen waarmee u uw AIR-toepassing ondertekent. Bijvoorbeeld:
• U wilt een zelfondertekend certificaat wijzigen in een certificaat dat door een ondertekeningsinstantie is uitgegeven.
• U wilt een zelfondertekend certificaat dat bijna is verlopen, wijzigen in een ander certificaat. • U wilt een commercieel certificaat wijzigen in een ander commercieel certificaat, bijvoorbeeld wanneer de identiteit van uw bedrijf is gewijzigd. Omdat het handtekeningcertificaat een van de elementen is waarmee de identiteit van een AIR-toepassing wordt bepaald, kunt u een update van uw toepassing niet gewoon ondertekenen met een ander certificaat. AIR herkent een AIR-bestand alleen als een update als u de oorspronkelijke en alle bijgewerkte AIR-bestanden met hetzelfde certificaat ondertekent. Anders wordt het nieuwe AIR-bestand geïnstalleerd als een afzonderlijke toepassing in plaats van dat de bestaande installatie wordt bijgewerkt. Vanaf AIR 1.1 kunt u het handtekeningcertificaat van een toepassing wijzigen met een migratiehandtekening. Een migratiehandtekening is een tweede handtekening voor het AIR-updatebestand. De migratiehandtekening gebruikt het oorspronkelijke certificaat, waardoor wordt vastgelegd dat de ondertekenaar de oorspronkelijke uitgever van de toepassing is.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 333 AIR-toepassingen distribueren, installeren en uitvoeren
Belangrijk: Het certificaat moet worden gewijzigd voordat het oorspronkelijke certificaat verloopt of wordt ingetrokken. Als u geen update maakt die met een migratiehandtekening is ondertekend voordat uw certificaat verloopt, moeten gebruikers de bestaande versie van uw toepassing verwijderen voordat zij updates installeren. Commerciële certificaten kunnen gewoonlijk worden vernieuwd om te voorkomen dat ze verlopen. Zelfondertekende certificaten kunnen niet worden vernieuwd. Certificaten wijzigen: 1 Maak een update voor uw toepassing. 2 Plaats het AIR-updatebestand in een pakket en onderteken het met het nieuwe certificaat. 3 Onderteken het AIR-bestand opnieuw met het oorspronkelijke certificaat (met de ADT-opdracht -migrate).
De procedure voor het toepassen van een migratiehandtekening wordt beschreven in “AIR-bestanden ondertekenen om het toepassingscertificaat te wijzigen” op pagina 375. Wanneer het bijgewerkte AIR-bestand wordt geïnstalleerd, verandert de identiteit van de toepassing. Deze identiteitsverandering heeft de volgende gevolgen:
• De uitgevers-id van de toepassing wordt gewijzigd in de uitgevers-id van het nieuwe certificaat. • De nieuwe versie van de toepassing heeft geen toegang tot gegevens in het bestaande gecodeerde lokale archief. • De locatie van de opslagmap van de toepassing wordt gewijzigd. Gegevens op de oude locatie worden niet naar de nieuwe map gekopieerd. (Maar de nieuwe toepassing kan de oorspronkelijke locatie wel vinden op basis van de oude uitgevers-id.)
• De toepassing kan geen lokale verbindingen meer openen met de oude uitgevers-id. • Als een gebruiker een AIR-bestand voor de migratie opnieuw installeert, wordt het geïnstalleerd als een afzonderlijke toepassing met de oorspronkelijke uitgevers-id. Uw toepassing is verantwoordelijk voor het migreren van alle gegevens tussen de oorspronkelijke en de nieuwe versie van de toepassing. Als u gegevens wilt migreren naar het ELS (Encrypted Local Store, gecodeerd lokaal archief), moet u de gegevens exporteren voordat de certificaatwijziging plaatsvindt. De nieuwe versie van uw toepassing kan het ELS van de oudere versie niet lezen. (Het is vaak eenvoudiger om de gegevens opnieuw te maken dan deze te migreren.) U kunt de migratiehandtekening het best blijven toepassen op zoveel mogelijk volgende updates. Anders moeten gebruikers die de oorspronkelijke toepassing nog niet hebben bijgewerkt een tussentijdse migratieversie installeren of hun huidige versie verwijderen voordat ze uw laatste update kunnen installeren. Uiteindelijk verloopt het oorspronkelijke certificaat natuurlijk en kunt u geen migratiehandtekening meer toepassen. (Tenzij u de tijdstempeloptie uitschakelt, blijven AIR-bestanden die eerder met een migratiehandtekening zijn ondertekend echter wel geldig. De migratiehandtekening krijgt een tijdstempel zodat AIR de handtekening ook accepteert nadat het certificaat is verlopen.) Een AIR-bestand met een migratiehandtekening is verder hetzelfde als een normaal AIR-bestand. Als de toepassing wordt geïnstalleerd op een systeem zonder de oorspronkelijke versie, wordt de nieuwe versie op de gebruikelijke manier geïnstalleerd. Opmerking: Wanneer u een commercieel certificaat vernieuwt, hoeft u het certificaat gewoonlijk niet te migreren. Een vernieuwd certificaat heeft dezelfde uitgevers-id als het oorspronkelijke certificaat, tenzij de DN-naam is gewijzigd. Zie “Informatie over uitgevers-id's voor AIR” op pagina 329 voor een volledige lijst met de certificaatkenmerken die worden gebruikt om de DN-naam te bepalen.
Terminologie Deze sectie bevat een woordenlijst met een aantal belangrijke termen die u moet begrijpen wanneer u beslissingen neemt over de manier waarop u uw toepassing ondertekent voor openbare distributie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 334 AIR-toepassingen distribueren, installeren en uitvoeren
Term
Beschrijving
Certificeringsinstantie (CA)
Een entiteit in een netwerk met een openbare-sleutelinfrastructuur die optreedt als vertrouwde derde partij en de identiteit van de eigenaar van een openbare sleutel certificeert. Een CA geeft gewoonlijk digitale certificaten uit, die met een eigen persoonlijke sleutel zijn ondertekend, om te verklaren dat de identiteit van de certificaathouder is geverifieerd.
CPS (Certificate Practice Statement)
Bevat de procedures en het beleid van de certificeringsinstantie voor het uitgeven en verifiëren van certificaten. De CPS is opgenomen in het contract tussen de CA en haar abonnees en afhankelijke partijen. Hierin wordt ook het beleid voor identiteitsverificatie beschreven en het garantieniveau van de uitgegeven certificaten.
CRL (Certificate Revocation List)
Een lijst met uitgegeven certificaten die zijn ingetrokken en niet meer mogen worden vertrouwd. AIR raadpleegt de CRL op het moment dat een AIR-toepassing wordt ondertekend, en als er geen tijdstempel aanwezig is, opnieuw wanneer de toepassing wordt geïnstalleerd.
Certificaatketen
Een certificaatketen is een reeks certificaten waarbij elk certificaat is ondertekend door het volgende certificaat.
Digitaal certificaat
Een digitaal document dat informatie bevat over de identiteit van de eigenaar, de openbare sleutel van de eigenaar en de identiteit van het certificaat zelf. Een certificaat dat door een certificeringsinstantie is uitgegeven, is zelf ondertekend door een certificaat dat eigendom is van de uitgevende certificeringsinstantie.
Digitale handtekening
Een gecodeerd bericht of gecodeerde samenvatting die alleen kan worden gedecodeerd met de openbare sleutel van een sleutelpaar met een openbaar en een persoonlijk gedeelte. In een PKI bevat een digitale handtekening een of meer digitale certificaten die uiteindelijk te traceren zijn tot de certificeringsinstantie. Een digitale handtekening kan worden gebruikt om te valideren of een bericht (of computerbestand) niet is veranderd sinds het werd ondertekend (binnen de zekerheidsbeperkingen van de gebruikte cryptografiealgoritme) en om de identiteit van de ondertekenaar te valideren (aangenomen dat de uitgevende certificeringsinstantie wordt vertrouwd).
Sleutelarchief
Een database die digitale certificaten bevat en soms ook de bijbehorende persoonlijke sleutels.
JCA (Java Cryptography Architecture)
Een uitbreidbare architectuur voor het beheer van en de toegang tot sleutelarchieven. Zie de Java Cryptography Architecture Reference Guide voor meer informatie.
PKCS #11
De interfacestandaard van RSA Laboratories voor cryptografietokens. Een sleutelarchief met hardwaretokens.
PKCS #12
De standaardsyntaxis van RSA Laboratories voor uitwisseling van persoonlijke gegevens. Een sleutelarchief met bestanden die gewoonlijk een persoonlijke sleutel en het bijbehorende digitale certificaat bevatten.
Persoonlijke sleutel
De persoonlijke helft van een asymmetrisch cryptografiesysteem dat uit een openbare en een persoonlijke sleutel bestaat. De persoonlijke sleutel moet geheim blijven en mag nooit via een netwerk worden verzonden. Digitaal ondertekende berichten worden door de ondertekenaar gecodeerd met de persoonlijke sleutel.
Openbare sleutel
De openbare helft van een asymmetrisch cryptografiesysteem dat uit een openbare en een persoonlijke sleutel bestaat. De openbare sleutel is algemeen beschikbaar en wordt gebruikt voor het decoderen van berichten die met de persoonlijke sleutel zijn gecodeerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 335 AIR-toepassingen distribueren, installeren en uitvoeren
Term
Beschrijving
PKI (Public Key Infrastructure)
Een systeem van vertrouwen waarin certificeringsinstanties de identiteit van de eigenaren van openbare sleutels bevestigen. Clients van het netwerk vertrouwen erop dat de digitale certificaten die door een vertrouwde CA zijn uitgegeven de identiteit van de ondertekenaar van een digitaal bericht (of bestand) garanderen.
Tijdstempel
Digitaal ondertekende informatie die de datum en tijd bevat waarop een gebeurtenis is opgetreden. ADT kan een tijdstempel van een RFC 3161-compatibele tijdserver opnemen in een AIR-pakket. Wanneer een tijdstempel aanwezig is, wordt dit gebruikt om de geldigheid van een certificaat vast te stellen op het moment van ondertekenen. Hierdoor kan een AIR-toepassing worden geïnstalleerd nadat het handtekeningcertificaat is verlopen.
Tijdstempelinstantie
Een instantie die tijdstempels uitgeeft. Om door AIR te worden herkend, moet een tijdstempel voldoen aan RFC 3161 en moet de handtekening van het tijdstempel via een certificaatketen kunnen worden gekoppeld aan een vertrouwd basiscertificaat op de installatiecomputer.
336
Hoofdstuk 33: AIR-toepassingen updaten Gebruikers kunnen een AIR-toepassing installeren of updaten door te dubbelklikken op een AIR-bestand op hun computer of vanuit de browser (met behulp van de functie voor naadloze installatie). Het installatieprogramma van Adobe® AIR™ beheert de installatie en waarschuwt de gebruiker als deze een bestaande toepassing wil updaten. (Zie “AIR-toepassingen distribueren, installeren en uitvoeren” op pagina 319.) Met behulp van de klasse Updater kunt u er echter ook voor zorgen dat een geïnstalleerde toepassing zichzelf bijwerkt naar een nieuwe versie. (Een geïnstalleerde toepassing kan mogelijk detecteren dat er een nieuwe versie beschikbaar is die kan worden gedownload en geïnstalleerd.) De klasse Updater bevat de methode update(), waarmee u naar een AIR-bestand op de computer van de gebruiker kunt verwijzen en een update naar die versie kunt uitvoeren. Zowel de toepassings- als de uitgevers-id van een AIR-updatebestand moeten overeenkomen met die van de toepassing die moet worden bijgewerkt. De uitgevers-id is afgeleid van het handtekeningcertificaat. Dit betekent dat zowel de update als de toepassing die moet worden bijgewerkt, moeten zijn ondertekend met hetzelfde certificaat. Vanaf AIR 1.1 en hoger kunt u overstappen op het gebruik van een nieuw digitaal ondertekend certificaat voor een toepassing. Dit wordt certificaatmigratie genoemd. Als u wilt overstappen op het gebruik van een nieuwe handtekening voor een toepassing, moet het AIR-updatebestand worden ondertekend met zowel het nieuwe als het oorspronkelijke certificaat. Certificaatmigratie is een eenrichtingsproces. Na de migratie worden alleen AIRbestanden die zijn ondertekend met het nieuwe certificaat (of met beide certificaten), herkend als updates voor een bestaande installatie. Het beheer van updates van toepassingen kan vrij gecompliceerd zijn. AIR 1.5 is voorzien van het nieuwe updateframework voor Adobe® AIR™-toepassingen. Dit framework biedt API's waarmee ontwikkelaars goede updatemogelijkheden kunnen inbouwen in AIR-toepassingen. U kunt certificaatmigratie gebruiken om over te stappen van een zelfondertekend certificaat op een commercieel digitaal ondertekend certificaat of om over te stappen van het ene zelfondertekende of commerciële certificaat op een ander. Als u niet voor migratie kiest, moeten bestaande gebruikers de huidige versie van uw toepassing van hun computer verwijderen voordat ze de nieuwe versie kunnen installeren. Zie “Certificaten wijzigen” op pagina 332 voor meer informatie.
Informatie over het updaten van toepassingen De klasse Updater (in het pakket flash.desktop) bevat één methode, namelijk de methode update(), waarmee u de toepassing die wordt uitgevoerd, kunt updaten naar een andere versie. Als bijvoorbeeld een versie van het AIR-bestand (Sample_App_v2.air) op het bureaublad van de gebruiker staat, wordt de toepassing met behulp van de volgende code bijgewerkt: var updater:Updater = new Updater(); var airFile:File = File.desktopDirectory.resolvePath("Sample_App_v2.air"); var version:String = "2.01"; updater.update(airFile, version);
Voordat de klasse Updater door een toepassing wordt gebruikt, moet de gebruiker of toepassing de bijgewerkte versie van het AIR-bestand downloaden naar de computer. Zie “AIR-bestanden naar de computer van de gebruiker downloaden” op pagina 338.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 337 AIR-toepassingen updaten
Resultaten van het oproepen van de methode Updater.update() Wanneer een toepassing in de runtime de methode update() oproept, sluit de runtime de toepassing af en probeert de runtime de nieuwe versie van de toepassing vanuit het AIR-bestand te installeren. De runtime controleert of de toepassings- en uitgevers-id in het AIR-bestand overeenkomen met de toepassings- en uitgevers-id voor de toepassing die de methode update() oproept. (Zie “Eigenschappen van AIR-toepassingen instellen” op pagina 45 voor informatie over de toepassings- en uitgevers-id.) De runtime controleert ook of de tekenreeks version overeenkomt met de tekenreeks version die aan de methode update() is doorgegeven. Als de installatie zonder problemen wordt voltooid, opent de runtime de nieuwe versie van de toepassing. Als de installatie niet kan worden voltooid, wordt opnieuw de bestaande (eerder geïnstalleerde) versie van de toepassing geopend. Als een gebruiker in Mac OS een recentere versie van een toepassing wil installeren, moet de gebruiker over voldoende toegangsrechten beschikken om te installeren in de toepassingsmap. In Windows of Linux moet de gebruiker over beheerdersrechten beschikken. Als de bijgewerkte versie van de toepassing een bijgewerkte versie van de runtime vereist, wordt de nieuwe runtimeversie geïnstalleerd. Voor het updaten van de runtime moet de gebruiker over beheerdersrechten voor de computer beschikken. Wanneer een toepassing wordt getest met ADL, resulteert het oproepen van de methode update() in een runtimeuitzondering.
Informatie over de tekenreeks version De tekenreeks die is opgegeven voor de parameter version van de methode update(), moet overeenkomen met de tekenreeks in het kenmerk version van het hoofdelementapplication van het descriptorbestand van de toepassing voor het AIR-bestand dat moet worden geïnstalleerd. Uit veiligheidsoverwegingen is het verplicht de parameter version op te geven. Door van de toepassing te eisen dat deze het versienummer in het AIR-bestand verifieert, zal de toepassing niet per ongeluk een oudere versie installeren. Een dergelijke oudere versie zou een zwakke plek in de beveiliging kunnen bevatten, die al is gerepareerd in de toepassing die op dat moment is geïnstalleerd. De toepassing moet ook de tekenreeks version in het AIR-bestand vergelijken met de tekenreeks version in de geïnstalleerde toepassing om te voorkomen dat de computer van de gebruiker wordt aangevallen en er ten onrechte een downgrade wordt uitgevoerd. De tekenreeks version kan elke gewenste notatie hebben. De tekenreeks kan bijvoorbeeld bestaan uit cijfers, zoals '2.01', maar ook uit cijfers en letters, zoals 'versie 2'. U, als ontwikkelaar van de toepassing, mag zelf bepalen welke notatie u gebruikt voor deze tekenreeks. De runtime valideert de tekenreeks version niet. De code van de toepassing moet deze tekenreeks valideren voordat de toepassing wordt bijgewerkt. Als een Adobe AIR-toepassing een AIR-bestand via het web downloadt, is het een goede gewoonte om een mechanisme te gebruiken waarmee de webservice de Adobe AIR-toepassing kan informeren over de versie die wordt gedownload. De toepassing kan deze tekenreeks vervolgens gebruiken voor de parameter version van de methode update(). Als het AIR-bestand op een andere manier wordt verkregen, waarbij de versie van het AIR-bestand onbekend blijft, kan de AIR-toepassing het AIR-bestand onderzoeken om de versiegegevens vast te stellen. (Een AIRbestand is een met ZIP gecomprimeerd archief en het descriptorbestand van de toepassing is de tweede record in het archief.) Zie “Eigenschappen van AIR-toepassingen instellen” op pagina 45 voor meer informatie over het descriptorbestand van een toepassing.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 338 AIR-toepassingen updaten
Aangepaste gebruikersinterfaces voor toepassingsupdates presenteren AIR bevat een standaardinterface voor updates:
Deze interface wordt altijd gebruikt wanneer een gebruiker voor het eerst een versie van een toepassing op een computer installeert. U kunt echter uw eigen interface definiëren die moet worden gebruikt voor daarop volgende instanties. Als in uw toepassing een aangepaste interface voor updates wordt gedefinieerd, specificeert u een customUpdateUI-element in het descriptorbestand voor de nu geïnstalleerde toepassing: <customUpdateUI>true
Wanneer de toepassing is geïnstalleerd en de gebruiker een AIR-bestand opent met een toepassings- en een uitgeversid die overeenkomen met die van de geïnstalleerde toepassing, opent de runtime de toepassing in plaats van het standaard installatieprogramma van AIR. Zie “Aangepaste gebruikersinterfaces voor toepassingsupdates bieden” op pagina 53 voor meer informatie. Wanneer de toepassing wordt uitgevoerd (wanneer het object NativeApplication.nativeApplication de gebeurtenis load verzendt), kan de toepassing beslissen of de toepassing moet worden bijgewerkt (met behulp van de klasse Updater). Als de toepassing besluit een update uit te voeren, kan deze een eigen installatie-interface presenteren aan de gebruiker (die verschilt van de standaardinterface die wordt weergegeven als de toepassing wordt uitgevoerd).
AIR-bestanden naar de computer van de gebruiker downloaden Met de klasse Updater moet de gebruiker of de toepassing eerst een AIR-bestand lokaal op de computer van de gebruiker opslaan. Opmerking: AIR 1.5 is voorzien van een updateframework waarmee ontwikkelaars goede updatemogelijkheden kunnen inbouwen in AIR-toepassingen. In veel gevallen is het handiger om gebruik te maken van dit framework dan om de methode update() van de klasse Update rechtstreeks te gebruiken. Raadpleeg “Het updateframework gebruiken” op pagina 340 voor meer informatie.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 339 AIR-toepassingen updaten
Met de volgende code wordt bijvoorbeeld een AIR-bestand gelezen van een URL (http://example.com/air/updates/Sample_App_v2.air) en wordt het AIR-bestand in de opslagmap van de toepassing opgeslagen: var urlString:String = "http://example.com/air/updates/Sample_App_v2.air"; var urlReq:URLRequest = new URLRequest(urlString); var urlStream:URLStream = new URLStream(); var fileData:ByteArray = new ByteArray(); urlStream.addEventListener(Event.COMPLETE, loaded); urlStream.load(urlReq); function loaded(event:Event):void { urlStream.readBytes(fileData, 0, urlStream.bytesAvailable); writeAirFile(); } function writeAirFile():void { var file:File = File.applicationStorageDirectory.resolvePath("My App v2.air"); var fileStream:FileStream = new FileStream(); fileStream.open(file, FileMode.WRITE); fileStream.writeBytes(fileData, 0, fileData.length); fileStream.close(); trace("The AIR file is written."); }
Zie “Workflow voor het lezen van en schrijven naar bestanden” op pagina 124 voor meer informatie.
Controleren of een toepassing voor de eerste keer wordt uitgevoerd Wanneer u eenmaal een toepassing hebt bijgewerkt, kunt u desgewenst een informatief bericht of een welkomstbericht voor de gebruiker weergeven. Wanneer de toepassing wordt gestart, controleert de toepassing of deze voor het eerst wordt uitgevoerd, om te bepalen of het bericht moet worden weergegeven. Opmerking: AIR 1.5 is voorzien van een updateframework waarmee ontwikkelaars goede updatemogelijkheden kunnen inbouwen in AIR-toepassingen. Dit framework biedt gemakkelijke methoden om te controleren of een versie van een toepassing voor de eerste keer wordt uitgevoerd. Raadpleeg “Het updateframework gebruiken” op pagina 340 voor meer informatie. Deze controle kan onder andere worden uitgevoerd als u een bestand in de opslagmap van de toepassing opslaat bij het initialiseren van de toepassing. Telkens wanneer de toepassing wordt opgestart, controleert de toepassing of dat bestand bestaat. Als het bestand niet bestaat, wordt de toepassing voor de eerste keer uitgevoerd voor de huidige gebruiker. Als het bestand bestaat, is de toepassing al ten minste één keer uitgevoerd. Als het bestand bestaat maar een versienummer bevat dat ouder is dan het huidige versienummer, weet u dat de gebruiker de nieuwe versie voor de eerste keer uitvoert. Als uw toepassing gegevens lokaal opslaat (bijvoorbeeld in de opslagmap van de toepassing), wordt u aangeraden te controleren of er eerder opgeslagen gegevens (van vorige versies) aanwezig zijn wanneer de toepassing voor het eerst wordt uitgevoerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 340 AIR-toepassingen updaten
Het updateframework gebruiken Het beheer van updates van toepassingen kan vrij gecompliceerd zijn. Het updateframework voor AdobeAIRtoepassingen biedt API's waarmee ontwikkelaars goede updatemogelijkheden kunnen inbouwen in AIR-toepassingen. De functionaliteit van het AIR-updateframework helpt ontwikkelaars met het volgende:
• Periodiek controleren op updates op basis van een interval of op verzoek van de gebruiker • Downloaden van AIR-bestanden (updates) van een bron op het web • De gebruiker waarschuwen wanneer de nieuw geïnstalleerde versie voor het eerst wordt uitgevoerd • Bevestigen dat de gebruiker wil controleren op updates • Informatie over de nieuwe updateversie weergeven aan de gebruiker • Informatie over de voortgang van het downloaden en eventuele fouten weergeven aan de gebruiker Het AIR-updateframework is voorzien van een voorbeeldgebruikersinterface die u in uw toepassing kunt gebruiken. Deze biedt de gebruiker basisinformatie en opties met betrekking tot updates van de toepassing. Uw toepassing kan ook een eigen aangepaste gebruikersinterface definiëren voor gebruik met het updateframework. Met het AIR-updateframework kunt u informatie over de updateversie van een AIR-toepassing opslaan in eenvoudige XML-configuratiebestanden. Bij de meeste toepassingen beschikt de eindgebruiker over een goede updatefunctionaliteit als u deze configuratiebestanden instelt en wat basiscode toevoegt. Zelfs als u niet gebruikmaakt van het updateframework, omvat Adobe AIR een klasse Updater die AIR-toepassingen kunnen gebruiken om te upgraden naar een nieuwe versie. Met deze klasse kan een toepassing een upgrade uitvoeren naar een versie die aanwezig is in een AIR-bestand op de computer van de gebruiker. Bij upgrademanagement komt echter vaak meer bij kijken dan alleen de update in een lokaal opgeslagen AIR-bestand.
Bestanden in het AIR-updateframework Het AIR-updateframework omvat de volgende mappen:
• doc—De documentatie (die u nu aan het lezen bent) voor het AIR-updateframework. • frameworks—Deze map bevat SWC-bestanden voor Flex-ontwikkeling en SWF-bestanden voor HTMLontwikkeling. Zie de volgende secties voor meer informatie:
• “De Flex-ontwikkelomgeving instellen” op pagina 340 • “Frameworkbestanden opnemen in een HTML-gebaseerde AIR-toepassing” op pagina 341 • samples—Deze map bevat Flex- en HTML-gebaseerde voorbeelden waarmee wordt aangegeven hoe het updateframework voor toepassingen kan worden gebruikt. U compileert en test deze bestanden op dezelfde manier als een AIR-toepassing.
• templates—Deze map bevat voorbeelden van update-descriptorbestanden (eenvoudig en gelokaliseerd) en configuratiebestanden. (Zie De Flex-ontwikkelomgeving instellen en “Eenvoudig voorbeelden: De ApplicationUpdaterUI-versie gebruiken” op pagina 341 voor meer informatie over deze bestanden.)
De Flex-ontwikkelomgeving instellen De map frameworks/flex van het updateframework bevat de volgende bestanden:
• ApplicationUpdater.swc—Definieert de basisfunctionaliteit van de updatebibliotheek, zonder gebruikersinterface • ApplicationUpdater_UI.swc—Definieert de basisfunctionaliteit van de updatebibliotheek en omvat een gebruikersinterface die uw toepassing kan gebruiken om de update-opties weer te geven
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 341 AIR-toepassingen updaten
SWC-bestanden definiëren klassen die u kunt gebruiken bij de Flex-ontwikkeling. Als u het updateframework wilt gebruiken bij het compileren met de Flex SDK, neemt u het bestand ApplicationUpdater.swc of ApplicationUpdater_UI.swc op in de aanroep naar de amxmlc-compiler. In het volgende voorbeeld laadt de compiler het bestand ApplicationUpdater.swc in de submap lib van de Flex SDK-map: amxmlc -library-path+=lib/ApplicationUpdater.swc
-- myApp.mxml
In het volgende voorbeeld laadt de compiler het bestand ApplicationUpdater_UI.swc in de submap lib van de Flex SDK-map: amxmlc -library-path+=lib/ApplicationUpdater_UI.swc
-- myApp.mxml
Als u toepassingen ontwikkeld met Flex Builder, voegt u het SWC-bestand toe op het tabblad Library Path van de Flex Build Path-instellingen in het dialoogvenster Properties. Let op dat u de SWC-bestanden kopieert naar de map waarnaar u verwijst in de amxmlc-compiler (wanneer u gebruikmaakt van Flex SDK) of Flex Builder.
Frameworkbestanden opnemen in een HTML-gebaseerde AIR-toepassing De map frameworks/html van het updateframework bevat de volgende SWF-bestanden:
• ApplicationUpdater.swf—Definieert de basisfunctionaliteit van de updatebibliotheek, zonder gebruikersinterface • ApplicationUpdater_UI.swf—Definieert de basisfunctionaliteit van de updatebibliotheek en omvat een gebruikersinterface die uw toepassing kan gebruiken om de update-opties weer te geven JavaScript-code in AIR-toepassingen kan gebruikmaken van klassen die zijn gedefinieerd in SWF-bestanden. Als u het updateframework wilt gebruiken, neemt u het bestand ApplicationUpdater.swf of ApplicationUpdater_UI.swf op in uw toepassingsmap (of een submap). Voeg vervolgens in het HTML-bestand dat het framework zal gebruiken (in JavaScript-code) een script-tag op waardoor het bestand wordt geladen: <script src="applicationUpdater.swf" type="application/x-shockwave-flash"/>
U kunt ook deze script-tag gebruiken om het bestand ApplicationUpdater_UI.swf te laden: <script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"/>
De API die wordt gedefinieerd in deze twee bestanden, wordt beschreven in het resterende deel van dit document.
Eenvoudig voorbeelden: De ApplicationUpdaterUI-versie gebruiken De ApplicationUpdaterUI-versie van het updateframework biedt een basisinterface die u gemakkelijk kunt gebruiken in uw toepassing. Hier volgt een eenvoudig voorbeeld. Maak eerst een AIR-toepassing die het updateframework aanroept: 1 Als het een HTML-gebaseerde AIR-toepassing is, laadt u het bestand ApplicationUpdaterUI.js: <script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"/>
2 Instantieer in de AIR-toepassingsprogrammalogica een object ApplicationUpdaterUI.
Gebruik in ActionScript de volgende code: var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI();
Gebruik in JavaScript de volgende code: var appUpdater = new runtime.air.update.ApplicationUpdaterUI();
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 342 AIR-toepassingen updaten
U kunt desgewenst deze code toevoegen aan een initialisatiefunctie die wordt uitgevoerd wanneer de toepassing is geladen. 3 Maak een tekstbestand met de naam updateConfig.xml en voeg daar het volgende aan toe: http://example.com/updates/update.xml <delay>1
Bewerk het URL-element van het bestand updateConfig.xml zodat dit overeenkomt met de uiteindelijke locatie van het update-descriptorbestand op uw webserver (zie de volgende procedure). delayis het aantal dagen dat de toepassing wacht voordat wordt gecontroleerd of er een update beschikbaar is.
4 Voeg het bestand updateConfig.xml toe aan de projectmap van uw AIR-toepassing. 5 Zorg dat het updater-object verwijst naar het bestand updateConfig.xml en roep de methode initialize() van
het object aan. Gebruik in ActionScript de volgende code: appUpdater.configurationFile = new File("app:/updateConfig.xml"); appUpdater.initialize();
Gebruik in JavaScript de volgende code: appUpdater.configurationFile = new air.File("app:/updateConfig.xml"); appUpdater.initialize();
6 Maak een tweede versie van de AIR-toepassing, die verschilt van de eerste versie van deze toepassing. (De versie
wordt gespecificeerd in het descriptorbestand van de toepassing, in het element version.) Voeg vervolgens de geüpdate versie van de AIR-toepassing toe aan uw webserver: 1 Plaats de geüpdate versie van het AIR-bestand op uw webserver. 2 Maak een tekstbestand met de naam updateDescriptor.xml en voeg daar de volgende inhoud aan toe: 1.1http://example.com/updates/sample_1.1.air <description>This is the latest version of the Sample application.
Bewerk de version, URL en description van het bestand updateDescriptor.xml zodat deze overeenkomen met uw geüpdate AIR-bestand. 3 Voeg het bestand updateDescriptor.xml toe aan dezelfde map op de webserver die het geüpdate AIR-bestand bevat.
Dit is een eenvoudig voorbeeld, maar de updatefunctionaliteit die hier beschreven wordt is voldoende voor veel toepassingen. In de rest van dit document wordt beschreven hoe u het updateframework zo kunt gebruiken dat het optimaal voldoet aan uw vereisten. Voor een ander voorbeeld van het gebruik van het update-raamwerk bekijkt u de volgende voorbeeldtoepassing in het Adobe AIR developer center: Update-raamwerk in een Flash-toepassing (http://www.adobe.com/go/learn_air_qs_update_framework_flash_nl).
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 343 AIR-toepassingen updaten
Het update-descriptorbestand definiëren en het AIR-bestand toevoegen aan uw webserver Wanneer u het AIR-updateframework gebruikt, definieert u de basisgegevens over de beschikbare update in een update-descriptorbestand dat wordt opgeslagen op uw webserver. Het update-descriptorbestand is een eenvoudig XML-bestand. Het updateframework dat is opgenomen in de toepassing, controleert dit bestand om na te gaan of een nieuwe versie is geüpload. Het update-descriptorbestand bevat de volgende gegevens:
•
version—De nieuwe versie van de AIR-toepassing. In het nieuwe AIR-toepassingsdescriptorbestand moet
dezelfde tekenreeks worden gebruikt als de versie. Als de versie in het update-descriptorbestand niet overeenkomt met de versie van het geüpdate AIR-bestand, produceert het framework een uitzonderingsfout.
•
url—De locatie van het geüpdate AIR-bestand. Dit is het bestand dat de geüpdate versie van de AIR-toepassing bevat.
•
description—Meer informatie over de nieuwe versie. Deze informatie kan tijdens het updaten worden weergegeven aan de gebruiker.
De elementen version en url zijn verplicht. Het element description is optioneel. Dit is een voorbeeld van een update-descriptorbestand: 1.1a1http://example.com/updates/sample_1.1a1.air <description>This is the latest version of the Sample application.
Als u de tag description wilt definiëren voor meerdere talen, gebruikt u meerdere text-elementen die allemaal een lang-attribuut definiëren: 1.1a1http://example.com/updates/sample_1.1a1.air <description> English descriptionFrench descriptionRomanian description
Plaats het update-descriptorbestand samen met het geüpdate AIR-bestand op uw webserver. De map templates die wordt opgenomen bij de update-descriptor, bevat voorbeelden van update-descriptorbestanden. Hierbij zijn eentalige en meertalige versies.
Een updater-object instantiëren Nadat u het AIR-updateframework hebt geladen in uw code (zie “De Flex-ontwikkelomgeving instellen” op pagina 340 en “Frameworkbestanden opnemen in een HTML-gebaseerde AIR-toepassing” op pagina 341), moet u een updater-object instantiëren, zoals in het volgende voorbeeld: var appUpdater:ApplicationUpdater = new ApplicationUpdater();
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 344 AIR-toepassingen updaten
De vorige code maakt gebruik van de klasse ApplicationUpdater (die geen gebruikersinterface biedt). Als u de klasse ApplicationUpdaterUI wilt gebruiken (die wel een gebruikersinterface biedt), gebruikt u het volgende: var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI();
In de overige codevoorbeelden in dit document wordt ervan uitgegaan dat u een updater-object met de naam appUpdater hebt geïnstantieerd.
De update-instellingen configureren Zowel ApplicationUpdater als ApplicationUpdaterUI kunnen worden geconfigureerd via een configuratiebestand dat wordt geleverd met de toepassing, of via ActionScript of JavaScript in de toepassing.
Update-instellingen definiëren in een XML-configuratiebestand Het update-configuratiebestand is een XML-bestand. Dit kan de volgende elementen bevatten:
•
updateURL— Een tekenreeks. Deze geeft de locatie van de update-descriptor op de externe server aan. Iedere geldige URLRequest-locatie is toegestaan. U moet de eigenschap updateURL definiëren via het configuratiebestand of via een script (zie “Het update-descriptorbestand definiëren en het AIR-bestand toevoegen aan uw webserver” op pagina 343). U moet deze eigenschap definiëren voordat u de updater gebruikt (voordat u de methode initialize() van het updater-object aanroept, beschreven in “Het updateframework initialiseren” op pagina 346).
•
delay—Een getal. Dit geeft het tijdsinterval in dagen aan (waarden zoals 0,25 zijn toegestaan) waarna op updates
moet worden gecontroleerd. De standaardwaarde 0 specificeert dat de updater geen automatische periodieke controles uitvoert. Het configuratiebestand voor de ApplicationUpdaterUI kan naast de elementen updateURL en delay het volgende bevatten:
•
•
defaultUI: Een lijst van dialog-elementen. Ieder dialog-element heeft een attribuut name dat correspondeert met een dialoogvenster in de gebruikersinterface. Ieder dialogelement heeft een attribuut visible dat aangeeft of het dialoogvenster zichtbaar is. De standaardwaarde is true. Het attribuut name heeft de volgende mogelijke waarden:
•
"checkForUpdate"—Correspondeert met de dialoogvensters Check for Update, No Update en Update Error
•
"downloadUpdate"—Correspondeert met het dialoogvenster Download Update
•
"downloadProgress"—Correspondeert met de dialoogvensters Download Progress en Download Error
•
"installUpdate"—Correspondeert met het dialoogvenster Install Update
•
"fileUpdate"—Correspondeert met de dialoogvensters File Update, File No Update en File Error
"unexpectedError"—Correspondeert met het dialoogvenster Unexpected Error
Wanneer de waarde wordt ingesteld op false, wordt het corresponderende dialoogvenster niet weergegeven als onderdeel van de updateprocedure. Hier ziet u een voorbeeld van het configuratiebestand voor het ApplicationUpdater-framework: http://example.com/updates/update.xml <delay>1
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 345 AIR-toepassingen updaten
Hier ziet u een voorbeeld van het configuratiebestand voor het ApplicationUpdaterUI-framework, dat een definitie van het defaultUI-element bevat: http://example.com/updates/update.xml <delay>1 <defaultUI>
Verwijs voor de eigenschap configurationFile naar de locatie van dat bestand: zoals in het volgende
• ActionScript: appUpdater.configurationFile = new File("app:/cfg/updateConfig.xml");
• JavaScript: appUpdater.configurationFile = new air.File("app:/cfg/updateConfig.xml");
De map templates van het updateframework bevat een voorbeeldconfiguratiebestand, config-template.xml.
Update-instellingen definiëren met behulp van ActionScript- of JavaScript-code U kunt deze configuratieparameters ook instellen door middel van code in de toepassing, zoals in het volgende voorbeeld: appUpdater.updateURL = " http://example.com/updates/update.xml"; appUpdater.delay = 1;
De eigenschappen van het updater-object zijn updateURL en delay. Deze eigenschappen definiëren dezelfde instellingen als de elementen updateURL en delay in het configuratiebestand: de URL van het updatedescriptorbestand en het interval waarna op updates moet worden gecontroleerd. Als u een configuratiebestand en instellingen in code definieert, hebben de eigenschappen die zijn ingesteld via code voorrang op de corresponderende instellingen in het configuratiebestand. U moet de eigenschap updateURL definiëren, via het configuratiebestand of via een script (zie “Het updatedescriptorbestand definiëren en het AIR-bestand toevoegen aan uw webserver” op pagina 343), vóórdat u de updater gebruikt (voordat u de methode initialize()van het updater-object aanroept zoals beschreven in “Het updateframework initialiseren” op pagina 346). Het ApplicationUpdaterUI-framework definieert de volgende aanvullende eigenschappen van het updater-object:
•
isCheckForUpdateVisible—Correspondeert met de dialoogvensters Check for Update, No Update en Update Error
•
isDownloadUpdateVisible—Correspondeert met het dialoogvenster Download Update
•
isDownloadProgressVisible—Correspondeert met de dialoogvensters Download Progress en Download Error
•
isInstallUpdateVisible—Correspondeert met het dialoogvenster Install Update
•
isFileUpdateVisible—Correspondeert met de dialoogvensters File Update, File No Update en File Error
•
isUnexpectedErrorVisible—Correspondeert met het dialoogvenster Unexpected Error
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 346 AIR-toepassingen updaten
Iedere eigenschap correspondeert met een of meer dialoogvensters in de ApplicationUpdaterUI-gebruikersinterface. Iedere eigenschap is een Booleaanse waarde met een standaardwaarde van true (waar). Wanneer de waarde wordt ingesteld op false, worden de corresponderende dialoogvensters niet weergegeven als onderdeel van de updateprocedure. Deze dialoogvenstereigenschappen hebben voorrang op de instellingen in het update-configuratiebestand.
Het updateproces Het AIR-updateframework voert het updateproces uit in de volgende stappen: 1 De updater-initialisatieprocedure controleert of er een updatecontrole is uitgevoerd binnen het gedefinieerde
delay-interval (zie “De update-instellingen configureren” op pagina 344). Als er een updatecontrole moet worden uitgevoerd, wordt het updateproces voortgezet. 2 De updater downloadt en interpreteert het update-descriptorbestand. 3 De updater downloadt het geüpdate AIR-bestand. 4 De updater installeert de geüpdate versie van de toepassing.
Bij iedere stap die wordt voltooid, verzendt het updater-object gebeurtenissen. In de ApplicationUpdater-versie kunt u de gebeurtenissen annuleren die de geslaagde voltooiing van een stap in het proces aangeven. Als u een van deze gebeurtenissen annuleert, wordt de volgende stap in het proces geannuleerd. In de ApplicationUpdaterUI-versie geeft de updater een dialoogvenster weer waarmee de gebruiker het proces bij iedere stap kan annuleren of voortzetten. Als u de gebeurtenis annuleert, kunt u methoden van het updater-object aanroepen om het proces te hervatten. Terwijl de ApplicationUpdater-versie van de updater het updateproces doorloopt, wordt de huidige status ervan geregistreerd in de eigenschap currentState. Deze eigenschap wordt ingesteld op een tekenreeks die de volgende waarden kan hebben:
•
"UNINITIALIZED"—De updater is niet geïnitialiseerd.
•
"INITIALIZING"—De updater is bezig met initialiseren.
•
"READY"—De updater is geïnitialiseerd.
•
"BEFORE_CHECKING"—De updater heeft nog niet gecontroleerd op het update-descriptorbestand.
•
"CHECKING"—De updater controleert op de aanwezigheid van een update-descriptorbestand.
•
"AVAILABLE"—Het update-descriptorbestand is beschikbaar.
•
"DOWNLOADING"—De updater downloadt het AIR-bestand.
•
"DOWNLOADED"—De updater heeft het AIR-bestand gedownload.
•
"INSTALLING"—De updater is het AIR-bestand aan het installeren.
•
"PENDING_INSTALLING"—De updater is geïnitialiseerd en er zijn updates in behandeling.
Bepaalde methoden van het updater-object worden alleen uitgevoerd als de updater een bepaalde status heeft.
Het updateframework initialiseren Nadat u de configuratie-eigenschappen hebt ingesteld (zie “Eenvoudig voorbeelden: De ApplicationUpdaterUI-versie gebruiken” op pagina 341), roept u de methode initialize() aan om de update te initialiseren: appUpdater.initialize();
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 347 AIR-toepassingen updaten
Deze methode doet het volgende:
• De methode initialiseert het updateframework, waarbij eventuele updates in behandeling synchroon zonder toezicht worden geïnstalleerd. Het is verplicht deze methode aan te roepen tijdens het opstarten van de toepassing, omdat de toepassing tijdens het aanroepen mogelijk opnieuw wordt opgestart.
• De methode controleert of er een uitgestelde update is, en installeert deze. • Als er tijdens het updateproces een fout optreedt, worden het updatebestand en de versie-informatie gewist uit het opslaggebied van de toepassing.
• Als de opgegeven vertragingsperiode (delay) is verlopen, wordt het updateproces gestart. Als dat niet het geval is, wordt de timer opnieuw gestart. Het aanroepen van deze methode kan als resultaat hebben dat het updater-object de volgende gebeurtenissen verzendt:
•
UpdateEvent.INITIALIZED—Wordt verzonden wanneer de initialisatie is voltooid.
•
ErrorEvent.ERROR—Wordt verzonden wanneer er tijdens de initialisatie een fout optreedt.
Na het verzenden van de gebeurtenis UpdateEvent.INITIALIZED is het updateproces voltooid. Wanneer u de methode initialize() aanroept, start de updater het updateproces en worden alle stappen voltooid op basis van de ingestelde waarde voor delay. U kunt het updateproces echter altijd opstarten door de methode checkNow() van het updater-object aan te roepen: appUpdater.checkNow();
Deze methode doet niets als het updateproces al actief is. Zo niet, dan wordt het updateproces gestart. Het updater-object kan als resultaat van het aanroepen van de methode checkNow() de volgende gebeurtenis verzenden:
• gebeurtenis UpdateEvent.CHECK_FOR_UPDATE vlak voordat de poging het update-descriptorbestand te downloaden, wordt uitgevoerd. Als u de gebeurtenis checkForUpdate annuleert, kunt u de methode checkForUpdate() van het updater-object aanroepen. (Zie de volgende sectie.) Als u de gebeurtenis niet annuleert, controleert het updateproces op het updatedescriptorbestand.
Het updateproces beheren in de ApplicationUpdaterUI-versie In de ApplicationUpdaterUI-versie kan de gebruiker het proces annuleren door middel van de knop Cancel (Annuleren) in de dialoogvensters van de gebruikersinterface. U kunt het updateproces ook via programmacode annuleren door de methode cancelUpdate() van het object ApplicationUpdaterUI aan te roepen. U kunt eigenschappen van het ApplicationUpdaterUI-object instellen of u kunt elementen in het updateconfiguratiebestand definiëren om te bepalen welke bevestigingen in dialoogvensters worden weergegeven door de updater. Raadpleeg “De update-instellingen configureren” op pagina 344 voor meer informatie.
Het updateproces beheren in de ApplicationUpdater-versie U kunt de methode preventDefault() van gebeurtenisobjecten aanroepen die zijn verzonden door het object ApplicationUpdater om stappen van het updateproces te annuleren (zie “Het updateproces” op pagina 346). Door het standaardgedrag te annuleren heeft uw toepassing de mogelijkheid om een bericht weer te geven waarin de gebruiker wordt gevraagd of deze wil doorgaan. In de volgende secties wordt beschreven hoe u het updateproces kunt voortzetten wanneer een stap van het proces is geannuleerd.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 348 AIR-toepassingen updaten
Het update-descriptorbestand downloaden en interpreteren Het object ApplicationUpdater verzendt de gebeurtenis checkForUpdate voordat het updateproces begint, vlak voordat de updater probeert het update-descriptorbestand te downloaden. Als u het standaardgedrag van de gebeurtenis checkForUpdate annuleert, downloadt de updater het update-descriptorbestand niet. U kunt de methode checkForUpdate() gebruiken om het updateproces te hervatten: appUpdater.checkForUpdate();
Door het aanroepen van de methode checkForUpdate() zal de updater het update-descriptorbestand asynchroon downloaden en interpreteren. Als resultaat van het aanroepen van de methode checkForUpdate() kan de updater de volgende gebeurtenissen verzenden:
•
StatusUpdateEvent.UPDATE_STATUS—De updater heeft het update-descriptorbestand gedownload en geïnterpreteerd. Deze gebeurtenis heeft de volgende eigenschappen:
•
available—Een Booleaanse waarde. Wordt ingesteld op true als er een andere versie dan die van de huidige
toepassing beschikbaar is; als de versie hetzelfde is, wordt deze ingesteld op false.
•
version—Een tekenreeks. De versie van het toepassingsdescriptorbestand van het updatebestand
•
details—Een array. Als er geen gelokaliseerde versies van de beschrijving aanwezig zijn, retourneert deze array
een lege tekenreeks ("") als het eerste element en de beschrijving als het tweede element. Als er meerdere versies van de beschrijving aanwezig zijn (in het update-descriptorbestand), bevat deze array meerdere sub-array's. Iedere array heeft twee elementen: het eerste is een taalcode (bijvoorbeeld "en"), het tweede is de corresponderende beschrijving (een tekenreeks) voor die taal. Zie “Het update-descriptorbestand definiëren en het AIR-bestand toevoegen aan uw webserver” op pagina 343.
•
StatusUpdateErrorEvent.UPDATE_ERROR—Er is een fout opgetreden en de updater kon het update-
descriptorbestand niet downloaden of interpreteren.
Het update-AIR-bestand downloaden Het object ApplicationUpdater verzendt de gebeurtenis updateStatus nadat de updater het updatedescriptorbestand heeft gedownload en geïnterpreteerd. Het standaardgedrag is dat wordt gestart met het downloaden van het updatebestand als dit beschikbaar is. Als u het standaardgedrag annuleert, kunt u de methode downloadUpdate() aanroepen om het updateproces te hervatten: appUpdater.downloadUpdate();
Door het aanroepen van deze methode downloadt de updater asynchroon de updateversie van het AIR-bestand. De methode downloadUpdate() kan de volgende gebeurtenissen verzenden:
•
UpdateEvent.DOWNLOAD_START—De verbinding met de server is tot stand gebracht. Wanneer de
ApplicationUpdaterUI-bibliotheek wordt gebruikt, wordt door deze gebeurtenis een dialoogvenster weergegeven met een voortgangsbalk die de voortgang van het downloaden aangeeft.
•
ProgressEvent.PROGRESS—Wordt periodiek verzonden terwijl het bestand wordt gedownload.
•
DownloadErrorEvent.DOWNLOAD_ERROR—Wordt verzonden als er een fout optreedt bij de verbinding of het downloaden van het updatebestand. Wordt ook verzonden bij een ongeldige HTTP-status (bijvoorbeeld “404 Bestand niet gevonden”). Deze gebeurtenis heeft een eigenschap errorID, een geheel getal waarmee aanvullende foutgegevens worden gedefinieerd. Een aanvullende eigenschap subErrorID kan meer foutgegevens bevatten.
•
UpdateEvent.DOWNLOAD_COMPLETE—De updater heeft het update-descriptorbestand gedownload en
geïnterpreteerd. Als u deze gebeurtenis niet annuleert, gaat de ApplicationUpdater-versie door met de installatie van de updateversie. In de ApplicationUpdaterUI-versie krijgt de gebruiker een dialoogvenster te zien waarin deze de mogelijkheid krijgt om door te gaan.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 349 AIR-toepassingen updaten
De toepassing updaten Het object ApplicationUpdater verzendt de gebeurtenis downloadComplete wanneer het downloaden van het updatebestand is voltooid. Als u het standaardgedrag annuleert, kunt u de methode installUpdate() aanroepen om het updateproces te hervatten: appUpdater.installUpdate(file);
Door het aanroepen van deze methode installeert de updater een updateversie van het AIR-bestand. Deze methode omvat een parameter, file, die bestaat uit een object File dat verwijst naar het AIR-bestand dat als update moet worden gebruikt. Het object ApplicationUpdater kan de gebeurtenis beforeInstall verzenden als resultaat van het aanroepen van de methode installUpdate():
•
UpdateEvent.BEFORE_INSTALL—Wordt verzonden vlak voordat de update wordt geïnstalleerd. In bepaalde
gevallen is het aan te raden te voorkomen dat de update op dit moment wordt geïnstalleerd, zodat de gebruiker het huidige werk kan afmaken voordat de update wordt voortgezet. Als de methode preventDefault() van het object Event wordt aangeroepen, wordt de installatie uitgesteld totdat het systeem opnieuw wordt opgestart; er kan ook geen ander updateproces worden gestart. (Het gaat hierbij onder andere om updates die worden veroorzaakt door het aanroepen van de methode checkNow() of door de periodieke controle.)
Installatie via een willekeurig AIR-bestand U kunt de methode installFromAIRFile() aanroepen om de updateversie te installeren via een AIR-bestand op de computer van de gebruiker. appUpdater.installFromAIRFile();
Door deze methode installeert de updater een updateversie van de toepassing vanuit het AIR-bestand. De methode installFromAIRFile() kan de volgende gebeurtenissen verzenden:
•
StatusFileUpdateEvent.FILE_UPDATE_STATUS—Wordt verzonden nadat de ApplicationUpdater het bestand
heeft gevalideerd dat is verzonden via de methode installFromAIRFile(). Deze gebeurtenis heeft de volgende eigenschappen:
•
available—Wordt ingesteld op true als er een andere versie dan die van de huidige toepassing beschikbaar is; als de versie hetzelfde is, wordt deze waarde ingesteld op false.
•
version —De tekenreeks die de nieuwe beschikbare versie vertegenwoordigt.
•
path—Vertegenwoordigt het oorspronkelijke pad van het updatebestand.
U kunt deze gebeurtenis annuleren als de eigenschap available van het object StatusFileUpdateEvent is ingesteld op true. Als u deze gebeurtenis annuleert, wordt de updater niet verder uitgevoerd. Roep de methode installUpdate() aan om de geannuleerde update verder uit te voeren.
•
StatusFileUpdateErrorEvent.FILE_UPDATE_ERROR—Er is een fout opgetreden en de updater kon de AIR-
toepassing niet installeren.
Het updateproces annuleren U kunt de methode cancelUpdate() gebruiken om het updateproces te annuleren: appUpdater.cancelUpdate();
Met deze methode worden alle downloads die in behandeling zijn, geannuleerd. Verder worden alle onvolledig gedownloade bestanden verwijderd en wordt de periodieke controle op updates opnieuw opgestart.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 350 AIR-toepassingen updaten
Deze methode doet niets als het updater-object bezig is met initialiseren.
De interface ApplicationUpdaterUI lokaliseren De klasse ApplicationUpdaterUI biedt een standaardgebruikersinterface voor het updateproces. Deze interface is voorzien van dialoogvensters waarmee de gebruiker het proces kan starten, annuleren en andere handelingen kan uitvoeren. Via het element description van het update-descriptorbestand kunt u de beschrijving van de toepassing definiëren in meerdere talen. Gebruik meerdere text-elementen die lang-attributen definiëren, zoals in het volgende voorbeeld: 1.1a1http://example.com/updates/sample_1.1a1.air <description> English descriptionFrench descriptionRomanian description
Het updateframework gebruikte beschrijving die het best past bij de lokalisatieketen van de eindgebruiker. Zie Het update-descriptorbestand definiëren en het AIR-bestand toevoegen aan uw webserver voor meer informatie. Flex-ontwikkelaars kunnen rechtstreeks een nieuwe taal toevoegen aan de bundel "ApplicationUpdaterDialogs". JavaScript-ontwikkelaars kunnen de methode addResources() van het updater-object aanroepen. Deze methode voegt dynamisch een nieuwe resourcebundel toe voor een taal. De resourcebundel definieert gelokaliseerde tekenreeksen voor een taal. Deze tekenreeksen worden gebruikt in de tekstvelden van de verschillende dialoogvensters. JavaScript-ontwikkelaars kunnen de eigenschappen localeChain van de klasse ApplicationUpdaterUI gebruiken om de keten van landinstellingen die wordt gebruikt door de gebruikersinterface, te definiëren. In het algemeen maken alleen JavaScript (HTML)-ontwikkelaars gebruik van deze eigenschap. Flex-ontwikkelaars kunnen de ResourceManager gebruiken om de keten van landinstellingen te beheren. De volgende JavaScript-code definieert bijvoorbeeld resourcebundels voor Roemeens en Hongaars: appUpdater.addResources("ro_RO", {titleCheck: "Titlu", msgCheck: "Mesaj", btnCheck: "Buton"}); appUpdater.addResources("hu", {titleCheck: "Cím", msgCheck: "Üzenet"}); var languages = ["ro", "hu"]; languages = languages.concat(air.Capabilities.languages); var sortedLanguages = air.Localizer.sortLanguagesByPreference(languages, air.Capabilities.language, "en-US"); sortedLanguages.push("en-US"); appUpdater.localeChain = sortedLanguages;
Zie voor meer informatie de beschrijving van de methode addResources() van de klasse ApplicationUpdaterUI in de taalreferentie.
Inleiding tot lokalisatie Lokalisatie is het proces waarbij assets worden toegevoegd voor de ondersteuning van meerdere landinstellingen. Een landinstelling is de combinatie van een taal en een landcode. Zo verwijst en_US bijvoorbeeld naar de Engelse taal zoals die wordt gesproken in de Verenigde Staten, en fr_FR naar de Franse taal zoals die wordt gesproken in Frankrijk. Als u een toepassing wilt lokaliseren voor deze landinstellingen, moet u beschikken over twee sets assets: een voor de landinstelling en_US en een voor de landinstelling fr_FR. Verschillende landinstellingen kunnen gebruikmaken van dezelfde taal. en_US en en_GB (Groot-Brittannië) zijn bijvoorbeeld verschillende landinstellingen. In dit geval maken beide landinstellingen gebruik van de Engelse taal, maar de landcode geeft aan dat het verschillende landinstellingen betreft die daarom mogelijk gebruikmaken van verschillende assets. Bij een toepassing voor de landinstelling en_US kan het woord "kleur" bijvoorbeeld worden gespeld als "color", terwijl voor de landinstelling en_GB dit "colour" is. Ook worden valuta-eenheden aangegeven in dollars of ponden, afhankelijk van de landinstelling, en kan de notatie van datums en tijden verschillen. U kunt ook een set assets voor een taal opgeven zonder een taalcode te specificeren. U kunt bijvoorbeeld en-assets opgeven voor de Engelse taal en aanvullende assets voor de landinstelling en_US, die specifiek zijn voor Amerikaans Engels. De AIR SDK biedt een HTML Localization Framework (dit bevindt zich in het bestand AIRLocalizer.js). Dit framework bevat API's die helpen bij het werken met meerdere landinstellingen. Zie “HTML-inhoud lokaliseren” op pagina 353 voor meer informatie. Lokalisatie is meer dan het vertalen van de tekenreeksen die worden gebruikt in uw toepassing. Elk willekeurig type asset, zoals geluidsbestanden, beelden en video's, kan hierbij worden betrokken.
De toepassingsnaam en -beschrijving lokaliseren in het installatieprogramma van de toepassing U kunt meerdere talen opgeven voor de elementen name en description in het descriptorbestand van de toepassing. Hieronder wordt bijvoorbeeld de toepassingsnaam in drie talen opgegeven (Engels, Frans en Duits): Sample 1.0Échantillon 1.0Stichprobe 1.0
Het attribuut xml:lang voor elk tekstelement geeft een taalcode aan, zoals gedefinieerd in RFC4646 (http://www.ietf.org/rfc/rfc4646.txt).
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 352 AIR-toepassingen lokaliseren
Het element name definieert de toepassingsnaam die wordt weergegeven in het installatieprogramma van de AIRtoepassing. Het installatieprogramma van de AIR-toepassing maakt gebruik van de gelokaliseerde waarde die het best overeenkomt met de gebruikersinterfacetalen die zijn gedefinieerd in de instellingen van het besturingssysteem. Op dezelfde manier kunt u meerdere taalversies opgeven voor het element description in het descriptorbestand van de toepassing. Dit element definieert beschrijvende tekst die wordt weergegeven in het installatieprogramma van de AIR-toepassing. Deze instellingen zijn alleen van toepassing op de talen die beschikbaar zijn in het installatieprogramma van de AIRtoepassing. Ze definiëren niet de landinstellingen die beschikbaar zijn voor de actieve geïnstalleerde toepassing. AIRtoepassingen kunnen gebruikersinterfaces bieden die meerdere talen ondersteunen, inclusief en als aanvulling op de talen die beschikbaar zijn voor het installatieprogramma van de AIR-toepassing. Zie “Eigenschappen definiëren in het descriptorbestand van de toepassing” op pagina 46 voor meer informatie.
Een landinstelling kiezen Om te bepalen van welke landinstelling de toepassing gebruikmaakt, kunt u een van de volgende methoden gebruiken:
• Melding van de gebruiker - U kunt de toepassing starten met een standaard landinstelling en dan de gebruiker vragen de gewenste landinstelling te kiezen.
•
Capabilities.languages - De eigenschap Capabilities.languages geeft een array weer met de
voorkeurstalen die zijn ingesteld via het besturingssysteem van de gebruiker. Deze strings bevatten taaltags (en script- en regiogegevens, indien van toepassing) zoals gedefinieerd in RFC4646 (http://www.ietf.org/rfc/rfc4646.txt). Bij deze tekenreeksen worden koppeltekens gebruikt als scheidingsteken (bijvoorbeeld "en-US" of "ja-JP"). Het eerste item in de geretourneerde array heeft dezelfde primaire taal-id als de eigenschap language. Als languages[0] bijvoorbeeld wordt ingesteld op "en-US", wordt de eigenschap language ingesteld op "en". Als de eigenschap language echter wordt ingesteld op "xu" (hiermee wordt een onbekende taal opgegeven), is het eerste element in de array languages anders.
•
Capabilities.language - De eigenschap Capabilities.language geeft de taalcode voor de
gebruikersinterface van het besturingssysteem op. Deze eigenschap is echter beperkt tot 20 bekende talen. Op Engelse systemen retourneert deze eigenschap alleen de taalcode, niet de landcode. Om deze redenen is het beter om het eerste element van de array Capabilities.languages te gebruiken.
Flash-inhoud lokaliseren Flash CS3 en Flash CS4 bevatten een klasse Locale in de ActionScript 3.0-componenten. Met de klasse Locale kunt u bepalen hoe een SWF-bestand meertalige tekst weergeeft. Via het Flash-deelvenster Tekenreeksen kunt u in dynamische tekstvelden tekenreeks-id's gebruiken in plaats van letterlijke tekenreeksen. Hiermee kunt u een SWFbestand maken dat tekst weergeeft die uit een taalspecifiek XML-bestand is geladen. Meer informatie over het gebruik van de klasse Locale vindt u in de Flash ActionScript 3.0 Language and Components Reference.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 353 AIR-toepassingen lokaliseren
HTML-inhoud lokaliseren De AIR 1.1 SDK bevat een HTML-lokalisatieframework. Dit framework wordt gedefinieerd in het JavaScript-bestand AIRLocalizer.js. De map frameworks van de AIR SDK bevat het bestand AIRLocalizer.js. Dit bestand bevat de klasse air.Localizer, die functies bevat die helpen bij het maken van toepassingen die meerdere gelokaliseerde versies ondersteunen.
De AIR HTML-lokalisatieframeworkcode laden Als u het lokalisatieframework wilt gebruiken, kopieert u het bestand AIRLocalizer.js naar uw project. Neem het vervolgens met behulp van een scripttag op in het HTML-hoofdbestand van de toepassing. <script src="AIRLocalizer.js" type="text/javascript" charset="utf-8">
JavaScript kan dan in het vervolg het air.Localizer.localizer-object oproepen: <script> var localizer = air.Localizer.localizer;
Het air.Localizer.localizer-object is een singletonobject waarin methoden en eigenschappen worden gedefinieerd voor het gebruik en het beheer van gelokaliseerde resources. De klasse Localizer bevat de volgende methoden: Methode
Beschrijving
getFile()
Haalt de tekst van een opgegeven resourcebundel op voor een opgegeven landinstelling. Zie “Resources ophalen voor een specifieke landinstelling” op pagina 359.
getLocaleChain()
Retourneert de talen in de keten van landinstellingen. Zie “De keten van landinstellingen definiëren” op pagina 358.
getResourceBundle()
Retourneert de bundelsleutels en de corresponderende waarden als een object. Zie “Resources ophalen voor een specifieke landinstelling” op pagina 359.
getString()
Haalt de tekenreeks op die is gedefinieerd voor een resource. Zie “Resources ophalen voor een specifieke landinstelling” op pagina 359.
setBundlesDirectory( )
Stelt de locatie van de bundelmap in. Zie “AIR HTML Localizer-instellingen aanpassen” op pagina 357.
setLocalAttributePre fix()
Stelt het voorvoegsel in dat wordt gebruikt door localizer-kenmerken die worden gebruikt in HTML DOMelementen. Zie “AIR HTML Localizer-instellingen aanpassen” op pagina 357.
setLocaleChain()
Stelt de volgorde in van de talen in de keten van landinstellingen. Zie “De keten van landinstellingen definiëren” op pagina 358.
sortLanguagesByPrefe rence()
Sorteert de landinstellingen in de keten op basis van de volgorde van de landinstellingen in het besturingssysteem. Zie “De keten van landinstellingen definiëren” op pagina 358.
update()
Werkt het HTML DOM (of een DOM-element) bij met gelokaliseerde tekenreeksen uit de huidige keten van landinstellingen. Zie “Landinstellingen beheren” op pagina 355 voor meer informatie over ketens van landinstellingen. Meer informatie over de methode update() vindt u in “DOM-elementen bijwerken voor het gebruik van de huidige landinstelling” op pagina 356.
De klasse Localizer bevat de volgende statische eigenschappen:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 354 AIR-toepassingen lokaliseren
Eigenschap
Beschrijving
localizer
Retourneert een verwijzing naar het Localizer-singletonobject voor de toepassing.
ultimateFallbackLocale
De landinstelling die moet worden gebruikt wanneer de toepassing geen gebruikersvoorkeur ondersteunt. Zie “De keten van landinstellingen definiëren” op pagina 358.
Resourcebundels definiëren Het HTML-lokalisatieframework leest gelokaliseerde versies van tekenreeksen uit lokalisatiebestanden. Een lokalisatiebestand is een verzameling op sleutels gebaseerde waarden die serieel worden opgeslagen in een tekstbestand. Een lokalisatiebestand wordt ook wel een bundel genoemd. Maak in de toepassingsprojectmap een submap met de naam locale. (U kunt ook een andere naam gebruiken, zie “AIR HTML Localizer-instellingen aanpassen” op pagina 357.) Deze map zal de lokalisatiebestanden bevatten. Deze map wordt de bundelmap genoemd. Voor iedere landinstelling die uw toepassing ondersteunt, maakt u een submap van de bundelmap. Geef iedere submap een naam die overeenkomt met de landinstellingscode. De map voor Frankrijk noemt u bijvoorbeeld “fr” en de map voor Engeland “en”. U kunt een onderstrepingsteken (_) gebruiken om een landinstelling te definiëren die een taal- en een landcode heeft. De map voor Amerikaans Engels noemt u bijvoorbeeld “en_us”. (U kunt ook een koppelteken gebruiken in plaats van een onderstrepingsteken, bijvoorbeeld “en-us”. Beide worden ondersteund door het HTML-lokalisatieframework.) U kunt elk willekeurig aantal resourcebestanden toevoegen aan een submap locale. In het algemeen maakt u een lokalisatiebestand voor iedere taal (en zet u dat bestand in de map voor die taal). Het HTML-lokalisatieframework biedt de methode getFile(), waarmee u de inhoud van een bestand kunt lezen (zie “Resources ophalen voor een specifieke landinstelling” op pagina 359). Bestanden met de extensie .properties staan bekend als lokalisatie-eigenschappenbestanden. U kunt deze gebruiken om sleutelwaardeparen voor een landinstelling te definiëren. In een eigenschappenbestand wordt op iedere regel één tekenreekswaarde gedefinieerd. Het volgende definieert bijvoorbeeld de tekenreekswaarde "Hello in English." voor de sleute greeting: greeting=Hello in English.
Een eigenschappenbestand met de volgende tekst definieert zes sleutelwaardeparen: title=Sample Application greeting=Hello in English. exitMessage=Thank you for using the application. color1=Red color2=Green color3=Blue
Dit voorbeeld toont een Engelse versie van het eigenschappenbestand, die moet worden opgeslagen in de map en. Een Franse versie van dit eigenschappenbestand wordt opgeslagen in de map fr: title=Application Example greeting=Bonjour en français. exitMessage=Merci d'avoir utilisé cette application. color1=Rouge color2=Vert color3=Bleu
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 355 AIR-toepassingen lokaliseren
U kunt meerdere resourcebestanden definiëren voor verschillende soorten informatie. Zo zou het bestand legal.properties juridische standaardteksten met bijvoorbeeld copyrightgegevens kunnen bevatten. U kunt die resource desgewenst in meerdere toepassingen gebruiken. Ook kunt u eventueel afzonderlijke bestanden definiëren die gelokaliseerde inhoud definiëren voor verschillende onderdelen van de gebruikersinterface. Gebruik UTF-8-codering voor deze bestanden voor de ondersteuning van meerdere talen.
Landinstellingen beheren Wanneer uw toepassing het bestand AIRLocalizer.js laadt, onderzoekt het bestand de landinstellingen die in de toepassing zijn gedefinieerd. Deze landinstellingen corresponderen met de submappen van de bundelmap (zie “Resourcebundels definiëren” op pagina 354). Dit is de keten van landinstellingen. Het bestand AIRLocalizer.js sorteert automatisch de keten van landinstellingen op basis van de voorkeursvolgorde die is gedefinieerd in het besturingssysteem. (De eigenschap Capabilities.languages geeft een lijst weer van de gebruikersinterfacetalen van het besturingssysteem, op volgorde van voorkeur.) Als dus een toepassing resources definieert voor de landinstellingen "en", "en_US" en "en_UK", sorteert het AIR HTML Localizer-framework de keten van landinstellingen op de correcte manier. Wanneer een toepassing wordt gestart op een systeem waarop "en" wordt gerapporteerd als de primaire landcode, wordt de keten van landinstellingen gesorteerd als ["en", "en_US", "en_UK"]. In dat geval zoekt de toepassing eerst naar resources in de bundel "en", en vervolgens in de bundel "en_US". Als het systeem echter "en-US" rapporteert als de primaire landinstelling, wordt bij de sortering gebruikgemaakt van ["en_US", "en", en_UK"]. In dat geval zoekt de toepassing eerst naar resources in de bundel "en_US", en vervolgens in de bundel "en". Standaard definieert de toepassing de eerste landinstelling in de keten als de standaard landinstelling die moet worden gebruikt. U kunt de gebruiker vragen een landinstelling te selecteren wanneer deze de toepassing voor het eerst uitvoert. Vervolgens kunt u ervoor kiezen de selectie op te slaan in een voorkeurenbestand en die landinstelling te gebruiken wanneer de toepassing in het vervolg wordt opgestart. Uw toepassing kan resourcetekenreeksen gebruiken in een willekeurige landinstelling van de keten. Als een bepaalde landinstelling geen resourcetekenreeks definieert, gebruikt de toepassing de volgende overeenkomende resourcetekenreeks voor andere landinstellingen die is gedefinieerd in de keten. U kunt de keten van landinstellingen aanpassen door de methode setLocaleChain() van het Localizer-object op te roepen. Zie “De keten van landinstellingen definiëren” op pagina 358.
DOM-elementen bijwerken met gelokaliseerde inhoud Een element in de toepassing kan verwijzen naar een sleutelwaarde in een lokalisatie-eigenschappenbestand. Zo geeft het element title in het volgende voorbeeld het kenmerk local_innerHTML op. Het lokalisatieframework gebruikt dit kenmerk om een gelokaliseerde waarde op te zoeken. Standaard zoekt het framework naar kenmerknamen die beginnen met "local_". Het framework werkt de kenmerken bij die een naam hebben die overeenkomt met de tekst na "local_". In dit geval stelt het framework het kenmerk innerHTML van het element title in. Het kenmerk innerHTML gebruikt de waarde die is gedefinieerd voor de sleutel mainWindowTitle in het standaard eigenschappenbestand (default.properties):
Als de huidige landinstelling geen overeenkomende waarde definieert, doorzoekt het Localizer-framework de rest van de keten van landinstellingen. De volgende landinstelling in de keten waarvoor een waarde is gedefinieerd, wordt dan gebruikt.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 356 AIR-toepassingen lokaliseren
In het volgende voorbeeld gebruikt de tekst (kenmerk innerHTML) van het element p de waarde van de sleutel greeting die is gedefinieerd in het standaard eigenschappenbestand:
In het volgende voorbeeld gebruikt het kenmerk value (en weergegeven tekst) van het element input de waarde van de sleutel btnBlue die is gedefinieerd in het standaard eigenschappenbestand:
Om het HTML DOM zodanig bij te werken dat de tekenreeksen worden gebruikt die zijn gedefinieerd in de huidige keten van landinstellingen, roept u de methode update() van het Localizer-object op. Het oproepen van de methode update() zorgt ervoor dat het Localizer-object het DOM parseert en manipulaties toepast waar het lokalisatiekenmerken ("local_...") aantreft: air.Localizer.localizer.update();
U kunt waarden definiëren voor zowel een kenmerk (zoals "innerHTML") als het corresponderende lokalisatiekenmerk (zoals "local_innerHTML"). In dat geval overschrijft het Localizer-framework alleen de waarde van het kenmerk als er een corresponderende waarde wordt aangetroffen in de lokalisatieketen. Het volgende element definieert bijvoorbeeld zowel kenmerken van het type value als van het type local_value:
U kunt ook alleen een specifiek DOM-element bijwerken. Zie de volgende sectie, “DOM-elementen bijwerken voor het gebruik van de huidige landinstelling” op pagina 356. Standaard gebruikt de AIR HTML Localizer "local_" als voorvoegsel voor kenmerken die lokalisatie-instellingen voor een element definiëren. Standaard definieert bijvoorbeeld het kenmerk local_innerHTML de bundel- en resourcenaam die worden gebruikt voor de waarde innerHTML van een element. Verder definieert het kenmerk local_value standaard de bundel- en resourcenaam die worden gebruikt voor het kenmerk value van een element. U kunt de Localizer zodanig configureren dat een ander kenmerkvoorvoegsel wordt gebruikt dan "local_". Zie “AIR HTML Localizer-instellingen aanpassen” op pagina 357.
DOM-elementen bijwerken voor het gebruik van de huidige landinstelling Wanneer het Localizer-object het HTML DOM bijwerkt, maken gemarkeerde elementen gebruik van kenmerkwaarden op basis van tekenreeksen die zijn gedefinieerd in de huidige keten van landinstellingen. Als de HTML Localizer het HTML DOM moet bijwerken, roept u de methode update() van het Localizer-object op: air.Localizer.localizer.update();
Als u alleen een specifiek DOM-element wilt bijwerken, geeft u dat element als parameter door aan de methode update(). De methode update() heeft maar één parameter, parentNode, die optioneel is. Wanneer de parameter parentNode wordt opgegeven, definieert deze het DOM-element dat moet worden gelokaliseerd. Als de methode update() wordt opgeroepen en de parameter parentNode wordt opgegeven, worden gelokaliseerde waarden ingesteld voor alle onderliggende elementen die lokalisatiekenmerken opgeven. Kijk bijvoorbeeld naar het volgende div-element:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 357 AIR-toepassingen lokaliseren
Als u dit element wilt bijwerken zodat gelokaliseerde tekenreeksen worden gebruikt, gebruikt u de volgende JavaScript-code: var divElement = window.document.getElementById("colorsDiv"); air.Localizer.localizer.update(divElement);
Als een sleutelwaarde niet wordt gevonden in de keten van landinstellingen, stelt het Localizer-framework de kenmerkwaarde in op de waarde van het kenmerk "local_". Stel dat in het vorige voorbeeld het Localizer-framework in geen enkel standaard eigenschappenbestand in de keten van tekenreeksen een waarde kan vinden voor de sleutel lblColors. In dat geval wordt "default.lblColors" gebruikt als waarde voor innerHTML. Het gebruik van deze waarde geeft (voor de ontwikkelaar) aan dat er resources ontbreken. De methode update() verzendt de gebeurtenis resourceNotFound wanneer een resource niet kan worden gevonden in de keten van landinstellingen. De constante air.Localizer.RESOURCE_NOT_FOUND definieert de tekenreeks "resourceNotFound". De gebeurtenis heeft drie eigenschappen: bundleName, resourceName en locale. De eigenschap bundleName is de naam van de bundel waarin de resource niet is gevonden. De eigenschap resourceName is de resource die niet is gevonden. De eigenschap locale is de naam van de landinstelling waarin de resource niet is gevonden. De methode update() verzendt de gebeurtenis bundleNotFound wanneer de opgegeven bundel niet kan worden gevonden. De constante air.Localizer.BUNDLE_NOT_FOUND definieert de tekenreeks "bundleNotFound". De gebeurtenis heeft twee eigenschappen: bundleName en locale. De eigenschap bundleName is de naam van de bundel waarin de resource niet is gevonden. De eigenschap locale is de naam van de landinstelling waarin de resource niet is gevonden. De methode update() werkt asynchroon (en verzendt de gebeurtenissen resourceNotFound en bundleNotFound asynchroon). Met de volgende code stelt u gebeurtenislisteners in voor de gebeurtenissen resourceNotFound en bundleNotFound: air.Localizer.localizer.addEventListener(air.Localizer.RESOURCE_NOT_FOUND, rnfHandler); air.Localizer.localizer.addEventListener(air.Localizer.BUNDLE_NOT_FOUND, rnfHandler); air.Localizer.localizer.update(); function rnfHandler(event) { alert(event.bundleName + ": " + event.resourceName + ":." + event.locale); } function bnfHandler(event) { alert(event.bundleName + ":." + event.locale); }
AIR HTML Localizer-instellingen aanpassen Met de methode setBundlesDirectory() van het Localizer-object kunt u het pad van de bundelmap aanpassen. Met de methode setLocalAttributePrefix() van het Localizer-object kunt u het pad van de bundelmap aanpassen, evenals de waarde van het kenmerk dat wordt gebruikt door de Localizer. Het standaard bundelpad wordt gedefinieerd als de submap met landinstellingen van de toepassingsmap. U kunt een andere map opgeven door de methode setBundlesDirectory() van het Localizer-object op te roepen. Deze methode maakt gebruik van één parameter, path. Dit is het pad naar de gewenste bundelmap. Het is een tekenreeks. De parameter path kan een van de volgende waarden hebben:
• Een tekenreeks (String) die een pad op basis van de toepassingsmap definieert, bijvoorbeeld "locales" • Een tekenreeks (String) die een geldige URL definieert die gebruikmaakt van de URL-schema's app, app-storage of file, zoals "app://languages" (maak niet gebruik van het URL-schemahttp)
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 358 AIR-toepassingen lokaliseren
• Een File-object Zie “Paden van File-objecten” op pagina 111 voor meer informatie over URL's en mappaden. Met de volgende code stelt u bijvoorbeeld de bundelmap in op de submap languages van de opslagmap van de toepassing (en niet de toepassingsmap): air.Localizer.localizer.setBundlesDirectory("languages");
Geef een geldig pad op voor de parameter path. Bij een ongeldig pad wordt de uitzondering BundlePathNotFoundError gegenereerd. Deze fout heeft "BundlePathNotFoundError" voor de eigenschap name. De eigenschap message geeft het ongeldige pad aan. Standaard gebruikt de AIR HTML Localizer "local_" als voorvoegsel voor kenmerken die lokalisatie-instellingen voor een element definiëren. Het kenmerk local_innerHTML definieert bijvoorbeeld de bundel- en resourcenaam die worden gebruikt voor de waarde innerHTML van het volgende input-element:
Met de methode setLocalAttributePrefix() van het Localizer-object kunt u een ander kenmerkvoorvoegsel gebruiken dan "local_". Deze statische methode maakt gebruik van één parameter, die bestaat uit de tekenreeks die u wilt gebruiken als kenmerkvoorvoegsel. Met de volgende code stelt u het Localizer-framework zo in dat "loc_" wordt gebruikt als kenmerkvoorvoegsel: air.Localizer.localizer.setLocalAttributePrefix("loc_");
U kunt het kenmerkvoorvoegsel aanpassen dat door het Localizer-framework wordt gebruikt. U kunt het voorvoegsel bijvoorbeeld aanpassen als de standaardwaarde ("local_") een conflict veroorzaakt met de naam van een ander kenmerk dat door uw code wordt gebruikt. Gebruik bij het oproepen van deze methode alleen geldige tekens voor HTML-kenmerken. (De waarde mag bijvoorbeeld geen spatie bevatten.) Zie “DOM-elementen bijwerken met gelokaliseerde inhoud” op pagina 355 voor meer informatie over het gebruik van lokalisatiekenmerken in HTML-elementen. De instellingen voor bundelmap en kenmerkvoorvoegsel blijven niet bewaard als een nieuwe sessie van de toepassing wordt opgestart. Als u een aangepaste instelling voor bundelmap of kenmerkvoorvoegsel gebruikt, moet u deze opnieuw instellen iedere keer dat de toepassing opnieuw wordt opgestart.
De keten van landinstellingen definiëren Wanneer u de AIRLocalizer.js-code laadt, wordt standaard de standaardketen voor landinstellingen ingesteld. Deze keten van landinstellingen wordt gedefinieerd door de landinstellingen die beschikbaar zijn in de bundelmap en de taalinstellingen van het besturingssysteem. (Zie “Landinstellingen beheren” op pagina 355 voor meer informatie.) U kunt de keten van landinstellingen wijzigen door de statische methode setLocaleChain() van het Localizer-object op te roepen. U kunt deze methode bijvoorbeeld oproepen als de gebruiker een voorkeur voor een bepaalde taal opgeeft. De methode setLocaleChain() maakt gebruik van één parameter, chain, die bestaat uit een array van landinstellingen, bijvoorbeeld ["fr_FR","fr","fr_CA"]. De volgorde van de landinstellingen in deze array bepaalt de volgorde waarin het framework (in daaropvolgende bewerkingen) zoekt naar resources. Als een resource niet wordt aangetroffen in de eerste landinstelling van de keten, wordt verder gezocht in de resources van de andere landinstellingen. Als het argument chain ontbreekt, geen array is of een lege array is, treedt er een fout op en wordt de uitzondering IllegalArgumentsError gegenereerd. De statische methode getLocaleChain() van het Localizer-object retourneert een array met alle landinstellingen in de huidige keten. De volgende code leest de huidige keten van landinstellingen en voegt boven aan de keten twee Franse landinstellingen toe:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 359 AIR-toepassingen lokaliseren
var currentChain = air.Localizer.localizer.getLocaleChain(); newLocales = ["fr_FR", "fr"]; air.Localizer.localizer.setLocaleChain(newLocales.concat(currentChain));
De methode setLocaleChain() verzendt de gebeurtenis "change" wanneer de keten van landinstellingen wordt bijgewerkt. De constante air.Localizer.LOCALE_CHANGE definieert de tekenreeks "change". Deze gebeurtenis heeft één eigenschap, localeChain, een array van landinstellingscodes in de nieuwe keten van landinstellingen. De volgende code stelt een gebeurtenislistener in voor deze gebeurtenis: var currentChain = air.Localizer.localizer.getLocaleChain(); newLocales = ["fr_FR", "fr"]; localizer.addEventListener(air.Localizer.LOCALE_CHANGE, changeHandler); air.Localizer.localizer.setLocaleChain(newLocales.concat(currentChain)); function changeHandler(event) { alert(event.localeChain); }
De statische eigenschap air.Localizer.ultimateFallbackLocale vertegenwoordigt de landinstelling die wordt gebruikt wanneer de toepassing geen gebruikersvoorkeuren ondersteunt. De standaardwaarde is "en". Met de volgende code kunt u een andere landinstelling instellen: air.Localizer.ultimateFallbackLocale = "fr";
Resources ophalen voor een specifieke landinstelling De methode getString() van het Localizer-object geeft als resultaat de tekenreeks die is gedefinieerd voor een resource in een specifieke landinstelling. U hoeft geen waarde voor locale op te geven wanneer u deze methode oproept. In dat geval doorzoekt de methode de gehele keten van landinstellingen. Als resultaat wordt de tekenreeks geretourneerd in de eerste landinstelling die de gegeven resourcenaam bevat. De methode heeft de volgende parameters: Parameter
Beschrijving
bundleName
De bundel die de resource bevat. Dit is de bestandsnaam van het eigenschappenbestand zonder de extensie .properties. (Als deze parameter bijvoorbeeld wordt ingesteld op "alerts", zoekt de Localizer-code in lokalisatiebestanden met de naam alerts.properties.)
resourceName
De resourcenaam.
templateArgs
Optioneel. Een array van tekenreeksen die de genummerde tags in de vervangende tekenreeks vervangen. Hier volgt bijvoorbeeld een oproep van de functie, waarbij de parameter templateArgs["Raúl", "4"] is en de bijbehorende resource de tekenreeks "Hello, {0}. You have {1} new messages.". In dit geval retourneert de functie "Hello, Raúl. You have 4 new messages.". Als u deze instelling wilt negeren, geeft u de waarde null door.
locale
Optioneel. De landinstellingscode (bijvoorbeeld "en", "en_us" of "fr") die moet worden gebruikt. Als er een landinstelling wordt opgegeven en geen corresponderende waarde wordt gevonden, blijft de methode niet doorgaan met zoeken naar waarden in andere landinstellingen in de keten. Als er geen landinstellingscode wordt opgegeven, retourneert de functie de tekenreeks in de eerste keten die een waarde biedt voor de gegeven resourcenaam.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 360 AIR-toepassingen lokaliseren
Het Localizer-framework kan gemarkeerde HTML DOM-kenmerken bijwerken. U kunt gelokaliseerde tekenreeksen echter ook op andere manieren gebruiken. U kunt een tekenreeks bijvoorbeeld gebruiken in dynamisch gegenereerde HTML, of als parameterwaarde in een functieoproep. De volgende code roept bijvoorbeeld de functie alert() op met de tekenreeks die is gedefinieerd in de resource error114 in het standaard eigenschappenbestand van de landinstelling fr_FR: alert(air.Localizer.localizer.getString("default", "error114", null, "fr_FR"));
De methode getString() verzendt de gebeurtenis resourceNotFound wanneer de resource niet kan worden gevonden in de opgegeven bundel. De constante air.Localizer.RESOURCE_NOT_FOUND definieert de tekenreeks "resourceNotFound". De gebeurtenis heeft drie eigenschappen: bundleName, resourceName en locale. De eigenschap bundleName is de naam van de bundel waarin de resource niet is gevonden. De eigenschap resourceName is de resource die niet is gevonden. De eigenschap locale is de naam van de landinstelling waarin de resource niet is gevonden. De methode getString() verzendt de gebeurtenis bundleNotFound wanneer de opgegeven bundel niet kan worden gevonden. De constante air.Localizer.BUNDLE_NOT_FOUND definieert de tekenreeks "bundleNotFound". De gebeurtenis heeft twee eigenschappen: bundleName en locale. De eigenschap bundleName is de naam van de bundel waarin de resource niet is gevonden. De eigenschap locale is de naam van de landinstelling waarin de resource niet is gevonden. De methode getString() werkt asynchroon (en verzendt de gebeurtenissen resourceNotFound en resourceNotFound asynchroon). Met de volgende code stelt u gebeurtenislisteners in voor de gebeurtenissen resourceNotFound en bundleNotFound: air.Localizerlocalizer.addEventListener(air.Localizer.RESOURCE_NOT_FOUND, rnfHandler); air.Localizerlocalizer.addEventListener(air.Localizer.BUNDLE_NOT_FOUND, bnfHandler); var str = air.Localizer.localizer.getString("default", "error114", null, "fr_FR"); function rnfHandler(event) { alert(event.bundleName + ": " + event.resourceName + ":." + event.locale); } function bnfHandler(event) { alert(event.bundleName + ":." + event.locale); }
De methode getResourceBundle() van het Localizer-object retourneert een specifieke bundel voor een bepaalde landinstelling. De geretourneerde waarde van de methode is een object waarvan de eigenschappen overeenstemmen met de sleutels in de bundel. (Als de toepassing de gespecificeerde bundel niet kan vinden, geeft deze methode de waarde null als resultaat.) De methode heeft twee parameters, locale en bundleName. Parameter
Beschrijving
locale
De landinstelling (bijvoorbeeld "fr").
bundleName
De bundelnaam.
De volgende code roept bijvoorbeeld de methode document.write() aan om de standaardbundel voor de landinstelling fr te laden. Vervolgens wordt de methode document.write() aangeroepen om de waarden van de sleutels str1 en str2 in die bundel te schrijven:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 361 AIR-toepassingen lokaliseren
var aboutWin = window.open(); var bundle = localizer.getResourceBundle("fr", "default"); aboutWin.document.write(bundle.str1); aboutWin.document.write(" "); aboutWin.document.write(bundle.str2); aboutWin.document.write(" ");
De methode getResourceBundle() verzendt de gebeurtenis bundleNotFound wanneer de opgegeven bundel niet kan worden gevonden. De constante air.Localizer.BUNDLE_NOT_FOUND definieert de tekenreeks "bundleNotFound". De gebeurtenis heeft twee eigenschappen: bundleName en locale. De eigenschap bundleName is de naam van de bundel waarin de resource niet is gevonden. De eigenschap locale is de naam van de landinstelling waarin de resource niet is gevonden. De methode getFile() van het Localizer-object retourneert de inhoud van een bundel, in de vorm van een tekenreeks, voor een bepaalde landinstelling. Het bundelbestand wordt gelezen als UTF-8-bestand. De methode omvat de volgende parameters: Parameter
Beschrijving
resourceFileName
De bestandsnaam van het resourcebestand (bijvoorbeeld "about.html").
templateArgs
Optioneel. Een array van tekenreeksen die de genummerde tags in de vervangende tekenreeks vervangen. Hier volgt bijvoorbeeld een oproep van de functie waarbij de parameter templateArgs["Raúl", "4"] is en waarbij het corresponderende resourcebestand twee regels bevat: Hello, {0}. You have {1} new messages.
In dit geval retourneert de functie een tekenreeks van twee regels: Hello, Raúl. You have 4 new messages. locale
De landinstellingscode die moet worden gebruikt, bijvoorbeeld "en_GB". Als er een landinstelling wordt opgegeven en geen corresponderend bestand wordt gevonden, blijft de methode niet doorgaan met zoeken in andere landinstellingen in de keten. Als er geen landinstellingscode wordt opgegeven, retourneert de functie de tekst in de eerste landinstelling in de keten waarbij een bestand hoort dat overeenkomt met resourceFileName.
De volgende code roept bijvoorbeeld de methode document.write() op met gebruikmaking van de inhoud van het bestand about.html van de landinstelling fr: var aboutWin = window.open(); var aboutHtml = localizer.getFile("about.html", null, "fr"); aboutWin.document.close(); aboutWin.document.write(aboutHtml);
De methode getFile() verzendt de gebeurtenisfileNotFound wanneer er geen resource kan worden gevonden in de keten van landinstellingen. De constante air.Localizer.FILE_NOT_FOUND definieert de tekenreeks "resourceNotFound". De methode getFile() werkt asynchroon (en verzendt de gebeurtenis fileNotFound asynchroon). De gebeurtenis heeft twee eigenschappen: fileName en locale. De eigenschap fileName is de naam van het bestand dat niet kan worden gevonden. De eigenschap locale is de naam van de landinstelling waarin de resource niet is gevonden. De volgende code stelt een gebeurtenislistener in voor deze gebeurtenis:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 362 AIR-toepassingen lokaliseren
Datums, tijden en valuta's lokaliseren De manier waarop toepassingen datums, tijden en valuta's presenteren, is heel erg afhankelijk van de landinstelling. In de Verenigde Staten wordt bijvoorbeeld voor de notatie van datums maand/dag/jaar gebruikt, terwijl de Europese standaard dag/maand/jaar is. U kunt code schrijven om datums, tijden en valuta's op te maken. De volgende code converteert bijvoorbeeld een Dateobject naar de notatie maand/dag/jaar of dag/maand/jaar. Als de variabele locale (die de landinstelling vertegenwoordigt) wordt ingesteld op "en_US", retourneert de functie de notatie maand/dag/jaar. Het voorbeeld converteert een Date-object bij alle andere landinstellingen naar de notatie dag/maand/jaar: function convertDate(date) { if (locale == "en_US") { return (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear(); } else { return date.getDate() + "/" + (date.getMonth() + 1) + "/" + date.getFullYear(); } }
363
Hoofdstuk 35: AIR-toepassingen maken met behulp van opdrachtregelprogramma's Met de opdrachtregelprogramma's van Adobe® AIR™ kunt u Adobe AIR-toepassingen testen en toepassingspakketten maken. U kunt deze programma's ook gebruiken in geautomatiseerde constructieprocessen. De opdrachtregelprogramma's van AIR zijn opgenomen in de SDK van AIR (http://www.adobe.com/go/learn_air_download_AIRSDK_nl).
ADL (AIR Debug Launcher) gebruiken Gebruik ADL (AIR Debug Launcher) om zowel SWF- als HTML-toepassingen uit te voeren tijdens het ontwikkelen. Met ADL kunt u een toepassing uitvoeren zonder deze eerst in een pakket te plaatsen en te installeren. ADL maakt standaard gebruik van een runtime die in de SDK is opgenomen, zodat u de runtime niet afzonderlijk hoeft te installeren om ADL te gebruiken. ADL drukt traceerinstructies en runtimefouten af naar de standaarduitvoer, maar ondersteunt geen onderbrekingspunten of andere foutopsporingsfuncties. Als u een SWF-toepassing wilt ontwikkelen, gebruikt u Flash Debugger (of Flash CS) om complexe fouten op te sporen. U kunt verbinding maken met Flash Debugger door het foutopsporingsprogramma te starten voordat u de toepassing uitvoert met ADL.
Een toepassing starten met ADL Gebruik de volgende syntaxis: adl [-runtime runtime-directory] [-pubid publisher-id] [-nodebug] application.xml [rootdirectory] [-- arguments]
-runtime runtime-directory Hiermee geeft u de map op die de runtime bevat die u wilt gebruiken. Als u deze niet opgeeft, wordt de runtimemap in dezelfde SDK als het ADL-programma gebruikt. Als u ADL uit de SDK-map verplaatst, moet u de runtimemap opgeven. In Windows en Linux geeft u de map op die de map van Adobe AIR bevat. In Mac OS X geeft u de map op die Adobe AIR.framework bevat. -pubid publisher-id Hiermee wijst u de opgegeven waarde toe als de uitgevers-id van de AIR-toepassing voor deze uitvoering. Als u een tijdelijke uitgevers-id opgeeft, kunt u functies van een AIR-toepassing testen, zoals de communicatie via een lokale verbinding, die de uitgevers-id gebruiken om een toepassing uniek te identificeren. De uiteindelijke uitgevers-id wordt bepaald door het digitale certificaat waarmee het AIR-installatiebestand wordt ondertekend. -nodebug Hiermee schakelt u ondersteuning voor foutopsporing uit. Als u deze optie gebruikt, kan het toepassingsproces geen verbinding maken met Flash Debugger en worden dialoogvensters voor niet-verwerkte uitzonderingen onderdrukt. (Traceerinstructies worden wel in het consolevenster weergegeven.) Als u foutopsporing uitschakelt, kan uw toepassing iets sneller werken en wordt de uitvoeringsmodus van een geïnstalleerde toepassing beter geëmuleerd. application.xml Het descriptorbestand van de toepassing. Zie “Eigenschappen van AIR-toepassingen instellen” op pagina 45.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 364 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
root-directory Hiermee geeft u de hoofdmap op van de toepassing die wordt uitgevoerd. Als u deze optie niet opgeeft, wordt de map gebruikt die het descriptorbestand van de toepassing bevat. -- arguments Alle tekenreeksen na "--" worden als opdrachtregelargumenten doorgegeven aan de toepassing. Opmerking: Wanneer u een AIR-toepassing start die al is gestart, wordt geen nieuwe instantie van die toepassing gestart. In plaats daarvan wordt de gebeurtenis invoke verzonden naar de gestarte instantie.
Traceerinstructies afdrukken Als u traceerinstructies wilt afdrukken op de console waarmee ADL wordt uitgevoerd, voegt u aan uw code traceerinstructies toe met de functie trace(): trace("debug message"); air.trace("debug message");
Voorbeelden van ADL Een toepassing uitvoeren in de huidige map: adl myApp-app.xml
Een toepassing uitvoeren in een submap van de huidige map: adl source/myApp-app.xml release
Een toepassing uitvoeren en twee opdrachtregelargumenten, "tik" en "tak", doorgeven: adl myApp-app.xml -- tick tock
Een toepassing uitvoeren met een bepaalde runtime: adl -runtime /AIRSDK/runtime myApp-app.xml
Een oplossing uitvoeren zonder ondersteuning van het foutopsporingsprogramma: adl myApp-app.xml -nodebug
Verbinding maken met FDB (Flash Debugger) Als u in een op SWF gebaseerde AIR-toepassing fouten wilt opsporen met Flash Debugger, start u een FDB-sessie en start u vervolgens een foutopsporingsversie van uw toepassing. Een AIR-toepassing die de foutopsporingsversie van een SWF-bestand bevat, maakt automatisch verbinding met een luisterende FDB-sessie. Opmerking: Een foutopsporingsversie van een AIR-toepassing is een versie waarin het hoofd-SWF-bestand is gecompileerd met de markering -debug. 1 Start FDB. U kunt het FDB-programma vinden in de map bin van de Flex SDK.
De FDB-prompt wordt weergegeven op de console: 2 Voer de opdracht run uit. run [Enter] 3 Start een foutopsporingsversie van uw toepassing in een andere opdracht- of shellconsole: adl myApp.xml
4 Stel de gewenste onderbrekingspunten in met de FDB-opdrachten. 5 Typ: continue [Enter]
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 365 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Als een AIR-toepassing op SWF gebaseerd is, bestuurt het foutopsporingsprogramma alleen de uitvoering van ActionScript-code. Als een AIR-toepassing op HTML gebaseerd is, bestuurt het foutopsporingsprogramma alleen de uitvoering van JavaScript-code. Als u ADL wilt uitvoeren zonder verbinding te maken met het foutopsporingsprogramma, neemt u de optie -nodebug op: adl myApp.xml -nodebug
Voor basisinformatie over FDB-opdrachten voert u de opdracht help uit: help [Enter]
Meer informatie over de FDB-opdrachten vindt u in Using the command-line debugger commands in de Flexdocumentatie.
Afsluit- en foutcodes van ADL In de volgende tabel worden de afsluitcodes beschreven die ADL afdrukt: Afsluitcod e
Beschrijving
0
Gestart. ADL wordt afgesloten nadat de AIR-toepassing is afgesloten.
1
Er is een al gestarte AIR-toepassing opgeroepen. ADL wordt onmiddellijk afgesloten.
2
Gebruiksfout. Er zijn onjuiste argumenten opgegeven voor ADL.
3
De runtime is niet gevonden.
4
De runtime kan niet worden gestart. Dit gebeurt vaak wanneer het versie- of patchnummer dat in de toepassing is opgegeven niet overeenkomt met het versie- of patchnummer van de runtime.
5
Er is een fout met onbekende oorzaak opgetreden.
6
Het descriptorbestand van de toepassing is niet gevonden.
7
De inhoud van de descriptor van de toepassing is niet geldig. Deze fout geeft vaak aan dat de XML-code niet juist is opgebouwd.
8
Het hoofdbestand met de toepassingsinhoud (opgegeven in het element van het descriptorbestand van de toepassing) is niet gevonden.
9
Het hoofdbestand met de toepassingsinhoud is geen geldig SWF- of HTML-bestand.
AIR-installatiebestanden in een pakket plaatsen met ADT (AIR Developer Tool) Met ADT (AIR Developer Tool) kunt u zowel voor uw op SWF als voor uw op HTML gebaseerde AIR-toepassingen een AIR-installatiebestand maken. (Als u een toepassing maakt met Adobe Flash CS3, kunt u het AIR-pakket ook bouwen met de opdracht AIR-bestand maken in het menu Opdrachten. Zie “Adobe AIR-update voor Flash CS3 Professional” op pagina 13 voor meer informatie. Voor informatie over het gebruik van Flash CS4 om AIRtoepassingen te maken, gaat u naar Publiceren in Adobe AIR in Flash gebruiken.) ADT is een Java-programma dat u kunt starten vanaf de opdrachtregel of vanuit een hulpprogramma zoals Ant. De SDK van AIR en die van Flex bevatten opdrachtregelscripts waarmee u het Java-programma kunt uitvoeren.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 366 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
AIR-installatiebestanden in een pakket plaatsen Elke AIR-toepassing moet minimaal een descriptorbestand van de toepassing en een SWF- of HTML-hoofdbestand bevatten. Alle andere geïnstalleerde assets van de toepassing moeten ook in het AIR-pakket zijn opgenomen. Alle AIR-installatiebestanden moeten zijn ondertekend met een digitaal certificaat. Het AIR-installatieprogramma gebruikt de handtekening om te verifiëren of uw toepassingsbestand niet is gewijzigd sinds u het hebt ondertekend. U kunt een certificaat voor ondertekening van programmacode van een certificeringsinstantie of een zelfondertekend certificaat gebruiken. Met een certificaat dat door een vertrouwde certificeringsinstantie is uitgegeven, hebben gebruikers van uw toepassing enige garantie dat u de uitgever bent. Een zelfondertekend certificaat kan niet worden gebruikt om uw identiteit als de ondertekenaar te verifiëren. Hierdoor neemt ook de garantie af dat het pakket niet is gewijzigd, omdat een geldig installatiebestand door een vervalst bestand kan zijn vervangen voordat het de gebruiker bereikt. U kunt een AIR-bestand in één stap in een pakket plaatsen en ondertekenen met de ADT-opdracht -package. U kunt ook een tussentijds, niet-ondertekend pakket maken met de opdracht -prepare en het tussentijdse pakket in een afzonderlijke stap ondertekenen met de opdracht -sign. Bij het ondertekenen van het installatiepakket neemt ADT automatisch contact op met een tijdstempelserver om de tijd te verifiëren. De tijdstempelinformatie wordt opgenomen in het AIR-bestand. Een AIR-bestand dat een geverifieerd tijdstempel bevat, kan op een willekeurig moment in de toekomst worden geïnstalleerd. Als ADT geen verbinding kan maken met de tijdstempelserver, wordt het maken van het pakket geannuleerd. U kunt de tijdstempeloptie uitschakelen, maar zonder tijdstempel kan een AIR-toepassing niet worden geïnstalleerd nadat het certificaat is verlopen waarmee het installatiebestand is ondertekend. Als u een pakket maakt om een bestaande AIR-toepassing bij te werken, moet het pakket worden ondertekend met hetzelfde certificaat als de oorspronkelijke toepassing of met een certificaat dat dezelfde identiteit heeft. Twee certificaten hebben dezelfde identiteit als ze dezelfde DN-naam (Distinguished Name) bezitten (alle informatievelden komen overeen) en dezelfde certificaatketen naar het basiscertificaat hebben. U kunt daarom een vernieuwd certificaat van een certificeringsinstantie gebruiken zolang u de identificatiegegevens niet wijzigt. Vanaf AIR 1.1 kunt u een toepassing voor het gebruik van een nieuw certificaat migreren met de opdracht -migrate. Voor het migreren van het certificaat moet het AIR-bestand worden ondertekend met het nieuwe en het oude certificaat. U kunt een certificaat migreren om een zelfondertekend certificaat te wijzigen in een commercieel certificaat voor ondertekening van programmacode of om een zelfondertekend of commercieel certificaat te wijzigen in een ander certificaat van hetzelfde type. Wanneer u een certificaat migreert, hoeven bestaande gebruikers hun bestaande toepassing niet te verwijderen voordat ze uw nieuwe versie installeren. Migratiehandtekeningen bevatten standaard een tijdstempel. Opmerking: De identiteit en het standaard installatiepad van een AIR-toepassing worden bepaald door de instellingen in het descriptorbestand van de toepassing. Zie “De structuur van het descriptorbestand van de toepassing” op pagina 45. Een AIR-bestand in één stap in een pakket plaatsen en ondertekenen ❖ Gebruik de opdracht -package met de volgende syntaxis (op één opdrachtregel): adt -package SIGNING_OPTIONS air_file app_xml [file_or_dir | -C dir file_or_dir | -e file dir ...] ...
SIGNING_OPTIONS Met de ondertekeningsopties bepaalt u welk sleutelarchief de persoonlijke sleutel en het certificaat bevat waarmee het AIR-bestand wordt ondertekend. Als u een AIR-toepassing wilt ondertekenen met een zelfondertekend certificaat dat door ADT is gegenereerd, gebruikt u de volgende opties:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 367 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
-storetype pkcs12 -keystore certificate.p12
In dit voorbeeld is certificate.p12 de naam van het sleutelarchiefbestand. (ADT vraagt om een wachtwoord omdat dit niet wordt opgegeven op de opdrachtregel.) De ondertekeningsopties worden volledig beschreven in “Ondertekeningsopties voor de opdrachtregel van ADT” op pagina 372. air_file De naam van het AIR-bestand dat wordt gemaakt. app_xml Het pad naar het descriptorbestand van de toepassing. Dit kan een relatief pad ten opzichte van de huidige map of een absoluut pad zijn. (De naam van het descriptorbestand van de toepassing wordt in het AIR-bestand gewijzigd in “application.xml”.) file_or_dir De bestanden en mappen die in het AIR-pakket worden opgenomen. U kunt een willekeurig aantal bestanden en mappen opgeven, gescheiden door spaties. Als u een map opgeeft, worden alle bestanden en mappen in die map, behalve verborgen bestanden, aan het pakket toegevoegd. (Als het descriptorbestand van de toepassing wordt opgegeven, rechtstreeks of door het omzetten van jokertekens of het uitbreiden van mappen, wordt het genegeerd en niet opnieuw aan het pakket toegevoegd.) De opgegeven bestanden en mappen moeten zich in de huidige map of een submap van de huidige map bevinden. Gebruik de optie -C om een andere map dan de huidige te selecteren. Belangrijk: In de argumenten file_or_dir die na de optie –C volgen, kunnen geen jokertekens worden gebruikt. (Opdrachtshells zetten de jokertekens om voordat de argumenten worden doorgegeven aan ADT, waardoor ADT de bestanden op onjuiste locaties zoekt.) U kunt echter wel een punt (".") gebruiken om de huidige map aan te geven. Bijvoorbeeld met "-C assets ." wordt alles in de map assets, inclusief alle submappen, gekopieerd naar het hoofdniveau van het toepassingspakket. -C dir Hiermee wijzigt u de werkmap in de waarde van dir voordat de volgende bestanden en mappen worden toegevoegd aan het toepassingspakket. De bestanden en mappen worden toegevoegd aan de hoofdmap van het toepassingspakket. U kunt de optie –C een willekeurig aantal keren gebruiken om bestanden op te nemen vanuit meerdere plaatsen in het bestandssysteem. Als u voor dir een relatief pad opgeeft, wordt het pad altijd gebaseerd op de oorspronkelijke werkmap.
Wanneer ADT de bestanden en mappen omzet die in het pakket aanwezig zijn, worden de relatieve paden tussen de huidige map en de doelbestanden opgeslagen. Deze paden worden naar de mapstructuur van de toepassing omgezet wanneer het pakket wordt geïnstalleerd. Als u -C release/bin lib/feature.swf opgeeft, wordt het bestand release/bin/lib/feature.swf daarom in de submap lib van de hoofdmap van de toepassing geplaatst. -e file dir Hiermee plaatst u het opgegeven bestand in de opgegeven pakketmap.
Opmerking: In het element van het descriptorbestand van de toepassing moet de uiteindelijke locatie zijn opgegeven van het hoofdbestand van de toepassing in de mapstructuur van het toepassingspakket. Voorbeelden van ADT Pakketspecifieke toepassingsbestanden in de huidige map: adt –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf components.swc
Alle bestanden en submappen in de huidige werkmap in een pakket plaatsen: adt –package -storetype pkcs12 -keystore ../cert.p12 myApp.air myApp.xml .
Opmerking: Het sleutelarchiefbestand bevat de persoonlijke sleutel waarmee uw toepassing wordt ondertekend. Neem het handtekeningcertificaat nooit op in het AIR-pakket! Als u jokertekens gebruikt in de ADT-opdracht, plaatst u het sleutelarchiefbestand op een andere locatie, zodat het niet wordt opgenomen in het pakket. In dit voorbeeld bevindt het sleutelarchiefbestand, cert.p12, zich in de bovenliggende map.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 368 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Alleen de hoofdbestanden en een submap met afbeeldingen in een pakket plaatsen: adt –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf images
Het bestand application.xml en het SWF-hoofdbestand dat in een werkmap (release/bin) staat in een pakket plaatsen: adt –package -storetype pkcs12 -keystore cert.p12 myApp.air release/bin/myApp.xml –C release/bin myApp.swf
Assets vanuit meerdere plaatsen in uw gebouwde bestandssysteem in een pakket plaatsen. In dit voorbeeld bevinden de assets van de toepassing zich in de volgende mappen voordat ze in een pakket worden geplaatst: /devRoot /myApp /release /bin myApp.xml myApp.swf /artwork /myApp /images image-1.png ... image-n.png /libraries /release /libs lib-1.swf ... lib-n.swf AIRAliases.js
De volgende ADT-opdracht uitvoeren vanuit de map /devRoot/myApp: adt –package -storetype pkcs12 -keystore cert.p12 myApp.air release/bin/myApp.xml –C release/bin myApp.swf –C ../artwork/myApp images –C ../libraries/release libs
Resultaten in de volgende pakketstructuur: /myAppRoot /META-INF /AIR application.xml hash myApp.swf mimetype /images image-1.png ... image-n.png /libs lib-1.swf ... lib-n.swf AIRAliases.js
ADT uitvoeren als een Java-programma (zonder het klassepad in te stellen):
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 369 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
ADT uitvoeren als een Java-programma (waarbij het pakket ADT.jar is opgenomen in het Java-klassepad): java com.adobe.air.ADT –package -storetype pkcs12 -keystore cert.p12 myApp.air myApp.xml myApp.swf
ADT-foutmeldingen In de onderstaande tabel worden de mogelijke fouten aangeven die kunnen worden gerapporteerd door het ADTprogramma en de mogelijke oorzaken daarvan: Fouten bij de validatie van toepassingsbeschrijvingen Foutcode
Beschrijving
Opmerkingen
100
Toepassingsbeschrijving kan niet worden geparseerd
Controleer of er fouten voorkomen in de XML-syntaxis van het toepassingsbeschrijvingsbestand, zoals tags zonder eindtag.
101
Naamruimte ontbreekt
Voeg de ontbrekende naamruimte toe.
102
Ongeldige naamruimte
Controleer de spelling van de naamruimte.
103
Onverwacht element of attribuut
Verwijder de desbetreffende elementen en attributen. Aangepaste waarden zijn niet toegestaan in het beschrijvingsbestand. Controleer de spelling van de namen van elementen en attributen. Controleer of elementen zijn geplaatst binnen de correcte bovenliggende elementen en of attributen worden gebruikt met de correcte elementen.
104
Ontbrekend element of attribuut
Voeg het vereiste element of attribuut toe.
105
Element of attribuut bevat een ongeldige waarde
Corrigeer de desbetreffende waarde.
106
Ongeldige combinatie van vensterattributen
Bepaalde vensterinstellingen zoals transparency = true en systemChrome = standard, kunnen niet gezamenlijk worden gebruikt. Wijzig een van de incompatibele instellingen.
107
Minimumgrootte van venster is groter dan maximumgrootte
Verander de instelling voor de minimumof maximumgrootte.
Raadpleeg “Eigenschappen van AIR-toepassingen instellen” op pagina 45 voor meer informatie over de naamruimtes, elementen en attributen en hun geldige waarden. Fouten bij toepassingspictogrammen
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 370 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Foutcode
Beschrijving
Opmerkingen
200
Kan pictogrambestand niet openen
Controleer of het bestand aanwezig is op het opgegeven pad. Gebruik een andere toepassing om er zeker van te zijn dat het bestand kan worden geopend.
201
Pictogram heeft het verkeerde formaat
Het formaat van het pictogram (in pixels) moet overeenkomen met de XML-tag. Kijk bijvoorbeeld naar het volgende toepassingsbeschrijvingselement: icon.png
De afbeelding in icon.png moet precies 32x32 pixels bevatten. 202
Pictogrambestand bevat een afbeeldingsindeling die niet wordt ondersteund
Alleen de PNG-indeling wordt ondersteund. Converteer afbeeldingen in andere indelingen voordat u de toepassing inpakt.
Fouten in toepassingsbestanden Foutcode
Beschrijving
Opmerkingen
300
Bestand ontbreekt of kan niet worden geopend
Een bestand dat wordt gespecificeerd op de opdrachtregel, kan niet worden gevonden of geopend.
301
Toepassingsbeschrijvingsbestand ontbreekt of kan niet worden geopend
Het toepassingsbeschrijvingsbestand kan niet worden gevonden op het gespecificeerde pad of kan niet worden geopend.
302
Hoofdinhoudsbestand ontbreekt uit pakket
Het SWF- of HTML-bestand waarnaar wordt verwezen in het element van het toepassingsbeschrijvingsbestand, moet worden toegevoegd aan het pakket door het op te nemen in de bestanden die worden opgesomd op de ADTopdrachtregel.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 371 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Foutcode
Beschrijving
Opmerkingen
303
Pictogrambestand ontbreekt uit pakket
De pictogrambestanden die worden opgegeven in de toepassingsbeschrijving, moeten worden toegevoegd aan het pakket door ze op te nemen in de bestanden die worden opgesomd op de ADT-opdrachtregel. Pictogrambestanden worden niet automatisch toegevoegd.
304
Initiële vensterinhoud is ongeldig
Het bestand waarnaar wordt verwezen in het element van de toepassingsbeschrijving, wordt niet herkend als geldig HTML- of SWF-bestand.
305
SWF-versie van initiële vensterinhoud is hoger dan naamruimteversie
De SWF-versie van het bestand waarnaar wordt verwezen in het element van de toepassingsbeschrijving, wordt niet ondersteund door de versie van AIR die wordt gespecificeerd in de descriptornaamruimte. Deze fout wordt bijvoorbeeld gegenereerd als u probeert een SWF10 (Flash Player 10)-bestand te verpakken als de initiële inhoud van een AIR 1.1toepassing.
Afsluitcodes voor andere fouten Afsluitcode
Beschrijving
Opmerkingen
2
Gebruiksfout
Controleer de opdrachtregelargumenten op fouten
5
Onbekende fout
Deze fout geeft een situatie aan die niet kan worden verklaard door normale foutcondities. Mogelijke basisoorzaken omvatten incompatibiliteit tussen ADT en de Java-runtimeomgeving, beschadigde ADT- of JRE-installaties of programmeerfouten in ADT.
6
Kan niet schrijven naar uitvoermap
Controleer of de gespecificeerde (of geïmpliceerde) uitvoermap toegankelijk is en of het station waarop deze map zich bevindt, voldoende schijfruimte heeft.
7
Kan certificaat niet openen
Controleer of het pad naar de sleutelopslag correct is gespecificeerd. Controleer of het certificaat in de sleutelopslag toegankelijk is. U kunt het hulpprogramma Java 1.6 Keytool gebruiken om problemen met de toegang tot certificaten op te lossen.
8
Ongeldig certificaat
Het certificaat is verkeerd samengesteld, gewijzigd, verlopen of ingetrokken.
9
Kan het AIR-bestand niet ondertekenen
Verifieer de ondertekeningsopties die worden doorgegeven aan ADT.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 372 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Afsluitcode
Beschrijving
Opmerkingen
10
Kan geen tijdstempel maken
ADT kan geen verbinding met de tijdstempelserver tot stand brengen. Als u via een proxyserver verbinding maakt met internet, moet u mogelijk de JREproxyinstellingen configureren.
11
Fout bij maken certificaat
Verifieer de opdrachtregelargumenten die worden gebruikt voor het maken van handtekeningen.
12
Ongeldige invoer
Verifieer de bestandspaden en andere argumenten die via de opdrachtregel worden doorgegeven naar ADT.
Ondertekeningsopties voor de opdrachtregel van ADT ADT gebruikt JCA (Java Cryptography Architecture) om toegang te krijgen tot persoonlijke sleutels en certificaten voor het ondertekenen van AIR-toepassingen. Met de ondertekeningsopties worden het sleutelarchief en de persoonlijke sleutel en het certificaat in dat sleutelarchief opgegeven. Het sleutelarchief moet zowel de persoonlijke sleutel als de bijbehorende certificaatketen bevatten. Met de certificaatketen wordt de uitgevers-id voor de toepassing bepaald. Als het handtekeningcertificaat via een certificaatketen is gekoppeld aan een vertrouwd certificaat op een computer, wordt de algemene naam (CN) van het certificaat als de uitgeversnaam weergegeven in het dialoogvenster van de AIR-installatie. Voor ADT moet het certificaat aan de x509v3-standaard voldoen (RFC3280) en de EKU-uitbreiding (Extended Key Usage) met de juiste waarden voor de ondertekening van programmacode bevatten. Beperkingen in het certificaat worden gerespecteerd, waardoor sommige certificaten niet kunnen worden gebruikt voor het ondertekenen van AIRtoepassingen. Opmerking: ADT gebruikt de proxy-instellingen van de Java-runtimeomgeving (indien van toepassing) om verbinding te maken met internetbronnen voor het controleren van certificaatintrekkingslijsten en het verkrijgen van tijdstempels. Als u bij het gebruik van ADT problemen ondervindt wanneer verbinding wordt gemaakt met internetbronnen en er voor uw netwerk specifieke proxy-instellingen zijn vereist, kan het zijn dat u de JRE-proxy-instellingen moet configureren. Ondertekeningsopties voor AIR opgeven ❖ Gebruik de volgende syntaxis om de ondertekeningsopties voor de ADT-opdrachten -package en -prepare op te geven: [-alias aliasName] [-storetype type] [-keystore path] [-storepass password1] [-keypass password2] [-providerName className] [-tsa url]
-alias aliasName De alias van een sleutel in het sleutelarchief. U hoeft geen alias op te geven wanneer een sleutelarchief slechts één certificaat bevat. Als er geen alias is opgegeven, wordt de eerste sleutel in het sleutelarchief gebruikt. Niet in alle toepassingen voor sleutelarchiefbeheer mag een alias worden toegewezen aan certificaten. Als u het sleutelarchief van Windows gebruikt, wordt bijvoorbeeld de DN-naam van het certificaat als alias gebruikt. Met het Java-hulpprogramma Keytool kunt u de beschikbare certificaten weergeven zodat u de alias kunt bepalen. Als u bijvoorbeeld deze opdracht uitvoert: keytool -list -storetype Windows-MY
wordt soortgelijke uitvoer als hieronder weergegeven voor een certificaat:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 373 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Als u in de ADT-opdracht op de opdrachtregel naar dit certificaat wilt verwijzen, stelt u de alias in op: CN=TestingCert,OU=QE,O=Adobe,C=US
In Mac OS X is de alias van een certificaat in de Keychain de naam die wordt weergegeven in de toepassing Keychain Access. -storetype type Het type sleutelarchief. Dit wordt bepaald door de implementatie van het sleutelarchief. De standaard sleutelarchiefimplementatie die in de meeste installaties van Java is opgenomen, ondersteunt de typen JKS en PKCS12. Java 5.0 biedt ondersteuning voor het type PKCS11, voor toegang tot sleutelarchieven op hardwaretokens, en het type Keychain, voor toegang tot de KeyChain van Mac OS X. Java 6.0 biedt ondersteuning voor het type MSCAPI (in Windows). Als er andere JCA-providers zijn geïnstalleerd en geconfigureerd, kunnen er meer sleutelarchieftypen beschikbaar zijn. Als er geen sleutelarchieftype is opgegeven, wordt het standaardtype voor de standaard JCA-provider gebruikt. Archieftype
Indeling van sleutelarchief
Minimale Java-versie
JKS
Java-sleutelarchiefbestand (.keystore)
1.2
PKCS12
PKCS12-bestand (.p12 of .pfx)
1.4
PKCS11
Hardwaretoken
1.5
KeyChainarchief
KeyChain van Mac OS X
1.5
Windows-MY of Windows-ROOT
MSCAPI
1.6
-keystore path Het pad naar het sleutelarchiefbestand voor archieftypen die op bestanden zijn gebaseerd. -storepass password1 Het wachtwoord voor toegang tot het sleutelarchief. Als u dit niet opgeeft, vraagt ADT om het wachtwoord. -keypass password2 Het wachtwoord voor toegang tot de persoonlijke sleutel waarmee de AIR-toepassing wordt ondertekend. Als u dit niet opgeeft, vraagt ADT om het wachtwoord. -providerName className De JCA-provider voor het opgegeven sleutelarchieftype. Als u geen provider opgeeft, wordt de standaardprovider voor dat type sleutelarchief gebruikt. -tsa url De URL van een RFC3161-compatibele tijdstempelserver om een tijdstempel voor de digitale handtekening te verkrijgen. Als u geen URL opgeeft, wordt een standaard tijdstempelserver van Geotrust gebruikt. Wanneer de handtekening van een AIR-toepassing een tijdstempel heeft, kan de toepassing nog steeds worden geïnstalleerd nadat het handtekeningcertificaat is verlopen, omdat het tijdstempel aangeeft dat het certificaat geldig was op het moment van ondertekening. Als ADT geen verbinding kan maken met de tijdstempelserver, wordt het ondertekenen geannuleerd en wordt geen pakket gemaakt. Geef -tsa none op om het ophalen van een tijdstempel uit te schakelen. Een AIR-toepassing in een pakket zonder tijdstempel kan echter niet worden geïnstalleerd nadat het handtekeningcertificaat is verlopen. Opmerking: De ondertekeningsopties zijn gelijk aan de overeenkomstige opties van het Java-hulpprogramma Keytool. Met het hulpprogramma Keytool kunt u sleutelarchieven in Windows controleren en beheren. In Mac OS X kunt u hiervoor het beveiligingsprogramma van Apple® gebruiken.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 374 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Voorbeelden van ondertekeningsopties Ondertekenen met een .p12-bestand: -storetype pkcs12 -keystore cert.p12
Ondertekenen met het standaard sleutelarchief van Java: -alias AIRcert -storetype jks
Ondertekenen met een specifiek sleutelarchief van Java: -alias AIRcert -storetype jks -keystore certStore.keystore
Ondertekenen met de KeyChain van Mac OS X: -alias AIRcert -storetype KeychainStore -providerName Apple
Ondertekenen met het sleutelarchief van Windows: -alias cn=AIRCert -storeype Windows-MY
Ondertekenen met een hardwaretoken (raadpleeg de instructies van de fabrikant van het token om Java te configureren voor het gebruik van het token en voor de juiste waarde van providerName): -alias AIRCert -storetype pkcs11 -providerName tokenProviderName
Ondertekenen zonder een tijdstempel: -storetype pkcs12 -keystore cert.p12 -tsa none
Niet-ondertekende tussentijdse AIR-bestanden maken met ADT Gebruik de opdracht -prepare om een niet-ondertekend tussentijds AIR-bestand te maken. Een tussentijds AIRbestand moet met de ADT-opdracht -sign zijn ondertekend om een geldig AIR-installatiebestand te produceren. De opdracht -prepare heeft dezelfde vlaggen en parameters als de opdracht -package (met uitzondering van de ondertekeningsopties). Het enige verschil is dat het uitvoerbestand niet wordt ondertekend. Het tussentijdse bestand wordt gegenereerd met de bestandsextensie airi. Gebruik de ADT-opdracht -sign om een tussentijds AIR-bestand te ondertekenen. (Zie Tussentijdse AIR-bestanden ondertekenen met ADT.) Voorbeeld van ADT adt –prepare unsignedMyApp.airi myApp.xml myApp.swf components.swc
Tussentijdse AIR-bestanden ondertekenen met ADT Gebruik de opdracht -sign om een tussentijds AIR-bestand te ondertekenen met ADT. De ondertekeningsopdracht werkt alleen met tussentijdse AIR-bestanden (extensie airi). Een AIR-bestand kan maar één keer worden ondertekend. Gebruik de ADT-opdracht -prepare om een tussentijds AIR-bestand te maken. (Zie “Niet-ondertekende tussentijdse AIR-bestanden maken met ADT” op pagina 374.) AIRI-bestanden ondertekenen ❖ Gebruik de ADT-opdracht -sign met de volgende syntaxis:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 375 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
adt -sign SIGNING_OPTIONSairi_fileair_file
SIGNING_OPTIONS Met de ondertekeningsopties bepaalt u de persoonlijke sleutel en het certificaat waarmee het AIR-bestand wordt ondertekend. Deze opties worden beschreven in “Ondertekeningsopties voor de opdrachtregel van ADT” op pagina 372. airi_file Het pad naar het niet-ondertekende tussentijdse AIR-bestand dat moet worden ondertekend. air_file De naam van het AIR-bestand dat moet worden gemaakt. Voorbeeld van ADT adt –sign -storetype pkcs12 -keystore cert.p12 unsignedMyApp.airi myApp.air
Zie “AIR-bestanden digitaal ondertekenen” op pagina 328 voor meer informatie.
AIR-bestanden ondertekenen om het toepassingscertificaat te wijzigen Als u een bestaande AIR-toepassing wilt updaten voor het gebruik van een nieuw handtekeningcertificaat, gebruikt u de ADT-opdracht-migrate. In de volgende situaties kan het nuttig zijn om een certificaat te migreren:
• U wilt een zelfondertekend certificaat wijzigen in een certificaat dat door een ondertekeningsinstantie is uitgegeven.
• U wilt een zelfondertekend certificaat dat bijna is verlopen wijzigen in een nieuw zelfondertekend certificaat. • U wilt een commercieel certificaat wijzigen in een ander commercieel certificaat, bijvoorbeeld wanneer de identiteit van uw bedrijf is gewijzigd. Als u een migratiehandtekening wilt toepassen, moet het oorspronkelijke certificaat nog geldig zijn. Wanneer het certificaat is verlopen, kan geen migratiehandtekening worden toegepast. Gebruikers van uw toepassing moeten de bestaande versie verwijderen voordat ze de bijgewerkte versie kunnen installeren. Denk eraan dat de migratiehandtekening standaard een tijdstempel heeft, zodat AIR-updates die met een migratiehandtekening zijn ondertekend ook geldig blijven nadat het certificaat is verlopen. Opmerking: Wanneer u een commercieel certificaat vernieuwt, hoeft u het certificaat gewoonlijk niet te migreren. Een vernieuwd certificaat heeft dezelfde uitgevers-id als het oorspronkelijke certificaat, tenzij de DN-naam is gewijzigd. Zie “Informatie over uitgevers-id's voor AIR” op pagina 329 voor een volledige lijst met de certificaatkenmerken die worden gebruikt om de DN-naam te bepalen. De toepassing migreren voor het gebruik van een nieuw certificaat: 1 Maak een update voor uw toepassing. 2 Plaats het AIR-updatebestand in een pakket en onderteken het met het nieuwe certificaat. 3 Onderteken het AIR-bestand opnieuw met het oorspronkelijke certificaat en de opdracht -migrate.
Een AIR-bestand dat met de opdracht -migrate is ondertekend, kan worden gebruikt om een nieuwe versie van de toepassing te installeren en om eerdere versies te updaten, inclusief versies die zijn ondertekend met het oude certificaat. AIR-toepassingen migreren voor het gebruik van een nieuw certificaat ❖ Gebruik de ADT-opdracht -migrate met de volgende syntaxis:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 376 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
SIGNING_OPTIONS Met de ondertekeningsopties bepaalt u de persoonlijke sleutel en het certificaat waarmee het AIR-bestand wordt ondertekend. Met deze opties moet het oorspronkelijke handtekeningcertificaat worden geïdentificeerd. De opties worden beschreven in “Ondertekeningsopties voor de opdrachtregel van ADT” op pagina 372. air_file_in Het AIR-bestand voor de update, ondertekend met het nieuwe certificaat. air_file_out Het AIR-bestand dat wordt gemaakt. Voorbeeld van ADT adt –migrate -storetype pkcs12 -keystore cert.p12 myApp.air myApp.air
Zie “AIR-bestanden digitaal ondertekenen” op pagina 328 voor meer informatie. Opmerking: De opdracht -migrate is aan ADT toegevoegd in AIR 1.1.
Zelfondertekende certificaten maken met ADT Met zelfondertekende certificaten kunt u een geldig AIR-installatiebestand maken, maar dit geeft uw gebruikers slechts een beperkte veiligheidsgarantie omdat de echtheid van zelfondertekende certificaten niet kan worden geverifieerd. Wanneer een zelfondertekend AIR-bestand wordt geïnstalleerd, wordt bij de gebruiker weergegeven dat de uitgever onbekend is. Een certificaat dat door ADT is gegenereerd, is vijf jaar geldig. Als u een update maakt voor een AIR-toepassing die is ondertekend met een zelfondertekend certificaat, moet u het oorspronkelijke en het bijgewerkte AIR-bestand met hetzelfde certificaat ondertekenen. De certificaten die ADT produceert, zijn altijd uniek, zelfs als dezelfde parameters worden gebruikt. Als u updates zelf wilt ondertekenen met een certificaat dat door ADT is gegenereerd, moet u het oorspronkelijke certificaat daarom op een veilige locatie bewaren. Bovendien kunt u geen bijgewerkt AIR-bestand produceren nadat het oorspronkelijke, door ADT gegenereerde certificaat is verlopen. (U kunt nieuwe toepassingen met een ander certificaat publiceren, maar geen nieuwe versies van dezelfde toepassing.) Belangrijk: Vanwege de beperkingen van zelf-ondertekende certificaten, adviseert Adobe u ten zeerste om voor het ondertekenen van openbaar te maken AIR-toepassingen gebruik te maken van een commercieel certificaat dat is uitgegeven door een erkende certificeringsinstantie. Het certificaat en de bijbehorende persoonlijke sleutel die door ADT zijn gegenereerd, worden opgeslagen in een sleutelarchiefbestand van het type PKCS12. Het opgegeven wachtwoord wordt op de sleutel zelf ingesteld, niet op het sleutelarchief. Certificaten met een digitale id genereren voor zelfondertekende AIR-bestanden ❖ Gebruik de ADT-opdracht -certificate (op één opdrachtregel):
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 377 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
-cn name De tekenreeks die is toegewezen als de algemene naam (CN) van het nieuwe certificaat. -ou org_unit Een tekenreeks die is toegewezen als de organisatie-eenheid die het certificaat uitgeeft. (Optioneel.) -o org_name Een tekenreeks die is toegewezen als de organisatie die het certificaat uitgeeft. (Optioneel.) -c country Een ISO-3166-landcode van twee letters. Er wordt geen certificaat gegenereerd als een ongeldige code is opgegeven. (Optioneel.) key_type Het type van de sleutel die voor het certificaat wordt gebruikt: “1024-RSA” of “2048-RSA”.
pfx_file Het pad van het certificaatbestand dat wordt gegenereerd. password Het wachtwoord voor het nieuwe certificaat. Het wachtwoord is vereist voor het ondertekenen van AIRbestanden met dit certificaat. Voorbeelden van het genereren van certificaten adt -certificate -cn SelfSign -ou QE -o "Example, Co" -c US 2048-RSA newcert.p12 39#wnetx3tl adt -certificate -cn ADigitalID 1024-RSA SigningCert.p12 39#wnetx3tl
Als u deze certificaten wilt gebruiken om AIR-bestanden te ondertekenen, gebruikt u de volgende ondertekeningsopties met de ADT-opdracht -package of -prepare: -storetype pkcs12 -keystore newcert.p12 -keypass 39#wnetx3tl -storetype pkcs12 -keystore SigningCert.p12 -keypass 39#wnetx3tl
Apache Ant gebruiken met de hulpprogramma's van de SDK Dit onderwerp bevat voorbeelden waarin AIR-toepassingen worden getest en in een pakket geplaatst met het hulpprogramma Apache Ant. Opmerking: U vindt hier geen uitgebreid overzicht van Apache Ant. Zie http://Ant.Apache.org voor documentatie over Ant.
Ant gebruiken voor eenvoudige projecten In dit voorbeeld ziet u hoe u een AIR-toepassing bouwt met behulp van Ant en de opdrachtregelprogramma's van AIR. Er wordt een eenvoudige projectstructuur gebruikt waarbij alle bestanden in één map zijn opgeslagen. In deze voorbeelden worden diverse gedefinieerde eigenschappen gebruikt om het constructiescript eenvoudiger opnieuw te kunnen gebruiken. De installatielocaties van de opdrachtregelprogramma's worden gedefinieerd met één set eigenschappen: <property name="SDK_HOME" value="C:/Flex3SDK"/> <property name="ADL" value="${SDK_HOME}/bin/adl.exe"/> <property name="ADT.JAR" value="${SDK_HOME}/lib/adt.jar"/>
De tweede set eigenschappen is specifiek voor het project. In deze eigenschappen wordt uitgegaan van een naamgevingsconventie waarin de namen van het descriptorbestand van de toepassing en de AIR-bestanden zijn gebaseerd op het hoofdbronbestand. Ook andere conventies worden ondersteund.
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 378 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
ADL oproepen om een toepassing te testen Gebruik een exec-taak om de toepassing uit te voeren met ADL: <exec executable="${ADL}"> <arg value="${APP_DESCRIPTOR}"/>
ADL oproepen om een toepassingspakket te maken Voer het hulpprogramma adt.jar in een Java-taak uit om het toepassingspakket te maken: <java jar="${ADT.JAR}" fork="true" failonerror="true"> <arg value="-package"/> <arg value="-storetype"/> <arg value="${STORETYPE}"/> <arg value="-keystore"/> <arg value="${KEYSTORE}"/> <arg value="${AIR_NAME}"/> <arg value="${APP_DESCRIPTOR}"/> <arg value="${APP_NAME}.swf"/> <arg value="*.png"/>
Als er meerdere bestanden in het toepassingspakket moeten worden opgenomen, kunt u extra elementen van het type <arg> toevoegen.
Ant gebruiken voor meer complexe projecten De mapstructuur van een toepassing is gewoonlijk complexer dan een enkele map. In het volgende voorbeeld ziet u hoe u een constructiebestand gebruikt om een AIR-toepassing die een meer praktische projectmapstructuur heeft, te compileren, te testen en in een pakket te plaatsen. In dit voorbeeldproject zijn de bronbestanden van de toepassing en andere assets, zoals pictogrambestanden, opgeslagen in de map src. Met het constructiescript worden de volgende werkmappen gemaakt: build Hierin worden de releaseversies (niet-foutopsporingsversies) van gecompileerde SWF-bestanden opgeslagen. debug Hierin wordt een foutopsporingsversie van de toepassing (die niet in een pakket is geplaatst) opgeslagen, inclusief
alle gecompileerde SWF- en assetbestanden. Het hulpprogramma ADL voert de toepassing uit vanuit deze map. release Hierin wordt het definitieve AIR-pakket opgeslagen.
Voor de hulpprogramma's van AIR moeten enkele aanvullende opties worden gebruikt voor bestanden die niet in de huidige werkmap staan:
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 379 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
Testen Het tweede argument dat aan ADL wordt doorgegeven, bevat de hoofdmap van de AIR-toepassing. De
volgende regel wordt aan de testtaak toegevoegd om de hoofdmap van de toepassing op te geven: <arg value="${debug}"/>
Pakket maken Als in het pakket bestanden moeten worden geplaatst uit submappen die geen deel mogen uitmaken van de definitieve pakketstructuur, moet de werkmap van ADT worden gewijzigd met de instructie -C. Wanneer u de instructie -C gebruikt, worden bestanden en mappen in de nieuwe werkmap gekopieerd naar het hoofdniveau van het AIR-pakketbestand. Met -C build file.png wordt file.png dus gekopieerd naar de hoofdmap van de toepassingsmap. En met -C assets icons wordt de map icons naar het hoofdniveau gekopieerd en worden alle bestanden en mappen in de map icons ook gekopieerd. Met de volgende regels wordt bijvoorbeeld de map icons rechtstreeks toegevoegd aan het hoofdniveau van het toepassingspakketbestand: <arg value="-C"/> <arg value="${assets}"/> <arg value="icons"/>
Opmerking: Als u veel bronnen en assets naar andere relatieve locaties moet verplaatsen, is het gewoonlijk eenvoudiger om deze met Ant-taken naar een tijdelijke map te verplaatsen dan een complexe argumentenlijst voor ADT samen te stellen. Wanneer uw bronnen zijn geordend, kunt u deze met een eenvoudige argumentenlijst voor ADT in een pakket plaatsen. <project> <property name="SDK_HOME" value="C:/Flex3SDK"/> <property name="ADL" value="${SDK_HOME}/bin/adl.exe"/> <property name="ADT.JAR" value="${SDK_HOME}/lib/adt.jar"/> <property name="PROJ_ROOT_DIR" value="."/> <property name="APP_NAME" value="ExampleApplication"/> <property name="APP_ROOT_DIR" value="."/> <property name="APP_ROOT_FILE" value="${APP_NAME}.swf"/> <property name="APP_DESCRIPTOR" value="${PROJ_ROOT_DIR}/${APP_NAME}-app.xml"/> <property name="AIR_NAME" value="${APP_NAME}.air"/> <property name="release" location="${PROJ_ROOT_DIR}/release"/> <property name="assets" location="${PROJ_ROOT_DIR}/src/assets"/> <property name="STORETYPE" value="pkcs12"/> <property name="KEYSTORE" value="ExampleCert.p12"/> <mkdir dir="${release}"/> <exec executable="${ADL}"> <arg value="${APP_DESCRIPTOR}"/> <arg value="${APP_ROOT_DIR}"/> <java jar="${ADT.JAR}" fork="true" failonerror="true">
ONTWIKKELING VAN ADOBE AIR 1.5-TOEPASSINGEN MET FLASH CS4 PROFESSIONAL 380 AIR-toepassingen maken met behulp van opdrachtregelprogramma's
bitmapafbeeldingen, instellen voor pictogrammen 103
verplaatsen 122
bitmaps
verwijderen 123, 124 verwijzen 114 bestandenlijsten slepen en neerzetten, ondersteuning voor 147 bestandskiezer, dialoogvensters 115 bestandssysteem beveiliging 40
bytearrays
toepassing, opslagdirectory 26
kopiëren en plakken, ondersteuning voor 153 slepen en neerzetten, ondersteuning voor 137, 147 bitmaps, eigenschap (klasse Icon) 103 bladeren om een bestand te selecteren 115 om een map te selecteren 113
positie in 160 bytesAvailable, eigenschap (klasse ByteArray) 160 bytevolgorde 161 C Canvas, object 227, 234 Capabilities language, eigenschap 352 languages, eigenschap 352 Capabilities, klasse playerType, eigenschap 307 certificaten ADT, opdrachtregelopties voor 372 codeondertekening 44 indelingen van 330 instanties (CI's) 44
visible, element (descriptorbestand van de toepassing) 52
close(), methode 61
volgorde van vensters 75
htmlLoader, object 223
voorbeeldtoepassingen 2
moveTo(), methode 61
vorig formaat herstellen, vensters 62, 77
nativeWindow, eigenschap 61, 69, 231
vraagteken (?) teken in onbenoemde SQLparameters 181
nativeWindow, object 223
instellen voor gecodeerde mediainhoud 283 webbrowsers AIR-toepassing starten vanuit 300 detecteren of een AIR-toepassing is geïnstalleerd vanuit 325 detecteren, AIR-runtime vanuit 324
Y y, element (descriptorbestand van de toepassing) 52 Z zelfondertekende certificaten 44, 328, 376 zichtbaarheid van vensters 52 ZIP-bestandsindeling 164 ZLIB-compressie 162