dynamische iphone-anwendungen entwickeln. anwendungsentwicklung mit html, css und javascript

226

Upload: lee-s-barney

Post on 27-Dec-2016

226 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 2: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Dynamische iPhone-Anwendungen entwickeln

Page 3: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 4: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Lee S. Ba rney

Dynamische iPhone-Anwendungen entwickeln

.. ~ .. ADDISON-W ESLEY

An impri nt of Pearson Education

München • Boston • San Francisco • Harlow, England

Don Mills, Ontario • Sydney • Mexico City

Madrid • Amsterdam

Page 5: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Bibl iografische Information der Deutschen Nationalbibl iothek

Die Deut sche Nationalbibliot hek verzeichnet diese Publikation in der Deutschen Nationalbibl iografie;

det aillierte bibl iografische Dat en sind im Int ernet über http:/ /dnb.d-nb.de abrufbar.

Die Informationen in diesem Produkt werden ohne Rücksicht auf einen eventuel len Patentschutz

veröffentl icht. Warennamen werden ohne Gewährleistung der fre ien Verwendbarkeit benutzt.

Bei der Zusammenst el lung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht vollständig ausgeschlossen werden. Verlag, Herausgeber und Autoren

können für feh lerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch

irgendeine Haftung übernehmen. Für Verbesserungsvorschläge und Hinweise auf Fehler sind

Verlag und Herausgeber dankbar.

Autorisierte Übersetzung der amerikanischen Orig inalausgabe: "Developing Hybrid Applications forthe iPhone".

Al le Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig.

Fast al le Hard- und Softwarebezeichnungen und weitere Stichworte und sonstige Angaben, die in d iesem Buch verwendet werden, sind als eingetragene Marken geschützt.

Da es nicht möglich ist, in allen Fällen zeitnah zu ermitteln, ob ein Markenschutz besteht,

w ird das ®-Symbol in d iesem Buch nicht verwendet.

Authorized translation from the English language edit ion, entit led "Developing Hybrid Web Applications"

by Barney, lee S., published by Pearson Education, lnc, publishing as Addison Wesley Professional,

Copyright© 2009 All r ights reserved. No part ofthis book may be reproduced ortransmitted in anyform or by any means,

electronic or mechanical, including photocopying, recording or by any information storage retrieval system,

w ithout permission from Pearson Education, lnc. GERMAN language edit ion published by

PEARSON EDUCATION DEUTSCHLAND, Copyright© 2010

Umwelthinweis: Dieses Buch wurde auf chlor- und säurefreiem PEFC-zertifiz ierten Papier gedruckt.

Um Rohstoffe zu sparen, haben w ir auf Fol ienverpackung verzichtet.

10 9 8 7 6 s 4 3 2 1

13 12 11 10

ISBN: 978-3-8273-2918-9

© 2010 by Addison-WesleyVerlag,

ein lmprint der Pearson Education Deutschland GmbH,

Martin-Kollar-Straße 10 - 12, D-81829 München/Germany

Alle Rechte vorbehalten Übersetzung: G&U Language & Publishing Services GmbH, Flensburg, www.GundU.com

Fach Iektorat: Phi lipp Homann, phil [email protected] Lektorat: Brig itte Bauer-Schiewek, [email protected]

Korrektorat Sandra Gottmann, Münster

Covergestaltung: Marco Lindenbeck, [email protected]

Herstellung: Phil ipp Burkart, [email protected] Satz: mediaService (www.media-service.tv)

Druck und Verarbeitung: Kösel Druck, Krugzell (www.KoeseiBuch.de)

Printed in Germany

Page 6: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Dieses Buch ist meiner wundervollen Frau Joan und unseren fünf Jungs gewidmet, die es ertragen haben, dass ich beim Schreiben dieses Buches ständig zu beschäftigt war.

Die Ewigkeit reicht nicht aus, um mit euch zusammen zu sein.

Page 7: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 8: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Inhaltsverzeichnis

ln haltsverzeichnis

Vorwort

Entwicklungswerkzeuge für Web-Apps

Der Aufbau dieses Buches

On Ii ne-Queiien

Voraussetzungen

Danksagungen

Der Autor

Kontakt mit dem Autor

1 Entwicklung mit Dashcode und Xcode

11

11

12

14

15

15

15

15

17

1.1 Dashcode und die benutzerdefinierte Vorlage Quick-ConnectiPhone 17

1.2 Xcode und die benutzerdefinierte QuickConnect-Vorlage verwenden 21

1.3 Erste Einführung in Objective-C 26

1.4 Die Struktur von QuickConnectiPhone-Anwendungen in Objective-C 29

1.5 Webinhalt einbetten: QuickConnectiPhone 33

1.6 Zusammenfassung

2 JavaScript-Modularität und iPhone-Anwendungen

2.1 Modularität

2.2 Das JavaScript-Framework von QuickConnectiPhone­

ein Beispiel fü r Modularität

2.3 Die QuickConnectiPhone-Umsetzung des modularen Entwerfens

2.4 Implementierung von Unternehmens- und Ansichtsanwendungscontrol lern

2.5 Die Implementierung des Feh leranwendungscontrollers

2.6 Die Funktionalität der Anwendung erstellen

2.7 Zusammenfassung

41

41

43

53

Page 9: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Inhaltsverzeichnis

3 Benutzerschnittstellen f ür das iPhone erstellen

3.1 Die Schnittstellenrichtlinien von Apple

67

68

3.2 Listen- und browsergestützte Schnittstellen 71

3·3 Anwendungen mit nicht auf Listen beruhenden Ansichten 75

3·4 Immersionsanwendungen 8o

3·5 Benutzerdefinierte (55-Transformationen erstellen und verwenden 82

3.6 Ein Modul für Drag&Drop, Skalierung und Drehung erstellen und verwenden 90

3·7 Zusammenfassung 102

4 GPS, Beschleunigungsmessung und andere syst emeigene Funktionen von QuickConnect 103

4·1 Geräteaktivierung in JavaScript 104

4·2 Geräteaktivierung in Objective-C 111

4·3 Die Objective-C-Implementierung der QuickConnectiPhone-Architektur 120

4·4 Zusammenfassung 127

5 Google Maps einbetten 129

5·1 Abschnitt 1: Eine Karte in einer JavaScript-Anwendung mit

QuickConnect anzeigen 129

5·2 Abschnitt 2: Die Objective-C-Implementierung des Kartenmodu ls von QuickConnect 134

5·3 Zusammenfassung 147

6 Datenbankzugriff 149

6.1 Abschnitt 1: Die Beispielanwendung BrowserDBAccess 149

6.2 Abschnitt 2: SQLite-Datenbanken der WebKit-Engine verwenden 151

6.3 Abschnitt 3: Native SQLite-Datenbanken verwenden 157

6.4 Abschnitt 4: Das DataAccessObject in Datenbanken der WebKit-Engine verwenden 159

6.5 Abschnitt 5: DataAccessObject in nativen Datenbanken verwenden 172

8

Page 10: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Inhaltsverzeichnis

7 Datenzugriff über das Netzwerk

7.1 Abschnitt 1: Die Beispielanwendung BrowserAJAXAccess

7.2 Abschnitt 2: ServerAccessObject verwenden

7·3 Abschnitt 3: ServerAccessObject

7·4 Abschnitt 4: Sicherheitsfunktionen

7-5 Zusammenfassung

A Einführung in JSON

A.1 Abschnitt 1: Hintergrund

A.2 Abschnitt 2: Eine JSON-API für JavaScript

A.3 Zusammenfassung

B Evolution von QuickConnectFamily

8.1 Definitionen

Stichwortverzeichnis

187

188

190

196

208

209

211

211

213

216

217

219

221

9

Page 11: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 12: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Vorwort

ln diesem Buch lernen Sie, wie Sie eine neue Art von iPhone-Anwendungen erstellen:Web­

Apps, die in einer Kombination aus HTML, CSS und JavaScript geschrieben sind. Dabei han­

delt es sich um eigenständige Anwendungen, die wie normale iPhone-Programme direkt

auf dem Gerät ausgeführt werden, bei denen sich die Dateien aber nicht auf einem Server

im Internet befinden müssen.

Die erforderliche Entwicklungszeit und der Lernaufwand dafür, eine Anwendung in die

Hände Ihrer Kunden zu legen, ist bei Web-Apps geringer, da Sie weder Objective-C lernen

noch tiefe Kenntnisse des Frameworks Cocoa Touch haben müssen.

ENTWICKLUNGSWERKZEUGE FÜR WEB-ÄPPS

ln diesem Buch w ird das am häufigsten verwendete JavaScript-Softwarepaket aus dem

Open-Source-Bereich zum Schreiben von Anwendungen für das iPhone und den iPod

tauch behandelt, nämlich QuickConnectiPhone. Mit diesem Paket können Sie Anwendun­

gen schreiben, die direkt in JavaScriptauf geräteeigene Funktionen zugreifen, z.B. Vibra­

tion, GPS-Ortung, den Beschleunigungssensor usw. - und al l das, ohne eine einzige Zeile

Code in Obj ective-C oder Cocoa zu schreiben.

QuickConnectiPhone, das Sie von http:llsourceforge.netlprojectslquickconnect herunter­

laden können, bietet den Zugriff auf die meisten geräteeigenen Funktionen und ein sorg­

faltig entworfenes, vol lständig ausgestattetes Framework für die Entwicklung. Achten Sie

darauf, dass Sie QuickConnectFamily herunterladen. Zum Druckzeitpunkt dieses Buches

existiert dieses in der Version 1.5. Mit QuickConnect können Sie die Zeit bis zur Marktreife

Ihrer Anwendung verringern, da das Framework unter anderem den gesamten zusammen­

hängenden Code enthält, den Sie gewöhnlich in Objective-C, Cocoa und JavaScript schrei­

ben. Besonders schön ist, dass für die Nutzung der JavaScript-, HTML- und CSS-Dateien kein

Server im Netzwerk erforderlich ist.

Um den Lernaufwand zu verringern und das Verständnis zu verbessern, wurden überal l in

diesem Buch gute, sinnvol le Beispiele verwendet.

11

Page 13: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

VOrwort

Wenn Sie installierbare iPhone-Anwendungen erstel len, die dazu erforderlichen Fäh ig­

keiten erwerben und dynamische, ansprechende Lösungen schaffen wollen, die andere

Menschen gern benutzen, liegen Sie mit diesem Buch richtig, das Ihnen zeigt, wie Sie dieses

Paket verwenden.

Tabelle V.1 zeigt die einzelnen Funktionalitäten (zum Zeitpunkt der Abfassung dieses Buches).

Verfügbares Merkmal QuickConnectiPhone

GPS Ja

Beschleunigungsmesser Ja

Vibration Ja

Systemsounds Ja

Ad-hoc-Netzwerke (Bonjour) Ja

Netzwerke über Synchron isierungskabel Ja

Datenbankzugriff über Browser Ja

Integrierter Datenbankzugriff Ja

Drag&Drop-Bibliothek Ja

AJAX-Wrapper Ja

Aufzeichnung und Wiedergabe von Audiodateien Ja

Eingebettete Google-Karten Ja

Bibliothek f ür Diagramme und Grafiken Ja

Tabelle \1.1: QuickConnectiPhone-Funktionalitäten

DER AUFBAU DIESES BUCHES

Jedes Kapitel besteht aus zwei Teilen. Im ersten Teillernen Sie, wie Sie das betreffende Merk­

mal von QuickConnectiPhone einsetzen, um eine bestimmte Aufgabe zu erledigen, z.B. um

die aktuellen GPS-Daten des Geräts abzurufen. Der zweite Teil zeigt Ihnen, wie der Code

hinter dem JavaScript-Auf ruf aussieht und wie er funktioniert. So können Sie selbst ent ­

scheiden, w ie t ief Sie in die JavaScript- und Obj ective-C-Hintergründe eintauchen wol len.

12

Page 14: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Vorwort

Das Buch ist w ie folgt aufgebaut:

> Kapitel 1, »Entwicklung mit Dashcode und Xcode«, zeigt Ihnen, wie Sie Dashcode

und Xcode mit QuickConnectiPhone einsetzen, um ansprechende Anwendungen

für das iPhone in kurzer Zeit zu erstellen. ln diesem Kapitelfinden Sie auch die

Grundlagen der Verwendung von Dashcode und Methoden zur Übertragung von

Dashcode-Anwendungen in Xcode, um sie kompi lieren und auf Geräten ausführen

zu können.

> Kapitel2, »Die Modularität von JavaScript für iPhone-Anwendungen«, beschreibt, wie

Sie die Zeit bis zur Marktreife bedeutend verringern können, indem Sie die Modula­

rität des Framewerks QuickConnectiPhone nutzen. Hier erfahren Sie auch, wie Sie

Frontcontroller, Anwendungscontroller und die Ei nbi ndu ng von JavaScript rea Iisieren.

> Kapitel 3, »Benutzerschnittstellen für das iPhone erstellen«, hilft Ihnen dabei, Ihre

Anwendungen so zu schreiben, dass sie den Verteilungsrichtlinien für den Apple

App Store genügen. Hier lernen Sie die empfohlenen Vergehensweisen zum Erstel­

len nützlicher iPhone-Anwendungen kennen. Es werden ebenso die verschiedenen

Arten von Anwendungen beschrieben, die gewöhnlich für das iPhone geschrieben

werden, als auch die Fallstricke, derer Sie sich bewusst sein müssen.

> Kapitel 4, »GPS, Beschleunigungsmessung und andere systemeigene Funktionen

von QuickConnect«, zeigt Ihnen, wie Sie GPS-Daten, Beschleunigungsmesswerte

und Gerätebeschreibungen abrufen, wie Sie das iPhone vibrieren lassen und wie

Sie Audiodateien abspielen und aufnehmen. Hier greifen Sie mit dem Framework

QuickConnectiPhone auf diese geräteeigenen Merkmale zu und nutzen sie. Damit

wirken Ihre Anwendungen wirklich wie für das iPhone gemacht, und der Komfort

ihrer Anwendung erhöht sich.

> ln Kapitel 5, »Google Maps einbetten«, erfahren Sie, wie Sie mit QuickConnect­

iPhone eine Google-Karte in Ihre Anwendung aufnehmen. Dies ist eines der am

stärksten nachgefragten Merkmale. Dadurch müssen Sie Ihre Benutzer nicht län­

ger auf die Anwendung Karten verweisen.

> Kapitel6, »Datenbankzugriff«, zeigt, wie Sie Informationen aus Datenbanken abru­

fen und darin speichern, um diese dann in Ihrer Anwendung zu nutzen. Die Daten­

banken erstellen Sie mit dem Framework QuickConnectiPhone. Müssen Sie zusam­

men mit Ihrer Anwendung eine vordefinierte Menge von Daten in einer Datenbank

ausliefern? Dann lesen Sie dieses Kapitel!

13

Page 15: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

VOrwort

> ln Kapitel 7, »Datenzugriff über das Netzwerk«, geht es darum, wie Sie in Ihrer in­

sta llierten Anwendung auf Daten von Servern oder Diensten im Netzwerk zugreifen

und sie verwenden. Dies geht sehr einfach mit einem Wrapper, der Sie die Informa­

tionen von einem anderen Ort abrufen lässt. Wenn Sie z.B. Daten von einem Online­

Biog beziehen und mit einem Twitter-Feed zusammenführen müssen, erleichtert

das QuickConnectiPhone-Modul für den Datenzugriff über das Netzwerk diese

Aufgabe.

Darüber hinaus gibt es noch folgende Anhänge:

> Anhang A, »Einführung in JSON«, gibt eine ku rze Einführung in JSON (JavaScript

Object Notation). JSON ist eine der am häufigsten verwendeten und einfachsten

Möglichkeiten, um Daten überall dorthin zu übertragen, wo sie gebraucht werden.

> Anhang B, »Evolution von QuickConnectFamily«, gibt einen Überblick über die künf­

tige Entwicklung von QuickConnectiPhone. Wenn Sie Anwendungen für iPhones

und andere Plattformen erstellen möchten, z.B. für die Android-Telefone von Google,

Nokia- oder Blackberry-Handys oder Desktopsysteme mit Mac OS X, Linux oder Win­

dows, sollten Sie einen Blick in diesen Anhang werfen.

ÜNLINE-QUELLEN

QuickConnectiPhone unterliegt einer raschen Entwicklung. Um auf dem neuest enStand

der j üngsten Funktionen und Fähigkeit en zu bleiben und um mehr zu lernen, nutzen Sie

die folgenden Links.

QuickConnectiPhone

> Beispiele und das Framewerk können Sie von https://sourceforge.netlprojectsl quickconnect/ herunterladen.

> Einen Blag zur Entwicklung mit QuickConnect finden Sie auf http:lltetontech. wordpress.com.

> Das Wiki befindet sich auf http:llquickconnect.pbwiki.com/FrontPage.

> Die Google-Gruppe finden Sie auf http:llgroups.google.comlgroupl quickconnectiPhone/.

> Twitter-Meldungen gibt es auf http:lltwitter.comlquickconnect.

14

Page 16: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Vorwort

VORAUSSETZUNGEN

Um Nutzen aus diesem Buch ziehen zu können, brauchen Sie Grundkenntnisse in HTML,

CSS und JavaScript. Wenn Sie damit bereits Webseiten erstellt haben, sind Sie schon gut

für die Entwicklung von iPhone-Anwendungen vorbereitet. Wo in Qu ickConnectiPhone

Hilfestellung zum Objective-C-Code erforderl ich ist, wi rd sie auch gegeben. Dieses Buch

ist aber keine Einführung in Objective-C und keine An leitung dazu, wie Sie iPhone-Anwen­

dungen in Objective-C schreiben.

Sie müssen die Xcode-Werkzeuge von Apple von der iPhone-Entwicklerwebsite unter

http:!!developer.apple.comliphone herunterladen. Dazu brauchen Sie Mac OS X 10.5 oder

höher und einen Mac mit lntei-Chipsatz.

Es ist zwar nicht erforderlich, dass Sie über ein iPhone oder einen iPod touch verfügen,

doch ist dies sinnvol l, um die Anwendungen auf diesen Geräten testen und ausführen zu

können.

DANKSAGUNGEN

Mein besonderer Dank gilt Daniel Barney, der den Code für eingebettete Google-Karten

durchgearbeitet und korrigiert hat. Außerdem möchte ich meinen Mitarbeitern im Com­

puter Information Technology Department der Brigham Young University in ldaho für das

Zuhören und ihre Anregungen danken.

DER AUTOR

LeeS. Barney (aus Rexburg in ldaho) ist Professor im Computer Information Technology De­

partment des Business and Communication College an der Brigham Young University ldaho.

Er war als CIO und CTO von @HomeSoftware beschäftigt, einem Unternehmen zur Herstel­

lung webbasierter, mobiler Daten- und Zeitplananwendungen fü r die private Gesundheits­

vorsorge. Davor hat er über sieben Jahre lang als Programmierer, leitender Software-Ingeni­

eur, Qualitäts-, Entwicklungs- und Projektmanager für AutoSimulations lnc. gearbeitet, den

fü hrenden Hersteller von Planungs- und Terminsoftware für die Halbleiterindustrie. Er ist

der Autor des Buches Oracle Database AJAX & PHP Web Application Development.

KONTAKT MIT DEM AUTOR

Per E-Mail erreichen Sie den Autor (in englischer Sprache) über [email protected].

Für andere Formen der Kontaktaufnahme nutzen Sie die weiter vorn angegebenen Twitter-,

Wiki- und Google Groups-Links.

15

Page 17: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 18: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Entwicklung mit Dashcode und Xcode

Wenn Dashcode und Xcode zusammen eingesetzt werden, bieten sie die Leistungsfähig­

keit und einfache Verwendbarkeit, die Sie benötigen, um einmalige, spannende und hybri­

de iPhone-Anwendungen zu schreiben. Da beide Tools um benutzerdefinierte Vorlagen f ür

iPhone-Web-Apps erweitert wurden, brauchen Sie keinen eigenen Objective-C-Wrapper zu »backen«. in den ersten beiden Abschnitten erfahren Sie, wie Sie vorhandene Vorlagen

f ür iPhone-Web-Apps f ür Dashcode und Xcode verwenden, mit denen Sie recht schnell

zum Ziel kommen. Außerdem finden Sie in den Abschnitten 3 bis 5 eine ku rze Erörterung

der Grundlagen von Objective-C und darüber, wie eine in dieser Sprache geschriebene

iPhone-Anwendung in dem am meisten genutzten Framework für Web-Apps- QuickCon­nectiPhone- struktu riert ist.

1.1 DASHCODE UND DIE BENUTZERDEFINIERTE VORLAGE

QU ICK-(ON N ECTI PHON E

Da ein großer Tei l der Benutzeroberfläche und der Interakt ion f ür iPhone-Web-Apps mit

HTML, JavaScript und CSS erstellt wird, erfolgen Entwicklung und Fehlerbehebung über­

wiegend in Dashcode. Der mit Drag&Drop ausgestattete Oberflächengenerator ist in sei­

nem Umfang und der Leichtigkeit seiner Anwendung einmalig. Um die Anwendung zu

Page 19: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitell Entwicklung mit Dashcode und Xcode

erstellen, wird überwiegend Dashcode eingesetzt . Außerdem erledigen Sie mithilfe des zu­

gehörigen Simulators und der integrierten Debugging-Tools auch die Fehlerbehebung.

Da der größte Teil des Codes für iPhone-Hybridanwendungen ähnlich aussieht, macht das

Erstellen einer ent sprechenden Vorlage das Neuschreiben oder Importieren des gemeinsa­

men Codes zu Beginn jedes neuen Projekts überflüssig. Eine Abhandlung zum gemeinsamen

Code finden Sie in Kapitel2, »Die Modularität von Objeetive-C und iPhone-Anwendungen«.

Sie können QuickConnect von folgender Adresse herunterladen: http://sourceforge.net/ projectslquickconnect.ln diesem Download ist eine Dashcode-Vorlage enthalten, die Ihnen

beim Erstellen von iPhone-Hybridanwendungen hi lft. Die Installationsroutine für Quick­

ConnectFamily fügt diese Vorlage in Dashcode ein.

r KEINE QUICK(ONNECTIPHONE-VORLAGEN FÜR DASHCODE 3.0

Zum Druckzeitpunkt dieses Buches liegt QuickConnect in der Version 1.5 vor. Diese Ver­

sion unterstützt derzeit noch keine Vorlagen für die m it Snow Leopard erschienene

Dashcode Version 3.0. Möchten Sie dennoch die Vorlagen nutzen, installieren Sie bitte

das Xcode SDK für Leopard, dieses beinha ltet Dashcode 2.0.

C Dashcodt Abl.a9t l!eatb~itEn F~rmat Anordnen Ol?bug Darstellung Ftnntr Hilft

@ "' !""'! Ul'lbol'!.a.ntn

8 1ntroZ

~j)'t09f~mm:.t1ributt

m·"'""

8C ... 'e<gi)I"ISi~ O'*fiO Uil 4U lli ~IIO~IIek. l"' CEfl Mtlt•tstXY"~ ICl t.llcll!IUcm Si:<llc OvmKil ' ' ' u -d« O~jc:k!c io'l d c.n i ,.II)M."i OCitoc!l, 3 Artu:lu~cidl

lrlt(lf'i'nl!IOIIt ll

>

W Al~ ertt<i~: ruJl.iertn -

Hol!ldler & COde hin • C!!l!:m!a ~ Attribu t~ fc:s d ett:n

I ti I. • • ' iil( \ 4 ; ' I!<Stl; ' IJXI'

0 UD ~ ' · i•td ' ' ' I.;,'? ' ' ' h~' ' ' ' ' ' ' i&S5 •

Q~~ntCOnll ••

MII ~itH A~h'< IU!Sl'lrti!)! ._.if!J Ot rt 8:Hii112l'f ~r(lue~;. c&.:IH getldt" Wie l!l'ar~ ltunv )W,!t lh:IC:t,

~ Abbildung 1.1: Die Vorlage QuickConnectiPhone wird in Dashcode verwendet.

Sie sehen das Standarddialogfeld Bibliothek.

18

Page 20: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Dashcode und die benutzerdefinierte Vorlage Quick-ConnectiPhone

Nachdem Sie die Installationsroutine für QuickConnectFami ly ausgef ührt und Dashcode

gestartet haben (Dashcode befindet sich auf Ihrer Festplatte unter /Developer/Applica­

tions), finden Sie unterhalb der Dashcode-Widgets die Vorlage Qui ckConnect i Phone am

Ende des Dialogfelds zur Auswahl. Ein Doppelklick auf das Symbol Qui ckConnec t i Phone

bringt Sie direkt zum Dashcode-Hauptbildschirm, in dem die leere Benutzeroberfläche an­

gezeigt wird. Abbi ldung 1.1 zeigt, wie die Dashcode-Anwendung in Betrieb aussieht.

Um die im Framewerk integrierten Dateien zu verstehen und problemlos anwenden zu können, müssen Sie zunächst mit Dashcode eine einfache Benutzeroberfläche erstel len

und sie Ihrem iPhone mit Xcode bereitstellen. Die Oberfläche, die hier erstellt w ird, besteht

led iglich aus einer Schaltfläche und einem Textfeld. Wird die Schaltfläche betätigt, zeigt

das Textfeld »Welcome«.

WEB-ÄPPS UND DAS DIALOGFELD ALERT

Wer häufig in Objective-C schreibt, benutzt oft das Dialogfeld ALERT, um Fehler in einer

Anwendung zu suchen oder dem Benutzer etwas mitzuteilen. Die Objective-C-Funk­

tion al ert ist eigentlich nichts, was vom Objective-C-Modul erledigt wird, sondern ein

Aufruf in den nativen Code des umschließenden Browsers.

Dies ist in QuickConnectiPhone-Anwendungen nicht integriert, wei l die Verwendung

von Dialogfeldern die von Apple festgelegten Standards für die iPhone-Benutzerober­

fläche verletzt. Für die Fehlerbehebung bietet sich der Dashcode-Debugger an. Stellen

Sie Ihre Anwendung auf Xcode um, können Sie mithilfe der Funktion debug Meldun­

gen in der Xcode-Konsole ausgeben.

Um Benutzern wichtige Informationen zu übermitteln, fügen Sie sie unabhängig vom

verwendeten Tool in ein di v- oder ein anderes HTMl-Eiement ein.

Um diese Benutzeroberfläche zu erstellen, überzeugen Sie sich zunächst, dass das Dialog­

feld BIBLIOTHEK geöffnet ist. Wenn nicht, klicken Sie auf das entsprechende Symbol in der

obersten Leiste von Dashcode. Suchen Sie anschließend das Element TEXT am Ende der

Elementbibliothek, und ziehen Sie es auf den leeren Anwendungsbi ldschirm. Dann wird

oben in der Oberfläche Ihrer Anwendung ein Textbereich angezeigt, der das Wort Te xt

enthält. DieserText weist standardmäßig eine Breite von 100 Prozent auf Dashcode stellt

in der Ihrer Anwendung zugrunde liegenden Datei i ndex . html ein HTML-di v-Tag sowie

etwas Objective-C-Code bereit, um den Bereich nach Belieben mitText, Hintergrundfarben

usw. zu füllen .

19

Page 21: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitell Entwicklung mit Dashcode und Xcode

Für dieses Beispiel setzen Sie die ID dieses di v-Tags auf di spl ay und leeren das Text­

feld. Dazu verwenden Sie den Entitäteninspektor der Oberfläche, indem Sie das Dialogfeld

durch Auswahl des Informationssymbols in der obersten Symbol leiste von Dashcode akti­

vieren. Wechseln Sie auf die rot-weiße Registerkarte in der linken oberen Ecke des Informa­

tionsdia Ioges, setzen Sie das ID-Feld auf di spl ay und leeren Sie das Feld BEZEICHNUNG.

Versehen Sie die Oberfläche nun mit einer PusH-Schaltfläche, indem Sie sie hineinziehen

und außerhalb des Textfelds ablegen. Der Informationsdialog zeigt jetzt anstel le der In­

format ionen für das Textfeld diejenigen für die Schaltfläche an. Markieren Sie den blauen

Kubus in der rechten oberen Ecke des Dialogfelds INFORMATIONEN, um die Registerkarte

BEHAVIORS zu öffnen. Dort können Sie Objective-C-Funktionen als Handler für alle Ereig­

nisarten definieren, die in der Benutzeroberfläche vorkommen. Beachten Sie, dass zahl­

reiche übliche Obj ective-C-Mausereignisse fehlen . Sie wurden durch ongesturestart, ongesturechange und engestureend ersetzt. Geben Sie im Handler-Abschnitt des

Ereignisses onc l i ck changeText ein. Damit wird eine FunktionchangeText in die Datei

ma in. j s eingefügt und angezeigt. Sie können nun definieren, was geschieht , wenn das

Ereignis onc l i ck ausgelöst wird. ln diesem einfachen Fall f ügen Sie folgenden simplen Code in die FunktionchangeText ein:

document.getEl ementßy l d( 'displ ay ' ).innerHTML = ' We l come ' ;

Damit ist die Beispielanwendung so weit, dass sie im iPhone-Simulator ausgeführt wer­

den kann. Mit dem Symbol AusFÜHREN in der linken oberen Ecke von Dashcode starten

Sie den Simulator und führen Ihre Anwendung darin aus. Abbildung 1.2 zeigt die Beispiel­

anwendung im Simulator.

20

~ Abbildung 1.2: Die einfache Beispielanwendung wird nach einem Klick auf die Schaltjläche im Dashcode-Simulator ausgeführt.

Page 22: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

X-code und die benutzerdefinierte QuitkConnect-Vorlage verwenden

Nachdem Sie mit der Erstellung und Fehlerbehebung der Anwendung fertig sind, können

Sie dazu übergehen, den Code zur Bereitstellung als installierbare Anwendung in Xcode

umzuwandeln. Zunächst verwenden Sie Dashcode dazu, die betreffende Anwendung

bereitzustellen. Wenn Sie darauf verzichten, bleibt der Code in Ihrem Dashcode-Projekt

verborgen. Er enthält Direktiven, die nur Dashcode versteht.

Klicken Sie auf das Symbol BEREITSTELLEN links auf dem Dashcode-Bildschirm, um den

Bereitstellungsdialog einzublenden.Jetzt können Sie den fertigen HTML-, CSS- und Objective­

C-Code in einer Form auf der Festplatte speichern, die sich in Ihre Anwendung einbetten lässt.

Geben Sie im Feld PFAD einen Namen f ür ein neues Verzeichnis ein, um es auf der Festplatte

Ihres Rechners anzulegen. Dort werden die Dateien anschließend gespeichert. Sie sind jetzt

auch für den Import in Xcode bereit.ln Abbi ldung 1.3 sehen Sie den Bereitstellungsdialog.

Weitere Informationen darüber, welche Obj ective-C-Dateien in dieser Vorlage enthalten sind und w ie sie die Erstellung von Anwendungen erleichtern, finden Sie in Kapitel 2.

1.2 XCODE UND DIE BENUTZERDEFINIERTE QUICK(ONNECT­

VORLAGE VERWENDEN

Da Sie die Installationsrout ine Oui ckC onnectFami l y ausgeführt haben, ist die Xcode­

QuickConnectiPhone-Vorlage App l i ca t i on instal liert, mit der Sie j etzt das Xcode-Pro­

jekt fü r Ihre QuickConnectiPhone-Hybridanwendung erstellen. Dieser Abschnitt führt

Sie durch den Vorgang. Das Wiki Oui ckConnectFami l y enthä lt ein Video dazu (http:! I quickconnect.pbwiki.com!Moving-Dashcode-projects-to-Xcode) .

Als Erstes wählen Sie NEW_ PROJECT. Mit SELECT IPHONE OS APPLICATION S wi rd das Symbol

Q UI CK( ONNECT IPHONE ÄPPLICATION angezeigt. Doppelklicken Sie darauf, benennen Sie Ihr

Projekts i mp l eExamp l e und wählen Sie ein Verzeichnis, in dem Sie es auf Ihrer Festplatte

unterbringen wol len, oder legen Sie eines dafür an. Xcode erstellt dann ein Projekt, das die

Obj ective-C-Dateien enthält, die erforderlich sind, um Ihre Objective-C-Anwendung direkt

ohne Netzwerk- oder Internetzugriff auf dem Gerät auszuführen. ln der Gruppe RESOU R­

CES Ihrer Anwendung finden Sie einige HTML-, CSS- und Objective-C-Piatzha lterdateien.

Eine dieser Platzhalterdateien ist i ndex. html . Sie ent hält den HTM L-, CSS- und Objective­

C-Code für eine ausführungsbereite Beispielanwendung. ln Abbildung 1-4 sehen Sie, wie

sie als insta llierte Anwendung im Simulator ausgeführt wi rd.

21

Page 23: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapite l l Entwicklung mit Dashcode und Xcode

ti Dashcode Abl.lge Bearbeiten Format Anordnen Debug Darstellung Fenster Hilfe

B tnuo2

ebwnon '2S' di~pl:.y

:~· PloQtamru.trtlbut~ :::.·.·.· ..... ~ Webc!ip-S.,."bol

I ~ . .

Otteien

js fur.ct.on!>.JS

U tmo1gcs !f. inde:x.html

.i! mappil'lg$.jS

CJ mobile

..::J irn.lges cu mo1in.cn

...,J P.uts

c:J Parh (:j QCi ••• .,.

0 · ·- 0 E::

I I

simple:Examole (Arbeitet)

inuo2 fü r Webs e.rver bQ:reltstcallen

.~1'"", _IR_~_ Zl.iltUt r;ICII'f'C)l 'I

0

Zielort ' c;;loc. lh..t ~

(!1 Slmul:thOrt cer AIJsfi:l'ltung in OO.'I"'l in : M .to n tol't.ICXJI

Opeionfl:n

Verh:.llen beim Sichern ProJakt -o c:am tk~•Uti::litft~ut ::JE Hto·.-.ne #~trn

komprlmiervng ~ J~v.JScnpt fUr schnelleren 00Wfllo.ld komprirnie rM

Ben.adtri(hllgung C E- M3II mlt Unk 2üM bereltgene!lttl\ Wtbprogt:.'llnlu'WI senden

( Auf der Fe>tplatte sichern ... ) (~ _ ____;B:..:•:..:re"'its"'te:..:lle:c:• __ _,.

~ Abbildung 1-3: Der Bereitstellungsbildschirm zeigt die Bereitstellung der fertigen Anwendung im Verzeichnis ChaptenExample auf dem Webserver.

Um die zuvor in Dashcode erstellten Dateien in diesem Projekt einzufügen, löschen Sie die

folgenden Dateien:

> i ndex.html

> ma in . css

> mai n . j s

> Dateien in der Gruppe PARTS

> Dateien in der Gruppe IMAGES

Anschließend importieren Sie die Dateien index. html , ma in . css und ma in . js. Dazu

klicken Sie bei gedrückter ~-Taste mitderrechten Maustaste aufdie Gruppe RESOURCES

und wählen Aoo_EXISTING FILES. Wechseln Sie in das Verzeichnis, in dem Sie Ihre Dashcode­

Anwendung bereitgestellt haben, und markieren Sie die Dateien i ndex . html , ma i n. css

22

Page 24: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

X-code und die benutzerdefinierte Quit kConnect-Vorlage verwenden

und ma i n . j s. Sie können sie in das Xcode-Projekt kopieren oder dort benutzen, wo sie

liegen. Aktivieren Sie f ür dieses Beispiel bei jeder Aufforderung das Kontrollkästchen CoPv

ITEMS INTO DESTINATION GROUP'S FOLDER.

~ Abbildung 1.4: Die QuickConnect-Standardanwendung

KOPI EREN ODER NICHT KOPI EREN - DAS IST H IER DIE FRAGE

Ob Sie die vorliegenden Dateien kopieren oder Xcode mit Referenzen darauf arbeiten

lassen, ist Ihre Sache. Wie entscheiden Sie sich? Beide Methoden haben ihre Vorteile.

Kopieren Sie die Dateien, ist das Projektverzeichnis vollständig und kann anderen Ent­

wicklern übergeben werden, ohne dass diese die Verzeichnisstruktur des Rechners

replizieren müssen, auf dem die Originale liegen.

Bei Verwendung von Referenzen können Sie zu Dashcode zurückkehren, um Änderun­

gen vorzunehmen, und das Projekt anschließend exportieren, um die Dateien zu über-

~hreiben. Sie brauchen sie nicht erneut in Xcode zu importieren.

Als Nächstes klicken Sie mit der rechten Maustaste auf die Gruppe PARTS und import ieren

die Dateien in den gleichnamigen Ordner. Sollte die Gruppe PARTS nicht vorhanden sein,

legen Sie diese an. Wiederholen Sie diesen Schritt f ür die Gruppe IMAGES. Nun sind Sie fast

so weit, dass Sie die Anw endung ausf ühren können.

Da Dateien in die Gruppe RESOURCES aufgenommen w urden, muss Xcode angewiesen

w erden, sie in die von der Anwendung verwendet en Ressourcen einzubinden. Erweitern

Sie die Zielauswahl (TARGETS) am unteren Bildschirmrand sowie Ihre Anwendung und das

23

Page 25: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitell Entwicklung mit Dashcode und Xcode

Listing COPY BuNDLE RESOURCES. Sie sehen jetzt die Ressourcendat eien, die Ihre Anwen­

dung braucht, um zu laufen. Markieren Sie die Dat eien (nicht die Gruppen), die Sie gerade

in Ihr Projekt aufgenommen haben, und ziehen Sie sie in das genannte Listing. Erweit ern

Sie ansch ließend die Liste CoMPILE SouRCES, und löschen Sie alle Objective-C-Dateien. Sie

werden offensicht lich nicht kompil iert. Klicken Sie dazu bei gedrückter ~-Taste mit

der rechten Maustaste darauf, und wählen Sie DELETE. Damit entfernen Sie sie aus der

Kompilierungsl iste, aber nicht aus dem Proj ekt oder von der Festplatte.

Da Dashcode Verzeichn isse verwendet, Xcode j edoch Gruppen, müssen Sie zwei weitere

Änderungen vornehmen, um Ihre Anwendung starten zu können. Die erste erfolgt im Ab­

schnitt <head> der Datei i ndex . ht ml . Da die Objective-C- und alle übrigen referenziert en

Dateien im Ressourcenverzeichnis derfertigen Anwendung liegen, müssen die Verzeichnis­

verweise auf Pa rts und OCiPhone entfernt werden. Vorher sieht ein <scr ipt>-Tag

beispielsweise folgendermaßen aus:

<scri pt t ype= "text / javascript " sr c="Parts /u t i l iti es.js" charset= "ut f - B" ><I script >

Hinterher sollte es aussehen wie folgt :

<scri pt t ype= "text / javascript " sr c="ut i l i t i es. j s" charset="utf - 8" > <l scr ipt >

tl Xcod• File Edlt View P!Oje<t Bulld RI.An Design SCM \Vindow f He!p Quld<.Connt ct t S.t 8:32 PM 0. 0 r n n R 0 0 ;~ Pu.n&uaon:., Slmpl..._,..le - ...o;.ct F;nd

Actio.oe:TUSII!t

~<M~,·~··~•g••~~=~ll· lt.~ p{'Go:. I .,. ~!!:;~~:::c:lc • 0 Display lluults ln F.ncl Sm31't Cro11p

~ 5 "nd t(louna!CIIIpg0 ., )'} P"'":~~:~Q'tl'lttlx • 'lm• u r -t Stl1t Eiemrnt.!d ,

f!] l lnP!oittt

t!.l I'"""" I Ccl!.tiWIIS

~ Sl-npifb~·~ppO .- ~ D~s~codc to Xcodt.blt

~ ==~=:~:~: U StJ.I(h 1t-.roUQn tne Pvs~6Unor.Js f'llt fc.r "11'!1iGur Ir\ l l)ti llon y;r!tt;JS

... Q OIIIH SOJrces •OA.e~o:.~rces

• CJi m;)QI!S

1:1 b~l'lll)!l_(ll(kfc:l,, ~ i:tDvMin.pn~

·o~~ ii s.ttuOJS fs' Tr.:M itioM .j:. {~ T!<'lfiS!.,O,S.C:n jfTu\Js

: I c:::J!L) IJ }·~~

' ; j g lgnorcc.ue ( <>pttons ... }~

),!. St,)~.C:UlO Ut$ ~~ l'utfiBIItlOf'l~ $ ~ lonmni-Urld!~r.J ~ l i llli.h iu h ~ ~~(f'II~I!. IXt -, ,.

llnlkd UMI ,. • li"!.uJ~~w.~~~~~=~r..h::----------=-''-'.• .:::l~illTC~· ~··~ot~ ~::~;~ ~~ ~:::::~~~:~=~~~h~:~~~::~~~:~~~~ ~~;8 ; r! ~ Mli~Vi"d::~W.lllb lO thls..topi iUI~tdtll • (I; t ij) dct•bucOd hliticfl.j) ~ tll !1t -bcltto• l~111tll · 0 ; t.--.... HI.I'I • • u tlla._QOII~o i~t .. e1 ~

fu l n(o.pllu &I II e~~ntll'> lFL oi W:Hjt'OII1!1 IOO:f"S

.,EJQCI~45

~ tlll~ •• oontoln.etn1gM • • e~ l .t) OUilCCOeiOX<Od e.O 6S t h! :S.ßUUd: ta!se;

•Cifr~·~' 0 ~:!s~j~~:~ :~::;;9; 1~'-! '~;~t. , td; .. tiiJcorteraon o.tr•Mt11 ~ tll! :~ .~n~:nelltltl ltw;J~~I'il1. = t ll ~IICf't~rtr .. ·.cH~~.rn.:l' ; •~UI<it. lrumcwotk 69 •CJ tt c~dCI!i ;o II tr""''~ "'"'ll'r.ll "~•s

.. 9roui'IC:)t $0fl.ffltl!f WOI 1l 1'61 rtyl t ;

•CJao~:~tbunp!c:.~~P " ~ .. r t h!t.J:ac:t , rOU'di tiHIO:'It- d~eu'JIQ'.t.er:.oto:.::t_.._t<•ow'>·

ts::o..lld ·~tur · l o«vrr<e~<M fourcl ·n•our - ! « OJrrl!r<ts

~ Abbildung 1-5: Der Suchbildschirm zeigt die Ergebnisse der Suche nach Images I im gesamten Projekt.

24

Page 26: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

X-code und die benutzerdefinierte QuitkConnect-Vorlage verwenden

Da für alle in Dashcode erstellen Scha ltflächen usw. Bilder benutzt werden, müssen Sie

außerdem al le Instanzen des Strings I mages / im Projekt suchen und durch leereStrings

ersetzen. Dazu gehen Sie einfach ins Menü EDIT, wählen FIND _FIND IN PROJECT und suchen

dann I mages/. Abbildung 1.51istet die Suchergebnisse für dieses Beispiel vor dem Ändern

der Datei Pus hßu t t on. j s auf.

Nun können Sie Ihre Anwendung mithilfe des Symbols BUILD AND Go installieren und ausführen, das Sie in der obersten Symbolleiste von Xcode finden. Wi rd der Feh ler »No

provisioned iPhone OS device is connected« gemeldet, können Sie die Anwendung an statt

auf Ihrem Gerät im Simulator insta llieren und ausführen. Klicken Sie auf SucCEEDED in

der rechten unteren Ecke des Xcode-Fensters, wäh len Sie die Liste DEVICE I DEBUG in der

linken oberen Ecke des Dia logfelds, das eingeblendet wird, und klicken Sie auf die Auswahl

SIMULATOR. Beachten Sie, dass Sieweiter unten in der Liste auch RELEASE oR DEBUG wäh len

können. Dieses Dialogfeld sol lten Sie im Lauf der Entwicklung häufig einsetzen, um Ände­

rungen der beschriebenen Art durchzuführen. in Abbi ldung 1.6 sehen Sie die installierte

Anwendung bei der Ausführung im Simulator.

~ Abbildung 1.6: Die Anwendung simpleExample wurde im Simulator installiert und wird dort ausgeführt.

Herzlichen Glückwunsch- Sie haben gerade Ihre erste iPhone-Hybridanwendung fertig­

gestel lt.

25

Page 27: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapite l l Entwicklung mit Dashcode und Xcode

r PROVISION ING ? WAS IST DAS?

Provisioning ist der aus mehreren Schritten bestehende Vorgang, den Sie oder jemand,

der Sie darstellt, durchführen muss, damit Sie Ihre Anwendung auf einem Gerät instal­

lieren und ausführen können.

Um Ihr iPhone entsprechend nutzen zu können, müssen Sie Mitglied der Apple Deve­

loper Connection (ADC) sein und sich fü r die Benutzung des Program Porta l registriert

haben. Sind Sie Teil eines Teams, ist das Provisioning möglicherweise bereits erledigt; in

diesem Fall brauchen Sie nur noch die betreffenden Daten auf Ihr iPhone hochzuladen.

Umfangreiche Informationen zum Provisioning finden Sie in der ADC. Achten Sie da­

rauf, alle aufgeführten Schritte durchzuführen. Jede Abweichung kann zum Fehlschlag

füh ren, was Sie daran hindert, Ihre Anwendungen auf Ihrem Gerät zu testen. _j

1.3 ERSTE EINFÜHRUNG IN ÜBJECTIVE-(

Dieser Abschnitt stellt weder ein umfassendes Objective-C-Tutorium noch eine ausführliche

Erörterung der Verwendung von Objective-C zum Schreiben von iPhone-Anwendungen

dar, sondern vermittelt Ihnen eine Vorstellung davon, wie die in den Vorlagen benutzten

Obj ect ive-C-Kiassen interagieren und sich verhalten, sodass Sie dieses Wissen in iPhone­

Hybridanwendungen nutzen können. Es wird Grundwissen über Objekt e, Methoden und

Attribut e vorausgeset zt. Wollen Sie mehr über das JavaScript-Framework wissen oder nicht s

überObjective-C-Code erfahren, können Sie den Rest dieses Kapit els überspringen und direkt

zu Kapit el 2 gehen. Einen tieferen Einblick in die iPhone-Entwicklung in Objective-C bietet

Das iPhone-Entwicklerbuch: Rezept e für Anwendungsprogrammierung mit dem iPhone

SDK von Erica Sadun.

Objective-C ist eine interessant e Sprache. Für Leser mit Kenntnissen in JavaScript, PHP,Java,

Perl oder anderen Sprachen kann sie zunächst abschreckend und unbegreiflich wi rken.

Trot zdem verdient sie einen zweiten Blick, und zwar nicht nur, weil es sich um die »native«

Sprache des iPhone handelt.

Objective-C ist eine objektorientierte Va riant e von C. Sie können damit die gesamt e leis­

tungsfahige, spannende Programmierung in der Art von C/C++ durchführen, beispielsweise

Zeigerarithmetik, sowie ein iges, was Ihr Leben vereinfacht, beispielsweise automatische Spei­

cherverwaltung. Zu den ersten Dingen, die Sie in einer objektorientierten Sprache erledigen

müssen, gehört das lnstanzi ieren eines Objekts. Steht im Obj ective-C-Quellcode ein Objekt

mitdem Namen Wirbeltiermitden beiden Attribut en nameund anza h7 BeinezurVer­

fügung, w ird es wie folgt inst anziiert:

var einWirbel t ie r = new Wirbel t i er ("Laubfrosch" , 4) ;

26

Page 28: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Erste Einführung in Objective-C

Mögl icherweise halt en Sie dies f ür normal und erwart en, dass sich andere Sprachen ge­

nauso verhalten.

Die lnstanzi ierung in Obj ective-C sieht zunächst merkwürdig aus, wenn Sie diese Erwar­

tung hegen:

Wirbel t i er *ei nWi rbel tier = [[Wirbeltier al l oc] i nitWithName: @"Laubfrosch" andAn zahl ßei ne : 4];

Einige Teile erscheinen verständl ich, andere nicht. Wenn Sie darüber nachdenken, ergibt

a 7 7 oc Sinn, weil es beschreibt, wie dem Obj ekt Wi rbe 7 t i er Platz im RAM zugewie­

sen wird. Sogar i n itWi thName und andAnz ah7 Bei ne ergeben Sinn, wei l sie die beiden

benötigten Parameter setzen bzw. übergeben. Aber was geschieht eigentlich und was

bedeuten die eckigen Klammern?

Obj ective-C benutzt für alle Interaktionen mit Objekten und anderen Elementen, die in

anderen Sprachen im Unterschied zu Obj ective-C möglicherweise keine Obj ekte sind,

Meldungsübergabe (Nachrichten). Betrachten Sie die folgende Codezeile:

[W i rbel tier al l oc]

Es wurde bereits erwähnt, dass in diesem Codefragment einem Objekt mit dem Typ

Wi rbe 7 tierPlatz im RAM zugewiesen wird. Die eckigen Klammern um Wi rbe 7 tierund

a 7 7 oc geben an, dass das Obj ekt in der Anwendung, das f ür die Klasse Wi rbe 7 t i er steht,

die Meldung a 7 7 oc erha lten soll. Das Codef ragment ist folgendermaßen zu lesen: »Über­gib dem Objekt der Klasse Wi rbe 7 tiereine al/oc-Me/dung.« Das Ergebnis der Übergabe

dieser a 7 7 oc-Meldung an das Obj ekt der Klasse Wi rbe 7 ti er ist, dass ein Zeiger auf ein

neues Wi rbe 7 ti er-Objekt zurückgegeben wird.

r ZE IG ER? WAS IST DAS?

Zeiger sind interessant. Viele haben Angst davor, weil sie sie nicht verstehen oder nicht

wissen, worum es sich handelt.

Um sie zu verstehen, hier eine Ana logie: Stellen Sie sich eine große Menschenmenge

vor, darunter Alma und John. Sie kennen sich, und Alma weiß, wo sich John in der Men­

ge befindet. Sie nähern sich Alma und fragen sie, wo John ist. Sie zeigt mit dem Finger auf ihn und sagt: »Dort.«

ln diesem Augenblick ist Alma ein Zeiger auf John. Wenn Sie sich einen Zeiger als etwas

vorstellen, das weiß, an welcher Stelle im Speicher sich ein Obj ekt befindet, haben Sie l es verstanden.

27

Page 29: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitell Entwicklung mit Dashcode und Xcode

Diesem neu inst anziiert en Wi rbe 7 t i er-Obj ekt können dann Meldungen übergeben wer­

den. Der vorstehende Codeausschnitt ent hält eine weit ere Meldung f ür das Obj ekt .

Sie best eht aus der Kombination i nitWithName und andAnzahlBeine. Dass es sich bei

dieser zweiteiligen Meldung um eine Meldung handelt, erkennen Sie daran, dass die Teile

und das neue Objekt gemeinsam von eckigen Klammern umschlossen sind, was angibt,

dass eine Meldung übergeben wird. Mehrteilige Meldungen werden durch Leerzeichen

getrennt, d.h., zwischen den beiden Teilen der Meldung steht ein Leerzeichen.

Außerdem sind die Meldungsteile und die damit übergebenen Wert e durch den Doppel­

punkt ( :)verbunden. Jeder Meldungst eil kann mit maximal einem Parameter verknüpft

sein. Diese Meldung gibt einen Zeiger auf das neu zugewiesene Wi rbe 7 ti er-Obj ekt zu­

rück, sodass es lokal zur späteren Benut zung gespeichert werden kann. ln Objective-C

werden diese Meldungsindikatoren sowohl f ür ein- als auch f ür mehrteilige Meldungen

als Selektoren bezeichnet, weil sie angeben, welche Met hoden des Obj ekt s der Compiler

auswählt und ausführt.

Keh ren Sie zu dem Xcode-Proj ekt Si mp l eExamp l e zurück, das Sie in Abschn itt 2 ange­

legt haben. Sehen Sie sich die Methode appl i cat i onDi dFi ni sh l aunchi ng in der Datei

Si mp l eExamp l eAppDe l ega te . man, die die Vorlage erstellt hat. Kümmern Sie sich nicht

darum, was der Code macht, sondern betrachten Sie ihn als Beispiel für Meldungsüber­

gabe.

1 - Cv oid) appl icationDi dFi ni sh l aunchi ng : CUIAppl icati on *) appl icati on {

2 II Fol gendes hi l ft bei der Feh l ers uche , sodass Sie " genau " wissen , wo I hre Ansichten pl atzi ert wer den ;

3 II sehen Sie "rot " , handel t es sich um das l eer e Fens t er . 4 llwindow. backg roundCol or = [ UICol or redCo l or ] ; 5 6 OuickConnectVi ewCon t roll er * aßrowserViewCont roll er= 7 [ [QuickConnectViewControl l er al l oc ]

i nit];

8 9 II dem Fens t er di e Ansicht Cr eateViewCont r ol l er al s

II Unt eransich t hi nzufügen 10 [window addSubview: aßrowserViewContr ol l er . view] ; 11 12 [window makeKeyAndVis i bl e ] ; 13

28

Page 30: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Struktur wn QuickConnectiPhone-Anwendungen in Objective-C

Zei le 8 sollte vertraut aussehen. ln diesem Fall wi rd kein Wi rbeltier erstellt, sondern ein

sogenannter OuickConnectViewControl lerzugewiesen und initia lisiert. Der Ausdruck

verwendet a ll oc- und i n it-Meldungen, wie Sie sie vorhin gesehen haben. Der Klasse

wird die a l l oc-Meldung übergeben, die einen Zeiger auf das neu zugewiesene Oui ck­

ConnectViewControl ler-Objekt zurückgibt. An dieses neue Objekt wird über seinen

Zeiger die i ni t -Meldung gesendet.

Diese Meldung vollzieht dasselbe wie die mehrteilige Meldung i ni tWi thName:

andAnzah l Bei ne des Wi rbe 7 t i er-Objekts, ist j edoch wesentlich einfacher. Es handelt

sich nämlich um eine einteilige Meldung ohne Parameter. Weiter hinten in diesem Kapitel

erfahren Sie, wie lnitia lisierungs- und andere Methoden geschrieben werden, sodass Ihre

Objekte sie ausführen können, wenn sie eine Meldung erhalten.

Zei le 11 sendet eine Meldung an das wi ndow. Diese Meldung, addSubVi ew, ist mit einem

Parameter versehen, dem im Objekt a Br owser Vi ewContr o ll er enthaltenen vi ew­

Attribut.

Sie haben damit ein einsetzbares Beispiel dafür gesehen, wie ein Obj ekt instanziiert, wie

ein Zeiger mit lokaler Gültigkeit auf dieses neue Objekt gespeichert, wie auf die Attribute

eines Objekts zugegriffen w ird und w ie Meldungen mit und ohne Parameter an Objekte

übergeben werden. Das ist der größte Teil der Obj ective-C-Grundlagen, die Sie kennen

müssen, um den Code in den QuickConnectiPhoneVorlagendateien zu verstehen. Als

Nächstes sollen Sie erfahren, wie Obj ective-C-Anwendungen aufgebaut werden.

1.4 DIE STRUKTUR VON QUICK(ONNECTIPHONE­

ÄNWENDUNGEN IN ÜBJECTIVE-(

ln diesem Abschnitt geht es zwar um den grundlegenden Code in der Vorlage für

QuickConnectiPhone-Anwendungen, in allen anderen Implementierungen von Hybrid­

anwendungen wird jedoch derselbe Ansatz verwendet. Sie können eine der vorhandenen

Implementierungen benutzen oder nach deren Studium eigene Versionen erstellen.

Stellen Sie sich vor, Sie besitzen eine Menge Antei le einer erfolgreichen Fi rma, was mög­

licherweise zutrifft. Auf einer Aktionärsversammlung soll der Vorsitzende des Aufsichts­

rats gewählt werden, aber Sie können nicht teilnehmen, wei l Sie gerade Urlaub auf den

Bahamas machen. Wie können Sie dennoch Ihre Stimme abgeben?

Beauftragen Sie j emanden, f ür Sie abzustimmen, wird diese Person als Ihr Stellvertreter

bezeichnet. Er besitzt die voll ständige Vollmacht, auf der Versammlung in Ihrem Namen

zu handeln. Er könnte auch als Ihr Delegat bezeichnet werden. Dieser Delegat würde Sie

seinen Prinzipal nennen, weil Sie der eigentliche Aktionär sind. Abbildung 1.7 veranschau-

29

Page 31: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitell Entwicklung mit Dashcode und Xcode

licht diese Beziehung. iPhone-Anwendungen in Obj ective-C verwenden Prinzipal-Delegat­

Beziehungen zwischen Objekten, bei denen das eine der Prinzipal und das andere der

Delegat ist.

.,. Abbildung 7.7: Die grafische Darstellung zeigt, Prinzipal dass ein Prinzipal einen Delegaten und ein Delegat

einen Prinzipal hat.

iPhone-Anwendungen in Objective-C verwenden diese Prinzipal-Delegat-Beziehung häufig.

Folgende Beziehungen sind besonders interessant:

> UIApplication/UIApplicationDelegate

> UIWebView/UIWebViewDelegate

> UIAccelerometer /U IAccelerometerDelegate

An dieser Stelle müssen Sie wissen, dass die Implementierung von Protokollmethoden f ür

diese Delegaten Ihrer Anwendung, Ihrer Ansicht oder Ihrem Accelerometer mittei lt, dass

nicht Sie selbst, sondern der Delegat bestimmte Ereignisse behandeln soll, wenn sie ein­

treten. Jede Protokollmethode ist mit einem bestimmten Ereignis verknüpft.

PROTOKOLLE

Ein Protokoll ist eine Folge von Methoden, die einer Klasse hinzugefügt werden kann,

damit sie auf bestimmte Meldungen reagiert.

Vor dem Hintergrund dieses Prinzipal-Delegat-Konzepts werfen Sie jetzt einen Blick auf

eine Klasse, die ein Delegat ist. Es folgt die Headerdatei für die Klasse Simpl eExampl e­

AppDe 1 ega t e, die angelegt wurde, als Sie in Abschnitt 2 die QuickConnectiPhone-Vorlage

verwendet und die Anwendung Si mp 1 eExampl e erstellt haben.

Objective-C-Headerdateien enden auf . h und deklarieren Klassen. Sehen Sie sich die

Headerdatei fü r die Klasse Si mp 1 eExamp 1 eAppDe l egate an, machen Sie sich aber keine

Gedanken über ihre lmplementierungsdatei:

1 //S i mpleExamp1eAppDe1egate.h 2 #import <U I Kit/ UIKit.h> 3 #import QuickConnectViewCon t ro1 1er.h " 4 5 @interface Simpl eExamp1eAppDelegate

<U I App l i cat i onDe1egate>

30

NSObject

Page 32: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Struktur wn QuickConnectiPhone-Anwendungen in Objective-C

6 7 I BOutlet UIWi ndow * wi ndow: 8 Qui ckConnect ViewController * browserVi ewCont r oller: 9 10 11 @property (nonatomic, r etai n ) UIWindow * wi ndow: 12 @property ( nonatomi c , ret ai n ) Qui ckConnectViewContro l l er

* browserViewControl l er; 13 14 @end

Betrachten Sie Zeile 5· Wenn Sie mit Java vertraut sind, lassen Sie sich nicht durch den

Indikator @i nt erfa ce in die Irre führen. Er bedeutet nicht, dass diese Klasse einer Java­

Schnittstel le entspricht, sondern dass die Datei die Schnittstellendefinition f ür diese Klas­

se ent hält . Die Headerdatei deklariert, welche Attribut e Si mp l eExamp l eAppDe l egate

hat, wie darauf zugegriffen w ird und welche Met hoden in der separaten Implementie­

rungsdat ei ent halten sein sollen. Diese Klasse besitzt keine eigenen Methoden.

Was macht Zei le 5 denn nun, wenn es sich nicht um eine Schnittstellendefin it ion in Java­

Manier handelt? Sie deklariert den Namen der Klasse, nämlich Si mpl e Examp l eApp ­

Oe l egate, und gibt mithilfe des Doppelpunkts als Trennzeichens an, dass sie von der Klas­

se NSObj ect erbt. Deshalb handelt es sich um ein Obj ekt von NSObject und kann allevon

NSObject defin ierten Meldungen entgegennehmen. Wenn Sie sich die Klasse NSObj ect

in der API-Dokumentat ion im Xcode-Hilfemenü anschauen, sehen Sie, dass sie eine Me·

thode desc ri pt i on besitzt . Wei l Si mpl e Examp l eAppDe l egate durch Vererbung ein Ob­

j ekt von NSObj ect ist, besit zt sie also auch eine Methode descri pti on.

Im Ansch luss an die Deklaration der Vererbung von NSObject lesen Sie <UI Appl ica ­

t i onDe legate>. Dies weist die Klasse Si mpl eExampl eAppDel egate an, sich als

Delegat fü r Ihre Anwendung zu verha lten, und gibt Ihnen die Möglichkeit, die Metho­

den der U I App l i cat i onDe l egate-Prot okol lmeldungen in der Implementierungsdatei von Si mpl eExampl eAppDel egate umzuset zen. Eine davon ist appl icationDid ­

Fi ni shl aunchi ng.

Diese Methode wird aufgerufen, soba ld die Anwendung vollst ändig geladen und st art ­

bereit ist . Sie ermöglicht Ihnen, Ihre Anwendung anzupassen oder den Benut zer bei Be­

darf um weitere Informationen zu bitten.

Zei le 11 im folgenden Code ent hält die QuickConnectiPhone-Definition von app l i ca ­

ti onDi dFi ni sh l aunchi ng in der lmplementierungsdatei. Sie beginnt mit einem M inuszeichen (-),das besagt, dass es sich um eine Obj ekt met hode handelt . ( voi d) be­

deutet, dass die Methode nichts zurückgibt, und : ( U IApp l i cat i on *) gibt an, dass der

Methode ein Parameter des Typs U IApp l i cat i onübergeben w ird.

31

Page 33: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitell Entwicklung mit Dashcode und Xcode

1 II 2 II Simpl eExampleAppDelegate .m 3 II Simpl eExample 4 II 5 #import "SimpleExampleAp pDelegate . h" 6 @impl ementation SimpleExampl eAppDel egate 7 8 @synthesize window: 9 @synthesize browse rViewControll er: 10 11 - Cvoid) appl icationDi dFin ish l aunching:CUIApplication *)

applica t ion { 12 II Dies hi lft bei de r Feh l ersuche, sodass 13 II Sie "genau " wissen, wo Ihre Ansichten pl aziert werden; 14 II sehen Sie "rot " , schauen Sie das l eere Fenster an, 15 II in Ih ren vertei l ten Anwendungen 16 II benutzen Sie Schwarz 17 II window. backgroundColo r = [UICol or redCol or]: 18 19 QuickConnectViewControl l er *aßrowserV iewController=

[[QuickConnectViewControl l er al loc] i nit ] ; 20 II dem Fenster die Ansicht aßrowserViewCont rol l er 21 II al s Unteransicht hinzufügen 22 [window addSubview:aßrowse rViewContro l l er.view]; 23 [window ma keKeyAndVisibl e]; 24

Diese Methode app l i cat i onDi d Fi nish Launch i ng wi rd als Teil der Delegatklasse für Ihre Anwendung automatisch aufgerufen, wenn die Anwendungfertig geladen ist. Deshalb kann sie dazu verwendet werden, andere Elemente zu instanziieren, die möglicherweise in der Anwend ung benötigt werden. in diesem Fa ll sehen Sie in Zei le 19 die Zuweisung und lnitia lisierung der anderen Klasse (Oui c kConnect Vi ewCont roll e r), die durch QuickCon­nect-Vorlage in Ihre Anwendung integriert wurde.

iPhone-Anwendungen sind ansichtsbasiert, und jedes Objekt von U I Wi ndow oder U IVi ew ka nn U I Vi ew-Objekte ent halten. Deshalb ist es möglich, eine Ansicht in einer Ansicht un­terzubringen. Von einer derart igen Gestaltung ist fü r iPhone-Anwendungen jedoch abzu-

32

Page 34: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Webinhalt einbetten: QuickConnectiPhone

raten. Anstelle dieses hierarchischen Ansatzes tauscht die Entwicklergemeinde meistens

nach Bedarf des Benutzers auf möglichst hoher Ebene untergeordnete Ansichten gegen­

einander aus.

Außerdem führt der Austausch von Unteransichten zu einer flacheren, wen iger komple­

xen Ansichtenstruktur in Ihrer Anwendung. Dankenswerterweise hat die Vorlage, die Sie

zum Erstellen der Anwendung benutzt haben, genau die richtige Anzahl von Ansichten

innerhalb von Ansichten untergebracht, damit Sie Ihren Webinhalt darstellen können. Wie

Sie später sehen, ist in der Ansicht, die gerade in das Fensterobjekt eingefügt wurde, eine Web-Unteransieht enthalten.

Die Klasse Qu i c kConnectV i ewCon t r o 11 er enthält das eigentliche Ansichtsobjekt, das

Ihren Inhalt als eines seiner Attribute im Fenster Ihrer Anwendung anzeigt. Dieses Attribut

muss dem Hauptfenster als Unteransicht hinzugef ügt werden, was in Zeile 22 geschieht.

Die Klasse Qu i ckConnectVi ewCon t r ol l er enthält nicht nur die lnhaltsansicht, son­

dern ist außerdem ein Delegat fü r die GPS-Orts-, Accelerometer-, WebView- und andere

Ereignisa rten.

1.5 WEBINHALT EINBETTEN: QUICK(ONNECTIPHONE

Um in Ihrer Anwendung Webinhalt w ie Objective-C-Anwendungen oder einfache Web­

seiten anzuzeigen, müssen Sie die Klasse U I WebVi ew benutzen. Alle Implementierungen

von Hybrida nwendu ngen, a I so auch QuickCon nectiPhone, verwenden diese Klasse. Wollen

Sie in einer Anwendung ein toll es Schriftsteuerelement haben -d.h. mehrere Schriftarten und/oder Größen und Farben -, müssen Sie mit U IWebVi ew arbeiten oder den Text mit viel

Mühe selbst zeichnen. Die Klasse U IWebVi ew bietet den wesentlich einfacheren Weg, weil

sie außer Obj ective-C auch HTML und CSS interpretiert, was Ihnen die Möglichkeit gibt,

komplexe Text- und sonstige Layouts zu erstellen.

Die Klasse U IWebV i ew ist eigentlich ein Wrapperfür die Darstellu ng durch das WebKit, der

von dem Safari-Browser, Adobe Air-, Android- und Nokia-Telefonen sowie einigen anderen

Anwendungen benutzt wird, darunter die zu OS X gehörenden w ie Mail. Auch Dashcode

verwendet das WebKit-Modul in großem Umfang.

Wie in den beiden vorhergehenden Abschnitten erwähnt, muss das U I WebVi ew-Obj ekt

einer anderen Ansicht in der Anwendung als Unteransicht hinzugef ügt werden, um eine

Webansicht in die Anwendung einzubinden. Dazu dient die Methode l oadVi ew der Klasse

QuickConnectVi ewCont r oll er.

33

Page 35: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel l Entwicklung mit Dashcode und Xcode

Diese Methode enthält eine Reihe von Elementen, die es ermöglichen, in einer auf Objec­

tive-C basierenden Anwendung Verhaltenweisen auszudrücken. Dazu gehört beispiels­

weise der Code, der die Benutzeroberfläche Ihrer Anwendung auf Bi ldschi rmgröße skaliert.

Diese Fähigkeit ist standardmäßig auskommentiert, weil die Benutzeroberfläche so ge­

staltet werden sollte, dass sie auf den Bildschirm passt.

Der interessante Teil von l oadVi ew ermöglicht die Anzeige der Oberfläche, die Sie weiter

vorn in diesem Kapitel in Dashcode erstellt haben. Der folgende Codeausschnitt zeigt, wie

das iPhone diesen Inhalt in die Anwendung einfügt. Er beginnt mit der Berechnung von

Größe und Ursprung für die Anzeige des UI WebVi ew-Objekts. Dazu fragt er Größe und

Position des Anzeigerahmens der Anwendung ab.

Diese Informationen stehen in der als webFramebezeichneten Struktur CGRect, die durch

Senden der Meldung app l i cati on Frame an den Hauptbildschirm der Anwendung er­

stellt wird. Sämtliche CGRect-Strukturen bestehen aus zwei Elementen: einem Ursprung

mit dem Namen CG Po i nt, der die x-und die y-Koord inate der linken oberen Ecke angibt,

und der Angabe CGS i ze mit der Größe des Rechtecks in Höhe und Breite:

CGRect webFrame = [ [U I Screen mainScreen] app l i ca t ion Frame]; webFrame .or igi n.y -= 20 .0:

x- und y-Koordinate, Breite und Höhe einer CGRect-Strukt ur sind Fließkommazahlen, die

Pixelwerte aufnehmen. Die zweite Zeile des vorstehenden Codes zeigt, wie der aktuelle in

derVariablen web Fra me gespeicherte Wert f ür die senkrechte Position geändert w ird. Sie

versch iebt den Ursprung um 20 Pixel nach oben, was erforderlich ist, um den in der Ansicht

vorhandenen Leerraum für eine nicht vorhandene Werkzeugleiste oben im Anzeigefenster

zu überdecken.

Diese Werkzeugleiste ist in zah lreichen St andardanwendungen zu finden, beispielsweise

in Einstellungen, mit denen Sie Ihre Wi-Fi-Verbindungen konfigurieren. Sie wurde aus den

Vorlagen entfernt, um den beschränkten Bi ldschirmplatz für die Anwendung bestmögl ich

nutzen zu können. Hätten Sie gern, dass diese Leiste als Navigationsleiste das Vor- und

Zurückverhalten aufweist, sollten Sie dies mithilfe von Dashcode als Tei l ihrer Anwendung

real isieren.

Stehen die gewünschte Position und Größe für die Anzeige Ihres Webinha lts in der Varia­

blen web Frame, können Sie damit ein U I WebVi ew-Obj ekt mit dem Namen aWebVi ew ini­

t ialisieren (siehe Zeile 1 und 2 des folgenden Codes). Beachten Sie die Ähnlichkeit mit der

Zuweisung an Quic kConnec t Vi ewControll er, die Sie weiter vorn in diesem Kapitel

34

Page 36: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Webinhalt einbetten: QuickConnectiPhone

untersucht haben. Die wesentlichen Unterschiede liegen darin, dass die a l l oc-Meldung

an die Klasse UI WebVi ew gesendet wird und dass das UI WebVi ew-Objekt, das gerade

eine Zuweisung erha lten hat, die Meldung i ni tW i thFrame empfängt und die Struktur

web Frame erhält, die im vorigen Codeausschnitt erstellt und geändert wurde. Das Objekt

aWebV i ew wird entsprechend den Positions- und Größenwerten in webFrame angelegt:

1 UIWebV iew * aWebView = [ [ UIWebView alloc ] 2 i nitWithFrame:webFrameJ: 3 self .webView = aWebView : 4 aWebVi ew.autoresizesSubv i ews = YES: 5 aWebVi ew.autoresiz i ngMask=( UIV iewAutoresi zi ngFlexi bleHeight 6 1 UIV iewAutoresi zingFlex i bleWi dth); 7 //den webV i ew- Delega ten für die Webans icht au f sich se l bs t setzen 8 [ aWebView setDel egate:sel f ] ;

Mit dem Code in Zei le 3 wird das neue U IWebVi ew-Objekt im Attribut webVi ew der Klas­

se Qu i c kconnectWebVi ewCont r ol l e r gespeichert, sodass andere Methoden der Klasse

später daraufzugreifen können. Das wird bei Verwendung der in Kapitel4, »GPS, Beschleu­

nigung und andere native Funktionen mit QuickConnect«, beschriebenen Fähigkeiten zur

Besch leunigung, GPS-Lokalisierung usw. wichtig.

Zei le 5 und 6 geben an, wie viel Flexibi lität das Objekt aWebVi ew besitzt, um sich selbst

neu zu zeichnen. Vermeiden Sie es nach Möglichkeit, Unteransichten hinzuzufügen. Zeile

4 besagt, dass sich die Größe von Unteransichten gemeinsam mit der von aWebVi ew än­

dert. Wenn sich die Breite von aWebVi ew aufgrundeiner Drehung ändert, soll sich somit

die Breite aller Unteransichten um denselben Skalierungsfaktor ändern.

Zei le 5 und 6 besagen, dass sich auch Breite und Höhe von aWebVi ew ändern. Wenn das

iPhone gedreht wird, ist es üblich, dass die aktuelle Ansicht ins oder aus dem Querformat

wechselt und sich an die neue Breite und Höhe anpasst, die das Gerät hergibt. Werden

die beiden Zei len entfernt oder auskommentiert, wird die Anwendung trotzdem gedreht,

aber Breite und Höhe von aWebVi ew bleiben bestehen. Dadurch erscheint im Querformat

rechts von den Anwendungen ein großer Leerraum. Sie sollten äußerst selten zu lassen,

dass die Ansicht Ihrer Anwendung ohne Größenanpassung gedreht wird.

Zei le 8 des vorstehenden Codes sendet aWebVi ew eine Meldung, dass das aktuelle

Qu i ckConnect Vi ewCont roll er-Objekt se l f als Delegat des Objekts aWebVi ewfungiert.

Dies ermöglicht die Implementierung mehrerer optionaler Methoden von UIWebView-

35

Page 37: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitell Entwicklung mit Dashcode und Xcode

Oe l egate in der Klasse Qu i c kConnect Vi ewContro ll er. ln Tabelle 1.1 sind diese Metho­

den zusammengestellt.

Fügen Sie der Klasse Qui c kConnectVi ewCont ro l l er bei Bedarf beliebige dieser optiona­

len Methoden hinzu.ln derVorlagesind bereitswebVi ew: s hou l dSta r tloadWi t h Reques t,

webV i ew:DidStartload, webV i ew:Did Fi ni shl oad und webView :d i dFail l oad­

Wi th Error enthalten.

Nach der Vorbereitung von aWebVi ew müssen Sie jetzt angeben, welcher Inhalt geladen

werden soll, und dann den Ladevorgang auslösen. Dazu muss der Speicherort der Datei

i ndex . htm l in den Ressourcen der Anwendung ermittelt werden. Glücklicherweise ver­

fügt die Klasse NSBundl e, die Ihre Anwendung auf der Festplatte des Gerätes repräsen­

tiert, über die Methode pathForResource: ofType, wie Sie in Zeile 3 und 4 des folgenden

Codeausschnitts sehen.

Die Methode path ForRes ource : ofTy pe übernimmt als Parameter zwei Strings. Der ers­

t e ist der Name der Datei, der als index des Strings gezeigt wi rd, der zweite die Erweite­

rung html des Dateinamens. Als Ergebnis dieses Methodenaufrufs wi rd ein vollständiger Pfad zu der Datei auf Ihrem iPhone erstellt und in der lokalen Variablen fi l ePa t hst ri ng

abgelegt. Anschließend kann aus dem String ein Objekt erstellt werden, das den URL zu

der Datei darstellt, sowie das Objekt aRequest der Klasse NSURLRequest, das für das zu

ladende Element steht (siehe Zeile 7 und 8).

1 //den Pfa d der Datei i ndex . html fi l e im 2 //Verzeichnis Resources ermitteln 3 NSString *f i l ePathStr i ng = [ [ NSBund l e mainßundl e] 4 path Fo r Resource :@"i ndex " ofType:@" html " ]; 5 //den URL und die Anforderung für di e Datei i ndex.html erstell en 6 NSURL *aURL = [ NSURL f i l eURLWith Pat h: fi l ePat hStr i ng ]; 7 NSURLRequest *aRequest = [ NSURLRequest 8 requestWithURL: aURL]; 9 //die Datei i ndex. html in die Webans icht l aden 10 [ aWebVi ew l oadRequest:aRequest]; 11 //die Webansicht i n die I nha l tsans i cht einfügen 12 [ contentView addSubv i ew:aWebVi ew];

36

Page 38: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Webinhalt einbetten: QuickConnectiPhone

Methodensignatur Zeitpunkt des Aufrufs Parameter

- ( BOO L)webVi ew: Direkt bevor die webVi ew- die Ansicht,

CU IWebView *) webView Ansicht beginnt, die im Begriff ist, Inhalt

shouldStartloadWithRequest: Inhalt zu laden zu laden

CNSURLRequest *) request request- der

nav igat ionType: Speicherort des zu

CU IWebViewNav igationType) ladenden Inhalts

nav igat ionType na vi gat ionType-der

Typ der Benutzeraktion,

die das Laden der Seite

auslöst

Optionen für

UIWebViewNaviga -

t i onType-

Li nkCl i cked,

FormSubmit ted,

BackForward, Re l oad,

FormResubmitted

und Other

- Cvoid)webViewDidStart Load: Nachdem die webVi ew- die Ansicht,

CU I WebView *) webView Ansicht begonnen die den Inhalt lädt

hat, Inhalt zu laden

- Cvoid)webViewDidFinishload: Nachdem die Ansicht webVi ew- die Ansicht,

CU I WebView *) webView den Ladevorgang die den Inhalt lädt

erfolgreich

abgesch lossen hat

- Cvoid)webView: Wenn das Laden von webVi ew- die Ansicht,

CU I WebView *) webView Inhalt feh lsch lägt die versucht, den Inhalt

didFai l loadWith Error: zu laden

CNSError *) error Error- ein Fehlerob-

jekt, das für den aufge-

tretenen Fehler steht

Tabelle 1.1: Delegaten der U/WebView-API

37

Page 39: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel l Entwicklung mit Dashcode und Xcode

in Zeile 6 w ird dem NSURL-Objekt die Meldung fi l eURLWi thPath übergeben. Da eine

Datei direkt von der Festplatte geladen wird, ist dies die passende Meldung. Es ist das

Einzige, was für QuickConnectiPhone-Hybridanwendungen benötigt wird. Verwenden Sie

j edoch eine andere Implementierung und laden eine Seite direkt aus dem Web, heißt die

Meldung URLWithStri ng. Sie wird mit einem vollständigen URL als Parameter überge­

ben, etwa http://www.mobile-dev.de.

Nachdem das NSURLRequest-Objekt vol lständig erstellt ist, w ird das eigentliche Laden

des angeforderten URLs ausgelöst, indem die Meldung l oadReques t an das U IWebVi ew­

Objekt aWebVi ew gesendet wird. Als einziger Parameter dieser Meldung wird das NSURL­

Request-Objekt aReques t übergeben.

Nachdem eine Anforderung geladen wurde, wird aWebVi ew in das Hauptinhaltsfenster

eingefügt, indem diesem die Meldung addSubvi ew mit dem U IWebVi ew-Objekt als Pa ra­

meter gesendet wi rd. Geschieht dies nicht, w ird die Seite geladen und ist vollständig aktiv,

w ird jedoch nicht angezeigt.

1.6 ZUSAMMENFASSUNG

Um iPhone-Hybridanwendungen zu schreiben, benötigen Sie einen kleinen Obj ective-C­

Wrapper für Ihre aus HTML, CSS und JavaScript bestehende Anwendung. Dashcode ist ein

leistungsfähiges Werkzeug, mit dem Sie schnell und einfach dynamische Objective-C-An­

wendungen erstellen können, die sich mithilfe eines solchen Wrappers einbetten lassen.

Die QuickConnect iPhone-Anwendungsvorlagen f ür Dashcode und Xcode beschleunigen

die Entwicklung von Anwendungen, indem sie den sich w iederholenden Code, der in

Hybridanwendungen benutzt wird, in Ihr Proj ekt einbinden. Wie die Kapitel 3, 4, 5, 6 und

7 zeigen, stellen die Xcode-Vorlagen den Objective-C- und den JavaScript -Code bereit, den

Sie fü r Hybridanwendungen mit Objective-C-Zugriff auffolgende Dinge brauchen:

38

Page 40: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Zusammenfassung

1.6.1 QuickConnectiPhone

> Accelerometerdaten

> GPS-Ortsdaten

> Gerätevibration

> Benutzerdefinierte Systemtöne

> Audioaufzeichnung und -Wiedergabe

> Anzeige von Standardpickern für Datum und Datum/Uhrzeit

> SQLite-Zugriff während der Ausführung der Anwendung auf die Datenbanken, die

mit Ihrer Anwendung ausgeliefert werden, und diejenigen im UI We bVi ew-Objekt

M it den Dashcode- und Xcode-Vorlagen können Sie Anwendungen f ür das iPhone schnel­

ler erstellen als j emals zuvor.

39

Page 41: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 42: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

JavaScript-Modularität und iPhone-Anwend ungen

Beim Programmieren in JavaScript fallen einem normalerweise zwei Wendungen ein:

browserübergreifende Kompat ibilität und Komplexität. Dieses Kapitel zeigt Ihnen, w ie Sie

in iPhone-Hybridanwendungen Komplexität vermeiden, und gibt Ihnen Quellcode an die

Hand, der komplexe Verhaltensweisen schnell und einfach umsetzt, ohne die Flexibil ität

zu opfern. Bei iPhone-Web-Apps brauchen Sie sich keine Gedanken über browserüber­

greifende Kompatibi lität zu machen, weil nur das Safari-Modul WebKit verwendet wi rd.

Das vereinfacht es sogar, interessante und zufriedenstellende JavaScript-Anwendungen

zu schreiben.

2.1 MODU LARITÄT

Das Konzept der Modularität gibt es sowohl in den IT-Branchen als auch in anderen schon

lange. Das Wesen des Konzepts gibt die Wendung »Erstellung aus austauschbaren Teilen«

wieder. Handelt es sich dabei um wi rklich austauschbare Module, müssen sie einander

ohne oder nahezu ohne Änderungen an den Elementen ersetzen können, die mit ihnen zusammenarbeiten. ln Programmen ist dies normalerweise eine gemeinsame definierte

API, die sich nicht ändert.

Page 43: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

Die Unterhaltungsbranche sähe chaot isch aus, wenn jeder Fi lm auf einem anderen Medium

produziert würde, weil dann für jeden ein anderer Projektor benötigt würde. Standardisier­

te ein Autohersteller die Verbindung seiner Motoren mit dem Getriebe nicht, müsste jede Motor-Getriebe-Kombination von Hand entworfen werden. Die Kosten schnellten raketen­

artig in die Höhe, und die Qualität könnte leicht zusammenbrechen.ln der Softwarebranche

hat es zah lreiche Versuche gegeben, modularen, wiederverwendbaren Code zu schreiben.

Heute werden diese als Framewerks bezeichnet.

r MODULDEFINITION

Ein Modul muss zwei Charakteristika erfüllen: engen Zusammenhalt und lose Kopplung.

Enger Zusammenhalt bedeutet, dass das modulare Element eine klar defin ierte Rolle

spielt und alles Notwendige tut, um diese auszufüllen. Es hat einen Existenzzweck und

handelt danach, erledigt beispielsweise eine bestimmte Aktivität.

Lose Kopplung bedeutet, dass das Modul nicht darauf angewiesen ist, die interne

Funktionsweise anderer Module zu kennen, und dass andere Module seine interne

Funktionsweise ebenfalls nicht kennen. Dazu ist es notwendig, eine leistungsfähige

Schnittstelle zu erstellen und zu benutzen.

Sind diese beiden Charakteristika erreicht, ist ein Modul geboren.

Ein Steak ist ein Modul, Spaghetti dagegen nicht.

Framewerks sind interessant zu untersuchen. Normalerweise besteht bei ihnen ein Kom­

promiss zwischen der Leichtigkeit der Verwendung und der Flexibi lität. Arbeitet der Ent­

w ickler des Framewerks nicht sorgfä ltig, kann er die Erledigung unw icht iger Dinge mit

dem Framewerk einfach, die Erled igung dessen, was der Entwickler oder Programmierer

braucht,jedoch schwierig machen.

Häufig wi rd beim Versuch, ein Framewerk einfach einsetzbar und flexibel zu gesta lten,

die Ska lierbarkeit der Ausf ührung geopfert, was bei Ruby on Rails der Fall ist. Es lässt sich

w underbar einsetzen, aber nicht auf Unternehmensgrößen mit großen Hardwaremengen

in Clustern skalieren, was die Supportfäh igkeit reduziert und den Aufwand erhöht . Wie kann ein Framewerk also skalierbar, einfach einset zbar und flexibel gestaltet werden? Die

Antwort liegt in gut angewandter und hoch ausgereifter Modularität.

Bestimmte Arten von Modulen tragen, auch wenn dies normalerweise weder gelehrt noch

hervorgehoben wi rd, zurVereinfachungder Softwareentwicklung bei. Diese in gewisser Wei­

se geheimen Module werden als Frontcontroller und Anwendungscontroller bezeichnet.

Die Beispiele in diesem Kapitel zeigen Ihnen, w ie Sie sie schreiben und einsetzen und w ie

sie die Erstellung von Anwendungen einfacher und schneller machen können.

42

Page 44: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das JavaScript-Framework von QuickConnectiPhone

2.2 DAS JAVASCRIPT-FRAMEWORK VON QUICK(ONNECT­

IPHONE- EIN BEISPIEL FÜR MODULARITÄT

Das JavaScript-Framework in den Dashcode- und Xcode-Vorlagen ist so gestaltet, dass es

die Prozessor- und Speichernutzung minimiert, aber dennoch einfach einsetzbar bleibt.

Da es hochgradig modular ist, erledigt jede Komponente eine bestimmte Sache, und zwar

gut und schnel l.

Die Gesta ltung beruht auf einem Paradigma von Befehl und Reaktion. Senden Sie einen

Befehl, führen die Module die notwendigen, mit diesem verknüpften Funktionen aus. Ab­

bi ldung 2.1 zeigt den Fluss der Verarbeitung durch eine Anwendung auf der Grundlage

dieses Entwurfsansatzes. Die Verarbeitung beginnt mit Schritt 1 und folgt den numme­

rierten Pfeilen durch das Framework.

Validierungs­steuerfunktion

I Anforderung

~ Frontcontroller

• 12

Anwendungscontroller

Unternehmens­steuerfunktion

5

Datenbankzugriffsobjekt

Ansichts­steuerfunktion

~ Abbildung 2.1: Der Verarbeitungsfluss für einen einzelnen Befehl

43

Page 45: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

Die einzigen Elemente im Fluss, die noch nicht erstellt wurden, sind die für das Verhalt en

Ihrer Anwendung spezifischen Va lidierungs-, Unternehmens- und Ansichtssteuerfunktio­

nen. Beispiele für diese anwendungsspezifischen Module finden Sie im gesamten weite­

ren Verlauf des Buches.

Um Benutzereingaben zu validieren, verwenden Sie Va lidierungssteuerfunkt ionen (Vali­dation Control Functions, VaiCF). Mit Unt ernehmenssteuerfunktionen (Business Control

Functions, BCF) rufen Sie Daten aus einer Datenbank, von einem Webserver oder aus einer

anderen Quelle ab oder speichern sie. Ansichtssteuerfunktionen (View Control Functions,

VCF) dienen zur Aktualisierung des Benutzerbildschirms.

Möglicherweise wollen Sie Benutzerdaten mith ilfe einer formularähnlichen Oberfläche erheben, die eine SuBMIT-Schaltfläche enthä lt. Diese Informationen können Sie anschlie­

ßend in der SQLite-Datenbank speichern und dem Benutzer mitteilen, dass die Speiche­

rung erfolgreich war.

Dazu erst ellen Sie drei Steuerfunktionen: eine Valid ierungssteuerfunktion, um sicherzu­

st ellen, dass die eingegebenen Dat en die Minimalstandards erfü llen, die Ihre Anwendung

benötigt, eine Unternehmenssteuerfunktion, um die Daten in der Dat enbank abzu legen,

und eine Ansicht ssteuerfunktion, um eine sichtbare Erfolgsmeldung auszugeben.

Nicht die gesamte Funktionalität muss mit allen drei Art en von Steuerfunkt ionen ver­

knüpft sein. Eine Anwendung w ie ein Spiel braucht normalerweise nicht j edes Mal, wenn

der Benut zer ein Verha lten auslöst, eine Validierungsst euerfunktion.

Abbildung 2.1 macht deut lich, dass nicht alle drei Steuerfunktionen mit einander kommu­

nizieren müssen. Die Module des Frameworks sind so gesta ltet, dass sie dies erledigen. Sie

brauchen Ihre Steuerfunkt ionen lediglich zu schreiben und mit Befehlen zu verknüpfen.

Aufgrund der Gest altung benötigt jede St euerfunkt ion nur wenige Zei len Code und ist

direkt einsatzfähig.

Da die Gestalt ung modular ist, können Sie problemlos das Konzept der Arbeitst eilung an­

wenden. Teilen Sie die Erst ellung dieser St euerfunktionen in einem Team nach Befehl oder

Typ auf, kann die eigenständige Arbeit schnell fortschreit en. Weit ere Informationen dazu, was die einzelnen Steuerfunktionen sind und w ie sie geschrieben werden, finden Sie in

Abschnitt 4 und 5·

Korrekt erst ellt e Steuerfunktionen lassen sich f ür mehrere Befehle w iederverwenden. Sie

können beispielsweise mehrere Befehle benut zen, um denselben Bildschirmbereich zu

akt ualisieren. Die Gesta lt ung ermöglicht Ihnen, eine Ansicht ssteuerfunkt ion zu verknüp­

fen, die den betreffenden Bi ldschirmbereich mit einer beliebigen Anzahl von Befehlen

akt ualisiert.

44

Page 46: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das JavaScript-Framework von QuickConnectiPhone

Wie in Tabelle 2.1 gezeigt, ist der Frontcontroller das Tor, das alle Anforderungen zur Aus­

führung passieren müssen. Dadurch, dass alle Anforderungen durch den Frontcontroller

gezwungen werden, w ird es wesentlich einfacher, die Reihenfolge der Ausführung in der

Anwendung im Voraus festzu legen.

Methodensignatur Rückgabe Parameter

handl eResultCaCmd, void aCmd- Ein eindeutigerString mit dem zu

pa ramArray) verarbeitenden Verhalten, zum Beispiel »displ ayßlog Entries«

pa ramArray -ein optionaler Parameter,

der aus einem Arrayvon Variablen besteht,

die möglicherweise bei der Vera rbeitung

benötigt werden

Tabelle 2.1: Die Frontcontroller-API

Der Frontcont roller hat viel Ähnlichkeit mit einer Mauer um eine ant ike befestigte Stadt:

Es gibt nur einen Weg hinein und hinaus. Durch Reduzierung der möglichen Einfal lspunk­

te in die Stadt lässt sie sich einfacher verteidigen, und die Bürger können sicherer leben.

Die Auf nahme eines Frontcontrol lers in Ihre Anwendung macht diese leichter schützbar.

Die Implementierung des Frontcontrol ler-Moduls im JavaScript-Framework von QuickCon­

nectiPhone ist in der Funktion ha nd l eRequest untergebracht, die Sie in der Datei Quick ­

Connect . j s fi nden, die in Xcode in der Gruppe OCi Phone bzw. in Dashcode im Ordner

QCi Phone Ihrer Anwendung steht. Wenn Sie diesen Code analysieren, erkennen Sie, w ie die

Funktionen fü r die Sicherheit und die Reihenfolge der Ausführung funkt ion ieren.

Wenn die Funktion hand l eRequest aufgerufen w ird, werden ihr ein Befehl und ein

Array mit Pa rametern übergeben. Der Parameter command ist erforderlich, der Pa rameter

pa ramArray dagegen optional.

Der folgende Code, Zeile 17 bis 20 der Datei funct i on s . j s der Anwendung s i mp l eCa l c,

ist ein Beispiel für den Aufruf der Funktion handle Request in Reakt ion auf eine Benutzer­akt ion. Hier klickt der Benutzer auf die Schaltfläche mit dem Addit ionssymboLAbbi ldung 2.2

zeigt die Anwendungs i mp l eCa l c, nachdem der Benutzer auf M umPLY geklickt hat.

45

Page 47: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

r HINWEIS

Sie finden diese und weitere in diesem Buch verwendete Beispielanwendungen als

Dashcode-Projekt innerhalb des von Ihnen heruntergeladenen QuickConnectFamily­

Paketes in dem Ordner iPhone Examples.

f unction add( event ) {

handleRequest ( ' math' ,new Array( '+' )) ;

Als erster Parameter w ird der Befehl ma t h übergeben, als zweiter ein Array, das lediglich

das Zeichen +enthält. Die Verwendung eines Arrays mag in diesem Fal l unnötig erschei­nen, aber weil der Entwurf als zweiten Parameter ein Arrayverlangt, ist er flexibler, wie Sie

weiter hinten in diesem Kapitel sehen.

Simple Calculator A B

~ ~

oiiifiiü 3 4' 5 • 15

~ Abbildung 2.2: Die Beispielanwendung simpleCalc zeigt das Ergebnis der Betätigung der Schaltfläche Multiply.

Die Funktion add ist der onc l i c k-Listener für eine Schaltfläche. Wird die damit verknüpf­

te Schaltfläche ausgewählt, werden alle dem Befehl math zugeordneten Validierungs-,

Unternehmens- und Ansichtssteuerfunktionen ausgeführt und ihnen das Parameterarray

übergeben. Beachten Sie, dass die Listener-Funktionen s ub t ra ct, mult i p l y und d i v i de

denselben Befehl wie add verwenden, im Array aber ein anderes Zeichen übergeben.

46

Page 48: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das JavaScript-Framework von QuickConnectiPhone

ln diesem Fal l verwendet die Anwendungfür jede Funktiona lität denselben Validierungs-,

Unternehmens- und Ansichtssteuercode wieder. Es ist auch möglich, in jedem Listen er ei­nen anderen Befehl und andere Unternehmenssteuerfunktionen zu benutzen, die Validie­

rungs- und die Ansichtssteuerfunktion jedoch wiederzuverwenden. ln diesem Fall ist für

jede gewünschte Art von Arithmetikoperation eine eigene Unternehmenssteuerfunktion

erforderlich, die jedoch ähnlich aussieht. Daher wurde die Entwurfsentscheidung getrof­

fen, nur eine Unternehmenssteuerfunktion zu schreiben.

Abbildung 2.3 zeigt den Anwendungsfluss im Beispiel s i mp l eCa l c bei Betätigung

einer Arithmet ikschaltfläche der Oberfläche durch den Benutzer. in diesem Fall werden

zwei Va lidierungssteuerfunktionen ausgeführt, um zu ermitteln, ob die Fortsetzung der

Ausführung gefahrlos ist. Denken Sie daran, dass der hier gezeigte modulare Entwurf die

Reihenfolge der Funktionsaufrufe erzwingt.

Die erste Validierungssteuerfunktion prüft, ob die beiden vom Benutzer eingegebenen

Werte Zah len sind. Die zweite, d i v i s i on By Ze roVa l CF, sorgt dafür, dass keine Division

durch null stattfindet.

Befehlsfluss

( checkNumbersVaiCF

( divisionByZeroVaiCF

( calculateSolutionBCF

( displaySolution VCF

) ) ) ) .,.. Abbildung 2-3: Ausführungsreihenfolge der dem

Befehl math zugeordneten Steuerfunktionen

Nach der Übergabe beiderValidierungen wird die Funktion cal cu lateSolu t ions BC F

aufgerufen, die die vom Benutzer angeforderte Berechnung durchführt. Anschließend

gibt die Funkt ion d i s p l aySo l ut i on VC F das Ergebnis aus (siehe Abbildung 2.2).

Scheitert die Anforderung j edoch an einer der beiden Validierungssteuerfunktionen, bie­

tet der modulare Entwurf Steuerfunktionen, die diese Situation handhaben können.

Fehlersteuerf unktionen (Error Control Functions, ECF) sind als Steuerfunktionen zur Hand­

habung von Fehlersituat ionen definiert . Schlägt eine Validierungsfunktion fehl, wi rd die

Funktion entry ECF aufgerufen (siehe Abbildung 2-4). Sie informiert den Benutzer über

einen Feh ler bei einer oder mehreren Eingaben.

47

Page 49: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

"math "

( checkNumbersVaiCF

( divisionByZeroVaiCF

} "badNum"

H entryECF )

} "divZero" ----------"

( calculateSolutionBCF

( displaySolutionVCF

) )

.,.. Abbildung 2.4: Der Befehlsfluss des Befehls math

Wie w ird denn nun der Befehl math den vier Befehlsfunktionen zugeordnet, die ausge­

führt werden müssen? ln der QuickConnectiPhone-lmplementierung dieser Gestaltung

werden vier Hilfstunkt ionen bereitgestel lt. Jede ordnet einen Befehl einer Steuerfunktion

zu, w ie Tabel le 2.2 zeigt.

Methodensignatur Rückgabe Parameter

Ma pCommandToVa l CF(command , void c omma n d -ein eindeut iger Stri ng m it

va l ida ti onCont ro l Function) dem zu verarbeitenden Verha lten,

zum Beispiel mat h

va l ida ti onCont ro l Function

-eine Va lidierungssteuerfunkt ion,

die ausgeführt wi rd, wenn die

Funkt ion hand l eRequest den Befehl

empfängt

Ma pCommandToBCF(command, void c omma n d -ein eindeut iger Stri ng m it

bus inessContro l Func t ion) dem zu verarbeitenden Verha lten,

zum Beispiel mat h

bus i nes sCon t ro l Func t ion- eine

Unternehmenssteuerfunktion, die

ausgeführt wi rd, wenn die Funkt ion

hand l eReques t den Befehl

empfängt

48

Page 50: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das JavaScript-Framework von QuickConnectiPhone

MapCommandToVCFCcommand, void comma nd-ein eindeutigerString mit

viewControlFunction ) dem zu verarbeitenden Verha lten,

zum Beispiel ma th

viewContro l Function-eine

Ansichtssteuerfunktion, die

ausgeführt wird, wenn die Funktion

handl eRequest den Befehl

empfängt

MapCommandToECFCcommand, void comma nd-ein eindeutigerString mit

errorControl Function) dem zu verarbeitenden Verhalten,

zum Beispiel d i vZero

er ro rCont ro l Func t ion-eine

Fehlerf unktion, die ausgeführt wird,

wenn die Funktion hand l eRequest

den Befehl empfängt

Tabelle 2.2: Die API Mapping Function

Der folgende Code, Zeile 24 bis 27 der Datei mappi ngs . j s, zeigt, wie die Zuordnung von

Befehlen zu Steuerfunktionen f ür den Befehl math und die beiden Fehlerbefehle badNum

und di vZero erfolgt.

//e i nen Befehl mehreren Fun ktionen zuordnen mapCommandToVa l CFC ' math ' ,checkNumbersVa l CF); mapCommandToVa l CFC ' math ' ,divisionByZeroVa l CF); mapCommandToBCFC ' math ' , ca l cu l at eSo l utionBCF); mapCommandToVCFC ' math ' , displ aySol utionVC F); //mehrere Befehl e, die einer Fun ktion zugeordnet sind mapCommandToECFC ' badNum ' , entryECF); mapCommandToECFC ' divZero ' , entry ECF);

Ein gut gestalteter Frontcontroller muss nur einmal geschrieben werden und kann dann

in mehreren Anwendungen verwendet werden. Der konkrete Entwurffür Front- bzw. An­wendungscontroller in diesem Kapitel bietet auch eine einfache Möglichkeit, das spezifi ­

sche Verhalten Ihrer Anwendungen zu gestalten.

Da dieser vollständ ige Entwurf dafür sorgt, dass zuerst alle Validierungssteuerfunkt ionen

ausgeführt werden und dann alle Unternehmens- und Ansichtssteuerfunktionen, w ird

das Layout Ihrer Anwendung auf Funktionsebene einfach (siehe Abbildung 2-4).

49

Page 51: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

Außerdem stellt der vollständige Framework-Entwurf sicher, dass die Steuerf unktionen in derselben Reihenfolge ausgeführt werden, wie sie den Befeh len zugeordnet sind. Im vorstehenden Zuordnungscode wird die Funktion checkNumbersVal CF immer vor der Funktion d i v i s i on By Zer oVa l CF aufgerufen.

ÄNWEN DUNGSCONTROLLE R

Ein Anwendungscontroller, der auf dem Standardmuster für Anwendungscontroller beruht, dient dazu, Befehle einer bestimmten Funktiona lität zuzuordnen. Daher be­stehen Implementierungen des Musters im Allgemeinen aus einer Zuordnung, deren Sch lüssel Befehle und deren Werte Funktionalitätsziele sind.

Nach dem Entwurf in diesem Kapitel sind die mit den Sch lüsseln der Zuordnung ver­knüpften Werte Funktionslisten, was dem Controller ermöglicht, mehrere Funktionen in der angegebenen Reihenfolge auszuführen und die Modularität und Wiederver­wendbarkeit der Steuerfunktionsziele zu erhöhen.

Ein gut gestalteter Anwendungscontroller macht Ihre Anwendung erweiterbar, wei l Sie Funktionalität hinzufügen können, ohne die Kommunikation der Funktionen un­tereinander neu schreiben zu müssen.

Die QuickConnectiPhone-lmplementierung eines Anwendungscontrollers ist ein Bei­l spiel dafür.

Nachdem Sie nun gesehen haben, wie die Befehle den Steuerfunktionen zugeordnet sind, können Sie sich dem Erstellen solcher Funktionen zuwenden. Die Funktion checkN um­

be r s Va l CF ist recht typisch f ür Validierungssteuerfunktionen. Sie ist auf eine Einzelauf­gabe ausgericht et und sorgt ausschließlich dafür, dass die vom Benutzer eingegebenen Werte numerisch sind. Andernfalls ruft sie einen der Anwendungscontroller, nämlich d i spatchToECF, auf, um den Fehler zu behandeln:

f unct ion checkNumber sVa l CF(paramet er s){ //überprüfen , ob a und b Zahl en si nd

so

var a = document .get El ementßyld( ' a ' ) . val ue ; var b = document .get El ementßyld( ' b ' ) . val ue ; if (isNaN( a) I I isNaN( b)){

di spatchToECF( ' badNum', ' Ent er numbers on l y . ' ) ; r et ur n fa l se ;

return true ;

Page 52: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das JavaScript-Framework von QuickConnectiPhone

Validierungssteuerfunktionen geben t rue zurück, wenn die Situation als korrekt ausge­

wertet wird, sonst f a 1 se. Dadurch ist es möglich, die Verarbeitung bei einem Fehler sofort

anzuhalten, was die Sicherheit Ihrer Anwendung erhöht.

Weiter vorn in diesem Abschnitt hat die Unternehmenssteuerfunktion ca 1 cu1 ate ­

So1utionBCF solche Funktionen dem Befehl math zugeordnet. Wie die meisten Unter­

nehmenssteuerfunktionen fragt sie Daten ab, um damit zu arbeiten. ln diesem Fall holt sie die Daten aus der Benutzeroberfläche. ln anderen Fällen holt eine Unternehmens­

steuerfunktion vielleicht Werte aus einer Datenbank oder mithilfe von AJAX von einem

Server im Internet. Der folgende Code enthält die Implementierung dieser Unterneh­

menssteuerfunktion:

function ca1cu1ateSo1uti onBCF(parameters ){ var a document. getE1ementßy l d( 1 a 1 ).va1ue; var b = document. getE1ementßy l d( 1 b 1 ).va1ue;

if( a = I I ){

a = 0 ;

if(b = I I ){

b = 0 ;

//Ergebni s der Berechnung auswerten var expression = a+parameters[O]+b; var resu1t = eva 1(expression); return new Array(a , b, resu1t);

Unternehmenssteuerfunktionen geben nicht w ie Val idierungssteuerfunktionen einen

booleschen Wert, sondern ein Array mit Daten zurück. Es kann beliebige Informationen

enthalten. ln diesem Fa ll werden die beiden vom Benutzer eingegebenen Werte und das

berechnete Ergebnis zurückgegeben, wei l alldies später benötigt w ird, um die Anzeige für

den Benutzer zu erstellen (siehe Abbildung 2.2).

Die eigentliche Berechnung des Ergebnisses erfolgt mit der JavaScript -Funktion eva 1,

die versucht, einen beliebigen String so auszuf ühren, als enthielte er gültigen JavaScript ­

Code. Gibt der Benutzer in diesem Fa ll als Werte 3 und 5 ein und betätigt die Schaltfläche

Mu 1 t i p 1 y, enthält die Va riable express i onden String »3*5«. Wenn dieser an ev a 1 über­

geben wi rd, lautet das zurückgegebene Resultat 15.

51

Page 53: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel2 JavaScript-Modularität und iPhone-Anwendungen

Seien Sie mit der Funktioneva l vorsichtig, weil sie jeden String ausführt, den sie bekommt.

ln der Beispielanwendung s i mp l eCa l c ist sie gefahrlos verwendbar, weil die Validie­

rungssteuerfunktion durchlaufen wurde, die dafür sorgt, dass die Werte a und b Zahlen

sind. Ist bei den Elementen, die im Aufruf von ev a l verwendet werden, keine Validierung

durchgeführt worden, könnten Benutzer die Funktionsweise einer Anwendung erkennen

und Schaden anrichten, beispielsweise mit einem SQL-Einfügeangriff, wenn die Unter­

nehmenssteuerfunktion Datenbankzugriff besitzt.

Die Funktion d i s p l ay So l ut i on V CF ist ein einfaches Beispiel für Ansichtssteuerfunk­

tionen. Wie die anderen Steuerfunktionen erledigt sie genau eine Sache: Sie aktualisiert

das d i V-Element f ür die Anzeige mit einem String, der die durchgeführte arithmetische

Operation und das berechnete Ergebnis zeigt:

function di sp l ay Sol utionVCF Cdata, pa r ameters ){ var resu l t = data[OJ [O J+' '+parameters [ OJ

+ ' '+data[O J[ l]+' = '+data [0 ] [2 ] ; document.getE l ementBy l d( ' di spl ay ' ) . i nnerHTML result;

Im Allgemeinen aktualisieren Ansichtssteuerfunktionen den HTML-Code der Hauptseite

in irgendeiner Weise. Ein Beispiel für eine größere Änderung der Ansicht ist das Ausblen­den der gesamten sichtbaren Benutzeroberfläche. Dieses Beispiel nimmt nur eine kleine

Änderung vor. Es zeigt die durchgeführte Rechnung und lässt den Rest der Benutzerober­fläche unberührt.

Auch Feh lersteuerfunktionen können einfach oder komplex sein. Sie können Verhalten

wie das Ändern gespeicherter Daten umfassen oder so einfach ausfallen wie das folgende

Beispiel für ent ry EC F. Es übernimmt als einzigen Parameter einen String und zeigt ihn

dem Benutzer an:

function entry ECFCmessage ) { document.getEl ementBy l d( ' di spl ay ' ) . i nnerHTML = message;

Wegen ihrer Einfachheit kann diese Feh lersteuerfunktion beim Scheitern derValidierung

in beiden Va lidierungssteuerfunktionen dieser Beispielanwendung eingesetzt werden.

Mit einer guten Implementierung des Front- bzw. Anwendungscontrollers können Sie

Entwurf und Umsetzung der Anwendung auf das eigentliche gewünschte Verha lten kon­

zentrieren anstattauf Kommunikation und Datenübergabe zwischen den Funktionen. Im

nächsten Abschnitt sehen Sie eine Implementierung eines Frontcontrollers und mehrerer

Anwend u n gscontroller.

52

Page 54: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die QuickConnectiPhone-Umsetzung des modularen Entwerfens

2.3 DIE QUICK(ONNECTIPHONE-UMSETZUNG DES

MODULAREN ENTWERFENS

Wie die meisten anderen Tei le der Entwurfsumsetzung in diesem Abschnitt ist auch die

Funktion handl eRequest kurz und knapp. Sie und die Methode, deren Fassade sie dar­

stellt, bestehen aus 21 Codezeilen, von denen nur 15 aktiv sind. Im folgenden Code sind die

interessanten Zeilen 7 bis 21 fett gedruckt.

Da die Funktion handl eRequest die Implementierung des Frontcontrollers des im

vorigen Abschnitt behandelten Entwurfs darstellt, ist sie für den Aufruf von vier Anwen­

dungscontrollern zuständig. Jedem davon obliegt die Behandlung eines Steuerfunktions­

typs. Als erster Anwendungscontroller wird d i spatchToVa l CF aufgerufen (Zeile 7 des

folgenden Codes). (Die einzelnen Anwendungscontroller-Funktionen werden in Tabelle 2.3 beschrieben.)

M ethodensignatur Rückgabe Parameter

dispa tc hToVa l CF Ein boaleseher Wert. a Cmd- ein eindeut igerString mit

( aCmd, pa ramArray) Bei Erfolgt r ue, bei dem zu verarbeitenden Verhalten,

Feh lschlag fa l se. zum Beispiel d i sp l ayßl ogEntri es

pa ramAr ray- ein optionaler

Parameter, der aus einem Array

von Variablen besteht, die bei der

Verarbeitung benötigt werden

dispa tc hToBCF(aCmd, Anzeigefert ige Daten a Cmd- ein eindeut igerString mit pa ramArray, oder stop. Wi rd dem zu verarbeitenden Verhalten,

ca l l ßac kData ) stop zurückgegeben, zum Beispiel d i sp l ayßl ogEntri es

erfolgt keine weitere pa ramAr ray- ein optionaler

Berechnung für den Parameter, der aus einem Array

angegebenen Befehl. von Variablen besteht, die bei der

Verarbeitung benötigt werden

ca l l BackDa ta- ein optiona ler

Parameter, den das Framewerk

erstellt, wenn asynchrone Aufrufe

aus Unternehmenssteuer-

funktionen erfolgen, die mit dem

Befehl verknüpft sind

53

Page 55: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

dispatchToVCF(aCmd , vo i d aCmd- ein eindeutigerString mit

data, paramArray, ) dem zu verarbeitenden Verhalten,

zum Beispiel d i spl ayß l og Entr i es

data- ein Array mit sämtlichen Daten, die Aufrufe von Unter-

nehmenssteuerfunktionen erzeugen

pa ramArray- ein optiona ler

Parameter, der aus einem Array

von Variablen besteht, die bei der

Verarbeitung benötigt werden

d ispa t chToECF(aCmd , void aCmd- ein eindeutigerString mit

errorMessage) dem zu vera rbeitenden Verhalten,

zum Beispiel d i sp l ayß l og Entri es

errorMessage -eine Meldung,

die den Entwickler mithilfe von

Protokollen oder den Benutzer

mithilfe der Anzeige informiert. Sie

sol lte aussagekräftig und f ür den

Zielbenutzer hilf reich sein, f ür den

sie gedacht ist.

Tabelle 23: Die Anwendungscontroller-API

Die Funktion dis pa tchToVa l CF ruft sämtliche Validierungssteuerfunktionen auf, die Sie

dem Wert command in der Variablen aCmd zugeordnet haben. Wird die Validierungsfunk­

tion aufgerufen, gibt sie den booleschen Wert t r ue zurück, wenn eine feh lsch lägt dage­

genfa l se.

Da der Aufruf vond is pa tc hToVa l CF von einer i f -Anweisung umschlossen ist, w ird Ihre

Anforderung nur bei Rückgabe von t rue weiter verarbeitet. Andernfa lls fä llt sie, fa lls Sie

dem Hauptbefeh l Feh lersteuerfunktionen zugeordnet haben, in der Fehlerbehandlungs­

routine durch. Die bereits vorgestel lte Beispielanwendung s i mp l eCa l c weist jedoch

keine derartigen Zuordnungen auf.

54

Page 56: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die QuickConnectiPhone-Umsetzung des modularen Entwerfens

1 f unction handl eRequest(aCmd, pa ramArray){ 2 requestHa ndl er (aCmd, par amArray, nul l ) ; 3 4 5 f unction reques tHandl er(aCmd, paramAr r ay , call BackData ){ 6 i f ( aCmd !=nul l){ 7 8 9 10 11 12 13 14 15 16 17 18 19 el se{

i f ( di spatchToVal CF( aCmd, paramArray)){ t ry{

var data = dispatchToBCF( aCmd, pa r amArr ay , ca llBackData ) ;

if( da t a != ' stop' ) { dispatchToVC F(aCmd , data , paramArray) ;

catch(err ){ l ogError(e r r) ;

20 di spatchToECF ( aCmd, ' va lidati on fa i l ed ' ) ; 21 22 23

Nachdem Ihre Anforderung die Validierung durchlaufen hat, ruft das Frontcontroller­

modul den nächsten Anwendungscontroller auf, d i spa t chToBCF. Diese Funktion ruft

die Unternehmenssteuerfunktionen auf, die Sie mit dem Befehl verknüpft haben, um die

gewünschten Dat en abzurufen oder zu speichern.

Gibt Ihre Unternehmenssteuerfunktion etwas anderes zurück als s top, ruft der Frontcont­

roller die Ansichtssteuerfunkt ionen auf, die Sie außerdem mit dem Befehl verknüpft haben.

Dazu benutzt sie den dritten Anwendungscontroller, di spatchToVCF. Weitere Informat io­

nen über Unternehmens- und Ansichtssteuerfunktionen finden Sie in Abschn itt 4·

Der Zweck des erwähnten Frontcontrol ler-Moduls besteht darin, eine schnel le und einfa­

che Möglichkeit bereitzustellen, um f ür einen stabi len, sicheren Berechnungsfluss durch

Ihre Anwendung zu sorgen. Wird ein Vera rbeitungsfluss ständ ig genutzt, ist es wesentlich

einfacher, Ihre Anwendungen zu erstellen und Fehler darin zu beheben. Verwenden Sie

die QuickConnectiPhone-lmplementierungen des Entwurfs, sollt en Sie daher die Funktion

hand l eRequest aufrufen, wenn Sie wollen, dass in der Anwendung etwas geschieht.

55

Page 57: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

Jede Anwendungssteuerfunktion aus Tabel le 2.3 spielt eine andere Rol le und ermöglicht

die Handhabung Ihres Befehls zur Fortsetzung oder Unterbrechung in Abhängigkeit von

Ihren Entscheidungen in den Valid ierungs- und Unternehmenssteuerfunktionen. Es han­

delt sich dabei um Module, weil sie wiederverwendbar, lose gekoppelt und eng zusam­

menhängend sind.

Die Funktion d i s pa tchToVa l CF stellt eine Fassade dar. Diese Funktion und die Funktion

di spatchToSC F sind identisch, was ihr Verhalten angeht, bearbeiten aber unterschied­

liche Datenmengen. Mit Validierungssteuerfunktionen untersuchen Sie Benutzereingaben.

Sicherheitssteuerfunktionen (Security Control Functions, SCFs) sollen dagegen sicherstellen,

dass Daten aus entfernten Quellen wie Websites keinen Schadcode ent halten. Aufgrund

dieser Funktionsähnlichkeit legen Sie den Arbeitscode am besten zentral ab und setzen zum

Aufrufen der zugrunde liegenden Prüffunktion Fassadenfunktionen ein.

Der folgende Code aus der Datei Ou i ckConnect. j s zeigt die Fassadenfunktion

d i spatchToVa l CF und die ihr zugrunde liegende Funktion check. Wie Sie sehen, ruft

d i spa t chToVal CF die Prüffunkt ion auf und übergibt dieser ihre beiden eigenen Para­

meter sowie einen weiteren. Dabei handelt es sich um einen String, der beschreibt, welche

Art von Zuordnungstabelle die Funkt ion verwenden sol l. Diese Zuordnungstabelle, ein

assoziatives Array, enthält sämtliche Verknüpfungen zwischen Befehlen und einem Array

von Validierungssteuerfunktionen. Wie Sie Befehle erstel len und mit Va lid ierungssteuer­

funktionen verknüpfen, steht in Abschnitt 2 dieses Kapitels.

1 function dispatchToVa l CF(vali dat ionCommand , paramArray){ 2 return check(va l i dationCommand , ' va li dation ' , paramArray ) ; 3 4

5 /* 6 *Diese Funkt ion soll nicht direkt vom Programmierer aufgeru fen

* werden . Verwenden Sie sie nicht. 7 */ 8 function check(command, t ype , data){ 9 var retVa l = t rue ;

10 /* 11 * all e Standardfunktionen ausführen , die für al l e

* Be fehle gel t en, wenn Standardfunktionen definiert sind 12 */

56

Page 58: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die QuickConnectiPhone-Umsetzung des modularen Entwerfens

13 var map = securityMap; 14 if(type = 'va l ida t ion'){ 15 map = va l ida t ionMap; 16 17 var defaultFuncs = map['default'J: 18 if(defaul t Funcs){ 19 var numFuncs = defaultFuncs.length: 20 for(var i = 0; i < numFuncs; i++ ){ 21 retVa l = defaul t Funcs[i] (command , data ) ; 22 if(retVal = fa l se){ 23 break: 24 25 26 27 /* 28 * wenn die Standardfunktionen passiert haben,

*die befehl sspezifisc hen ausführen 29 */ 30 if(retVa l = true){ 31 command Funcs = map [command]; 32 33 34

35 36 37 38 39 40 41 42 43 44

i f (commandFuncs){ var numFuncs commandFuncs . l ength; for (va r i = 0: i < numFuncs; i++){

retVa l = commandFuncs [ i]( data); if(re tVa l == fa l se){

brea k:

return retVal :

ln Zeile 17 versucht der Code, ein Array mit Steuerfunktionen abzurufen, die mit dem Befehl defau l t verknüpft sind. Das Abrufen dieser Funktionen bedeutet, dass Sie eine Ansichtssteuerfunktion schreiben kön nen, die für jeden Befehl aufgerufen wird, den Sie an handl eRequest senden, wenn Sie siedefaul t zuordnen.

57

Page 59: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

Eine gängige Standardvalidierungssteuerfunktion ist eine, die dafür sorgt, dass in der

Zuordnungstabel le für die Unternehmens- oder die Ansichtssteuerfunktionen oder in

beiden eine Zuordnung für den Befehl vorhanden ist, der gerade übergeben wird. Feh lt der

Befehl in diesen Funktionen, gibt es keinen Grund, mit seiner Verarbeitung fortzufahren,

wesha lb die weitere Prüfung abgebrochen und fa 1 se zurückgegeben wird.

Indem die Funktion f a 1 se zurückgibt, veranlasst sie die Funktion d i spa tc hToVa l CF, so­fort dasselbe zu tun. Dies veran lasst wiederum den Frontcontroller, die weitere Verarbei­

tung zu beenden. Diese Validierungssteuerfunktion fängt nicht zugeordnete fehlerhafte

Befehle ab, bevor sie im weiteren Verlauf zu Problemen in Ihrer Anwendung führen.

Gibt es keine Standardvalid ierungssteuerfunktionen oder durchläuft der Befehl alle mit

dem Befehl defa ul t verknüpften, ruft die Methodecheck ansch ließend die Liste der mit

dem betreffenden Befehl verknüpften Validierungssteuerfunktionen ab und führt sie der

Reihe nach aus.

Diese vorherige Prüfung von Eingaben al ler Art stellt, wie in Abschnitt 2 erörtert wird,

einen Zweck der Funktion d i s pa tchT oVa 1 CF und der von Ihnen erstellten Va lidierungs­

steuerfunktionen dar. Außerdem ermöglicht sie Ihnen, den Va lidierungs- und den Ausfüh­

rungscode zu t rennen, was den Support Ihrer Anwendung erleichtert. Es hilft Ihnen auch beim Schreiben der Software, indem es das Entwerfen vereinfacht (siehe Abschnitt 2).

2.4 IMPLEMENTIERUNG VON UNTERNEHMENS- UND

ANSICHTSANWENDUNGSCONTROLLERN

Der Unternehmensanwendungscontrol ler ist der komplexere der beiden Anwendungs­

controller, der Ansichtsanwendungscontroller ist dagegen einfach. Die Funktion di s ­

patchToBCF ruft al le einem Befehl zugeordneten Unternehmenssteuerfunktionen auf, auch wenn eine oder mehrere davon asynchrone Aufrufe vornehmen. Die Funktiond is ­

pa tchToVC F ist wesentlich einfacher, weil sie der Funktiond is pa tc hT oVa 1 CF sehr stark

ähnelt und Ansichtssteuerfunktionen niemals asynchron sind. Obwohl sich beide Funk­

tionen ähnlich verhalten, unterscheidet sich ihre Umsetzung erheblich.

Wie in Abschnitt 2 erörtert, wird die Unternehmensanwendungssteuerfunktion nur auf­gerufen, wenn die von Ihnen definierten und zugeordneten Va lid ierungssteuerfunktionen

ergeben, dass die Verarbeitung gefahrlos fortgesetzt werden kann. Obwohl die Funktion

zum Teil dieselben Ideen benutzt wie die Methode chec kVa 1 i da t i on, unterscheidet sie

sich erheblich von dieser.

Die Funkt ion di spatc hToBC F besteht aus zwei Haupttei len. Der erste umfasst Zeile 18 bis 40 und befasst sich mit dem Array ca 11 Ba ckData, das die bei einem asynchronen

Aufruf gesammelten Daten enthält. Nimmt Ihre Unternehmenssteuerfunktion keine

asynchronen Aufrufe vor, ist das Array nu l l . Führt sie einen Aufruf aus, beispielsweise

58

Page 60: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Implementierung von Unternehmens- und Ansichtsanwendungscontrollern

einen AJAX-Aufruf oder einen Aufruf zum Abfragen von Daten aus einer Datenbank, ent­

hält das Array die Daten, die erforderlich sind, um die übrigen dem Befehl zugeordneten

Unternehmenssteuerfunktionen aufzurufen. ln Zeile 25 und 31 sehen Sie, dass das Array

ca ll Ba c kDa t a die Ergebnisse aller vor dem asynchronen Aufruf aufgerufenen Unter­

nehmenssteuerfunktionen sowie die von diesem selbst erzeugten Daten enthält.

J DEFIN ITION VON »ASYNCHRON «

Bei der Arbeit mit Computern denken Sie gewöhnlich synchron, d.h., Sie tun Dinge

einzeln in einer definierten Reihenfolge. Beim Aufrufen einer Funktion erwarten Sie

normalerweise, dass die einzelnen Schritte nacheinander ausgeführt werden. Sind alle

Schritte erledigt, gibt die Funktion einen Wert oder voi d zurück.

Asynchrones Verhalten unterscheidet sich davon. Es ähnelt eher einem Fußballspiel.

Im Spiel ist jeder damit beschäftigt, ohne Rücksicht darauf, ob jemand anders auch

damit beschäftigt ist, das Notwendige zu tun. Alles andere wäre dumm. Stellen Sie sich

ein Spiel vor, in dem alle Spieler darauf warten, dass andere mit dem fertig werden,

was sie getan haben, bevor sie selbst anfangen, sich zu bewegen. Einfach dumm.

Asynchrones Verhalten in der Datenverarbeitung bedeutet, dass Sie eine Funktion an­

weisen können, etwas zu tun, während die Verarbeitung fortgesetzt wird, ohne darauf

zu warten, dass die Funktion etwas zurückgibt.

Zei le 34 f ügt in den Fällen, in denen vorher keine Unternehmenssteuerfunktion aufgeru­

fen w urde, die vom asynchronen Aufruf erzeugten Daten in das Array resul ts ein. Das

Array sieht nach Ausführung der Zei le daher fü r den Rest des Codes so aus, als hätten

keine asynchronen Aufrufe stattgefunden.

Zeile 37 fragt die Indexnummer der Unternehmenssteuerfunktion ab, die den asynchronen

Aufruf getätigt hat; andernfalls wüsste der Rest der Funktion di spatchToBCF nicht, wie

viele dem Befeh l zugeordnete Unternehmenssteuerfunktionen bereits ausgeführt wurden.

Asynchrone Aufrufe stellen einen »Bruch« in der Ausführung der dem Befehl zugeordneten

Unternehmenssteuerfunkt ionen dar. Die Funktion d i spa t chToBC F weiß nur dann, welche

Unternehmenssteuerfunkt ionen bereits ausgeführt wurden, wenn in den Daten, die sie aus

den Ergebnissen des asynchronen Aufrufs erhält, ein Hinweis enthalten ist.

ln Kapitel 6, »Datenbankzugriff«, geschieht dies mithilfe der Methoden getDa t a, set ­

Da ta, getNativeData und setNativeData des Da taAccessObject. Wenn Sie ein

eigenes Framewerk erstellen, das asynchrone Aufrufe ermöglicht, sollten Sie Code wie den

folgenden vorsehen:

59

Page 61: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

1 function dispatchToBCF(aCmd, paramArray, callßackData ){ 2 3 if(event = null) { 4 event = window . event: 5 6 if(event != null) { 7 stopDefaul t (event); 8 9 wi ndow.curCmd = aCmd: 10 if(paramArray){ 11 window .globalParamArray paramArray; 12 13 else{ 14 15

window .gl oba l ParamArray new Array();

16 var resu l ts = new Array() ; 17 window .numFuncsCal l ed = 0: 18 if(ca l l ßackDa t a){ 19 if(ca ll ßackDat a[OJ){ 20 if(cal l ßack0ata [1 ] ){ 21 var accumula tedData FromCa l l back =

22 ca l l ßack0ata[1 ][3J : 23 if(accumul atedDataFromCa l l back && 24 accumul atedDataFromCa ll back . l engt h > 0){ 25 resu l ts = accumulatedData FromCa l l back ; 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

if(resul ts . l ength = 0){ // resu l ts sol l immer ei n Array sein. // Die Kl ammern [ ] sorgen dafür. resu l ts = [ca l l ßackData[O JJ :

el se{ resu l ts. pus h(cal l ßackDa ta [O]);

if(ca ll ßack0at a[1]){ window . numFuncsCa l l ed ca l l ßack0ata[1 ][1];

41 var stop = fa l se; 42 i f(aCmd) {

60

Page 62: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Implementierung von Unternehmens- und Ansichtsanwendungscontrollern

43 44 45 46 47 48 49 50

var commandlist = businessMap[aCmd]; call Func = function(data){

if( data) { resul t s.append(data); window .globa l BCFResul ts = resu l ts;

i f (window . num FuncsCa l l ed < commandlist . l ength){ var funcToCa l l =

51 52

commandl i st [wi ndow . numFuncsCa ll ed ] ; window.numFuncsCal l ed++;

53 54 55 56 57 58 59 60 61 62 63 64 65

66 67 el se{

var resu lt = null; t ry{

resu l t = funcToCa l l (paramArray , resul t s) ;

catch(err){ di spatchToECF( ' runFa i l ure '.

err .message) ;

if(result != null ){ resu l ts[resul ts . l ength] ca l l Func() ;

result ;

68 stop = true ; 69 70 71 72 73 74 75

if(commandli st && command l ist . l engt h > 0){ ca ll Func() ;

76 if( stop ){ 77 ret urn ' stop '; 78 79 re t urn resu l ts ; 80

61

Page 63: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel2 JavaScript-Modularität und iPhone-Anwendungen

Die Zeilen 41 bis 8o der Anwendungssteuerfunktion di spatchToBCF enthalten drei Tätig­

keiten:

> Erstellung und Verwendung anonymer JavaScript-Funktionen

> Rekursion in JavaScript

> Auf rufen der mit einem Befehl verknüpften Unternehmenssteuerfunktionen

Anonym ist jede Funktion, die »nebenbei« innerhalb einer anderen Funktion angelegt

w ird, beispielsweise die Funktion ca ll Func in Zeile 44 bis 71 des vorstehenden Codes.

Außerhalb der Funktion d i spa tc hToBCF kommt diese Funktion nicht vor. Wie alle anony­

men Funktionen ist sie streng auf den Gültigkeitsbereich der Funktion beschränkt, inner­

halb derer sie deklariert wird. Al le Variablen, die in der umschl ießenden Funktion vor der

anonymen Funktion deklariert wurden, liegen trotzdem innerhalb des Gültigkeitsbereichs

und können in der anonymen Funktion benutzt werden, obwohl sie nicht als Parameter

übergeben wurden.

Zeile 43 und 44 bilden ein Beispiel dafür. Die Variable commandl i st wi rd außerha lb der Funktion ca l l Func definiert, nicht an diese übergeben und t rotzdem innerhalb der Funk­

tion verwendet. ln Zeile so und 51 wird sie benutzt, um die nächste auszuführende Unter­

nehmenssteuerfunktion aufzurufen. in Zei le 55 und 56 wird die Steuerfunktion ausgeführt,

und die Ergebnisse werden gespeichert.

Als Beispiel fü r Rekursion ruft sich ca l l Func in Zei le 65 selbst auf Dies geschieht am

Ende der Funktion und nur dann, wenn das Ergebnis des Aufrufs der Steuerfunktion nicht

nul l ist. Diese Art von Rekursion wird als Endrekursion bezeichnet, weil die Prüfung

am Sch luss der Funktion liegt. Findet sie am Anfang der Funktion statt, spricht man von

Anfangsrekursion. Die vollständige Rekursionskaskade, die die Funktion ca l l Func aus­

löst, beginnt mit dem Aufruf in Zeile 73-

REKURSION

Rekursion ist der Aufruf einer Funktion durch sich selbst.

Wenn die Funktion di spatchToVCF aufgerufen wird, ruft sie, wie Sie im folgenden Code

sehen, eine Liste von Steuerfunktionen ab, die dem Befehl zugeordnet sind Im Unterschied

zur Validierungsanwendungssteuerfunktion wird ihr ein Datenparameter übergeben: ein

Array, das die einzelnen Ergebnisse der Aufrufe der Unternehmenssteuerfunktionen enthä lt.

62

Page 64: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Implementierung des Fehleranwendungscontrollers

Gibt eine der Ansichtssteuerfunktionen stop zurück, werden wie bei di spatchToBCF keine weiteren Va lidierungssteuerfunktionen ausgeführt. Daher kann der Programmierer die weitere Ausführung beenden, indem er die Funktion di spatchToECF aufruft.

function dispatchToVCF(aCmd, data, paramArray){ if( aCmd) {

var vcfFunc l ist = viewMap [ aCmd]: if ( vcfFunc List = null ) {

vcfFunclist = new Array() ;

var numFuncs = vcfFunclist.length: for(var i = 0 : i < numFuncs ; i ++){

try{ retVa l = vcfFunclist [ i ] (da ta, paramArray) ;

catch(err) { debug(errorMessage(er r )) ;

i f(retVa l && retVa l = 'stop ' ) { break:

Die einzelnen Va lidierungssteuerfunktionen werden aufgerufen und ihnen die Ergebnis­

daten der Unternehmenssteuerf unktion sowie die ursprünglichen Parameter in Form der Variablen pa ramAr ray übergeben, die Ihre Anwendung an die Funktion ha nd l eReques t gesendet hat . Dies wurde in die Implementierung aufgenommen, um Ihnen die Möglich­keit zu geben, den vom Unternehmens- und vom Ansichtsanwendungscontroller aufge­rufenen Unternehmens- und Ansichtssteuerfunktionen Informationen zu übermitteln.

2.5 DIE IMPLEMENTIERUNG DES FEHLERANWENDUNGS­

CONTROLLERS

Anders als bei den anderen in Abschnitt 3 und 4 behandelten Anwendungscontrollern ermöglicht die Implementierung des Fehleranwendungscontrollers im QuickConnect­iPhone-Framework nur die Zuordnung einer einzigen Fehlersteuerfunktion zu einem Befeh l. Jede Fehlersteuerfunkt ion muss den Fehler also vol lständig behandeln, was die

Änderung gespeicherter Daten, die Aktualisierung der Ansicht zwecks Information des Benutzers und anderes umfasst.

63

Page 65: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 2 JavaScript-Modularität und iPhone-Anwendungen

Der folgende Code implementiert einen einfachen Fehleranwendungscontroller:

f unct i on dispatchToECFCer rorCommand , errorMessage){ var err orFunc = errorMap[error Command]; if(errorFunc){

r et urn errorFunc(errorMess age) ;

Diese Implementierung ruft einfach die auszuführende Fehlersteuerf unktion ab und

übergibt ihr die Feh lermeldung. Um die Fehlerbehandlung auf diese Weise zu akt ivieren,

istein direkt er Auf ruf von d i spa t chToEC F erforderlich, anstatt über hand l eRequest zu

gehen. ln der Funktion chec kNumbe r s Val CF finden Sie folgende Codezeile:

dispatchToECFC 'badNum ' , ' Enter numbers on l y . ' ) ;

Dieser Auf ruf von d i spa t chToEC F übergibt eine Meldung, die in die Anzeige der Benut­zeroberfläche aufgenommen werden soll und dem Benutzer mitteilt, dass nur Zahlen als

Eingabewert e akzept iert werden.

2.6 DIE FUNKTIONALITÄT DER ANWENDUNG ERSTELLEN

ln Abschnitt 3 bis 5 w ird erläut ert, was hint er den Kulissen geschieht, wenn Sie die Im­

plementierung des Front - und Anwendungscontrollerentwurfs des QuickConnect iPhone­

Frameworks benutzen. Welche Schritte müssen Sie f ür die Erstellung des Großtei ls der

Anwendungsfunktionalität nacheinander unternehmen?

1. Sämtliche Unternehmenssteuerfunktionen zum Abrufen oder Speichern von Daten

schreiben (siehe Abschnitt 4)

2. Sämtliche Ansichtssteuerfunktionen zum Ändern der Benutzeroberfläche schreiben

(siehe Abschnitt 4)

3. Sämtliche für die Benutzereingaben erforderlichen Validierungssteuerfunktionen

schreiben (siehe Abschnitt 3)

4. Sämtliche zur Behandlung möglicher Fehlerbedingungen erforderlichen Fehler­

steuerfunktionen schreiben (siehe Abschnitts)

5. Alle neuen Steuerfunktionen mithilfe der passenden mapCommandTo***-Funktion

einem Befehl zuordnen

Wenn Sie diese f ünf Schritte erledigt haben, ist die neue Funktionalität Bestandt eilihrer

Anwendung.

64

Page 66: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Zusammenfassung

2.7 ZUSAMMENFASSUNG

Modularität macht Ihren Code einfacher erstellbar, leichter pflegbar und kleiner, wenn

sie richtig angewandt wird. Wenn Sie dies und die Geschwindigkeit der Ausführungsziele

vor Augen haben, erleichtert die Implementierung des QuickConnectiPhone-Frameworks,

die Ihnen in j eder Anwendung zur Verfügung gestel lt wird, die Sie mit den QuickConnec­

tiPhone-Anwendungsvorlagen erstellen, Ihnen das Leben erhebl ich. Sie können sich auf

das konzentrieren, was Sie wollen, nämlich Funktionalität für Ihre Benutzer schreiben und

bereitstellen. Die Kommunikation zwischen den Funktionen und die Steuerung der Funk­

tionen erledigt das Framewerk für Sie.

Mit der Erstellung von Validierungs-, Unternehmens-, Ansichts- und Fehlersteuerfunktio­

nen können Sie den Umfang Ihrer Arbeit problemlos so gestalten, dass die Produktivität

zunimmt, während Sie gleichzeitig Qua lität und Sicherheit Ihres Codes steigern.

65

Page 67: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 68: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Benutzerschnittstellen für das iPhone erstellen

Das iPhone bietet einzigart ige Methoden fü r die Interaktion mit dem Benutzer. Bei diesem

neuen Medium reichen ältere Methoden zum Entwerfen von Schnittstellen nicht aus. Eine

von Ihnen erstellte Anwendung kann dem Benutzer die intuitiven Schnittstellen interaktio­

nen und -elementezur Verfügung stellen, nach denen iPhone-Benutzerverlangen.ln diesem

Kapitel geht es darum, wie das zu erreichen ist. Außerdem werden die Schnittstellenricht­

linien von Apple erörtert, mit deren Hilfe Anwendungen bewertet werden können, die in

den App Store aufgenommen werden sollen. Des Weiteren w ird ein Modul f ür Drag&Drop,

Skalierung und Drehung gezeigt und erläutert, damit Sie sehen, wie Sie mit Berührungs­

und Gestenereign issen in JavaScript umgehen. Diese neuen JavaScript-Ereignistypen sind

nämlich fü r die Gesta lt ung der iPhone-Benutzerschnittstelle wesentlich.

Page 69: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

3.1 DIE SCHNITTSTELLENRICHTLINIEN VON ÄPPLE

Um iPhone-Benutzern gleichartige Erlebnisse zu ermöglichen, hat Apple Richtlinien dafür

aufgestellt, was in iPhone-Benutzerschnittstellen verwendet werden soll. Dieser Abschnitt

stellt Ihnen die Grundlin ien und wichtigsten Punkte der Schnittstellenrichtlinien (Human

Interface Guide, HIG) des iPhones kurz und knapp vor. Die vollständigen Richtlinien finden

Sie unter folgender Adresse:

http:lldeveloper.apple.comliphone!library!documentation!UserExperience!Conceptual!

MobileH/C/Introductionllntroduction.html.

Die Schnittstellenrichtlinien für das iPhone beruhen auf den bereits früher für OS X und

die iPhone-Webentwicklung aufgestellten; vieles wurde daraus übernommen. Die neuen

Richtlinien stützen sich auf die Stärken ihrer Vorgänger und ergänzen sie durch Elemente, die spezifisch fü r iPhone-Anwendungen sind.

Der Platz des iPhone-Displays ist so begrenzt, dass Textausgaben fü r den Benutzer schnel l

unübersichtlich werden können. ln Anwendungen, deren Hauptfunktion nicht im Lesen

von Textdaten liegt, sollten nach Möglichkeit Bilder und Symbole verwendet werden, um

dem Benutzer Ideen und Funktionen nahezu bringen.

Der Schritt weg von Textsignalen gehört zum Wesen des iPhones. Es hat weder Pul I-down­

Menüs noch Banner. Sie sol lten daher auch in Ihrer Anwendung darauf verzichten. Wenn

sie gut gestaltet ist, sollte sie intu itiv bedienbar sein. Andernfalls ist sie nicht für das iPho­

ne geschrieben. Bei guter Gestaltung sol lte Ihre Anwendung ohne Gebrauchsanweisung

auskommen.

Ein Grund fü r das Ausufern von Pull-down-Menüs in vielen Anwendungen liegt darin,

dass sie nicht mehr einem einzigen Zweck dienen, sondern vielen. Betrachten Sie die ver­

fügbaren Büroanwendungen, erkennen Sie leicht, wie sie sich von den einfachen, zweck­

bestimmten Anwendungen, die sie einmal waren, zu den Giganten entwickelt haben, die

sie heute sind.

Textverarbeitungsprogramme verarbeiten nicht mehr nur Text. Sie müssen ausgefei lte

Layouts erstel len, Elemente aus vollkommen anderen Anwendungen einbinden können

und sogar eine Entwicklungsumgebung bereitstel len. Das Eindringen solcher Funktionen

hat diese Anwendungen zwar in gewisserWeise breit einsatzfäh ig, gleichzeitig aber auch

riesig und schwerfäl lig gemacht.

Jede iPhone-Anwendung sollte genau einen Zweck oder eine Funktion haben, die prob­lemlos zu defin ieren und für den Benutzer leicht zu erkennen ist. Wenn Sie sich an den

Standard von Apple halten, ist Ihre Anwendung leichter verständ lich und füh rt zu ange­

nehmeren Benutzererlebn issen.

68

Page 70: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Schnittstellenricht linien von Apple

Anwendungssteuerung ist eine wesentliche Komponente jedes Entwurfs. Ihre Anwen­

dungen sol lten dem Benutzer möglichst viele Steuermöglichkeiten geben, d.h., sie sollten

kein bestimmtes Verhalten erzwingen. Die Beschränkung von Optionen wird in iPhone­

Anwendungen nicht gern gesehen. Ein Beitrag dazu ist die flache Anordnung der Ansich­

ten. Eine tiefe hierarchische Staffelung überlässt dem Computer die Verantwortung und

sollte vermieden werden.

Da Handbewegungen wie Berührung und Mehrfachberüh rung die Interaktionsmethoden

für das iPhone darstellen, sollte Ihre Anwendung dies unterstützen. Jeder Berührungs­

punkt sollte eine angemessene Größe haben, damit der Benutzer ihn auswählen kann.

Der Standard sieht eine Höhe und Breite von 34 Pixel vor. Sind die Punkte kleiner, wei l Sie

versuchen, mehr Platz zu gewinnen, wi rd die Auswah l von Displayelementen für den Be­

nutzer schwierig und sein Erlebnis unschön.

Die Verhaltensweisen Swipe und Pinch werden zwar unterstützt, sind aber möglicher­

weise fü r den Benutzer schwer zu entdecken. Wol len Sie sie einbinden, sollten Sie optische

Hinweise darauf geben.ln einer E-Book-Anwendung können dazu zum Beispiel umgebo­

gene Seitenecken angezeigt werden.

Von Drag&Drop-Funktionen raten die Schnittstellenrichtl inien im Allgemeinen ab, weil

diese üblicherweise fü r Bildlauf und Schwenks verwendet werden. Es lassen sich jedoch

leicht Beispiele für erfolgreiche Anwendungen m it Drag&Drop finden. Apple hat sogar ein

übermäßig kompliziertes Beispiel dafür produziert, w ie dies in JavaScript zu erreichen ist.

Der zweite Tei l dieses Kapitels zeigt Ihnen, w ie Sie Schnittstellenelemente fü r Drag&Drop,

zum Skal ieren durch Pinching und zum Drehen sauber und einfach umsetzen.

Tabelle 3.1 listet al le unterst ützten Handbewegungen und das damit verknüpfte Standard­

verhalten auf. Indem Sie sich an diese Definitionen halten, erleichtern Sie es den Benut ­

zern, Ihre Anwendung zu erlernen. Definieren Sie die Verhaltensweisen jedoch um, w ird es

für die Benutzer schwieriger.

Handbewegung Verhalten

ta p Auswahl eines Schnittstel lenelements

drag Bildlauf oder Schwenk zur weiteren

Betrachtung

f l i ck Schneller Bildlauf oder Schwenk. Dies muss

ein weiteres Verhalten umfassen, wenn die

Handbewegung abgeschlossen ist.

69

Page 71: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

swi pe Aufdecken verborgener Komponenten,

beispielsweise Schaltflächen zum Löschen

von Zei len in der Tabellenansicht oder

zusätzliche Ansichten

double tap Zentrieren und dann hinein- oder

herauszoomen

expand i ng pinch ( pinch open ) Hineinzoomen

contracting pi nch ( pi nch close ) Herauszoomen

touch and hol d Vergrößerte Ansicht zeigen

Tabelle 3.1: Handbewegungen und Standardverhaltensweisen für das iPhone

Das iPhone ist gewiss ein erstaunliches Gerät, aber im Vergleich mit der Dateneingabe an

einer Standardtastatur kann das Eingeben von Text mühevoll und langsam sein. Achten

Sie darauf, dass Sie nach Möglichkeit nicht die direkte Eingabe, sondern die Auswahl von

Daten vorsehen. Bei Web-Apps springen Selektoren auf, sogenannte Picker, wenn der

Benutzer ein HTML-Options-Tag auswählt . Die Verwendung solcher Selektoren in Ihren

Anwendungen beschleunigt die Steuerung durch den Benutzer und reduziert frustrieren­

de Erfah rungen. ln Kapitel 4, »GPS, Beschleunigungsmessung und andere systemeigene

Funktionen von QuickConnect«, erfahren Sie, w ie Sie standardmäßige Zeitpicker für Da­

tum und Uhrzeit in Ihre Web-Apps einbinden.

Die Schnittstellenrichtlinien fü r iPhone-Standardanwendungen sehen vor, Kontrol lkästchen und Optionsschaltflächen zu vermeiden; stattdessen sollen Scha lter benutzt werden. Auf

jedem iPhone und iPod touchgibt es im Lieferzustand die Anwendung Sett i ngs, die in

großem Umfang mit Schaltern arbeitet. Abbildung 3-1 zeigt die Safari-Optionen, die sich da­

mit ändern lassen. Für die Entwickler von Web-Apps stellt diese Vermeidung von Options­schaltflächen und Kont rollkästchen ein Dilemma dar.

Die Dashcode-Anwendung, die zum Entwickeln der Benutzerschnittstel le für Web-Apps

verwendet wurde, weist kein Widget für Schalter auf; es lässt sich jedoch leicht erstel len.

Es besteht aus einem Kasten mit eingelassenem Rand mit zwei Textelementen, OFF und

ON, sowie einer Scha ltfläche.

M ith ilfe der Handbewegungsereignisse der Scha ltfläche können Sie sie veran lassen, nach

rechts bzw. links zu gleiten, sodass sich für den neuen Schalter zwei Zustände ergeben. Mit der Ca llback-Funktion onges tureend, die Sie fü r die Schaltfläche definieren, stellen

Sie fest, ob es sich um den Zustand ON oder OFF handelt, und speichern ihn. Abbi ldung

3-1 zeigt die Schalter, die dem Benutzer zur Verfügung stehen, um die Einstellungen der

Safari-Anwendung zu ändern. Gesta lten Sie Ihre Schalter genauso.

70

Page 72: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Listen- und browsergestützte Schnittstellen

Befolgen Sie diese grundlegenden Gestaltungsregeln, dann erfüllt Ihre Anwendung die

Anforderungen für die Verteilung im Apple Store und die Erwartungen der Benutzer an die

Funktionsweise Ihrer Anwendung. Die Verletzung dieser Konzepte setzt sie dagegen dem

Risiko aus, sowohl von Apple als auch von potenziellen Benutzern abgelehnt zu werden.

Gonoral

r Search Englno

Security

Google >]

~ Abbildung 3.1: Die Schalter in der Anwendung Settings für Safari

3.2 LISTEN- UND BROWSERGESTÜTZTE SCHNITTSTELLEN

Einer der grundlegenden Benutzerschnittstellentypen fü r iPhone-Anwendungen bewältigt

die Anordnung innerhalb der Schnittstelle mithilfe von Listen. Die Qu ickConnect-Beispiel­

anwendung Hi story Exampl e gehört dazu. ln Dashcode lässt sich diese Schnittstelle auf

zwei versch iedene Arten erstellen. Am schnellsten geht es, wenn Sie das Element Browser

verwenden.

Es ist in der BibliothekEl emente zu finden und lässt sich di rekt in Ihre Anwendung ziehen,

wodurch ein Stapel unabhängiger Ansichten angelegt wird. Ansichten sind die Hauptan­zeigeeinheit, mit der es Benutzer zu t un haben; sie werden häufig fa lsch als Bi ldschi rme

bezeichnet. Wenn einer Anwendung ein Browser - El ement hinzugefügt w ird, werden

zwei Standardansichten eingefügt, der Code zum Umschalten zwischen ihnen jedoch nicht. Außerdem bekommt sie automatisch einen Header mit einer Navigat ionsscha ltfläche. ln

Abbildung 3-2 sehen Sie Das hcode nach dem Hinzufügen des Elements Browser.

71

Page 73: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

Die automatisch in den Header eingefügte Schaltfläche braucht nicht geändert zu wer­

den, weil das B r owse r- El ement den darin angezeigten Text durch den des Headers der

vorherigen Ansicht erset zt (fa lls es eine gibt). Ändern Sie beim Erstel len einer Anwendung nicht den Text der Schaltfläche, sondern den des Headers, damit er den Namen der An­

wendung oder etwas anderes Passendes anzeigt.

@ I"\ I"\

~. II r::J. , AusfOIHetl P<lv~ Dar~td!u119

B ohneTirc.l

S tOt'ltent

Unbenannt

fJD Q S.IL"'E'M

lnfo•ma.tl011~11 &ibloltli!St S11<htrt -~· , ,, 1 !d;' , , , , ,, i.bb ' ' , • , , , 1.,•, ,, , , ,, , llbö' , , , ~, , , • • ,, Ii&', •, ,, , , LtSo' , , ,, •, • isül , , _ N

[3 'l:i' •·'-.,.""', -----c ~ P'rogo~mrn.ltlributc

§ Webd tp -Symbol

~A..sfUI'Ir~o& rteigt !>tr'l

Oberfläche gestatten

ßt>'~cgcn 5le Ob:lt~u: t)IJ) dc• &bliOCII~It. itl d~t'l A.fbt H.t:'Je(e!d l uno Jo"'C~rn s,e a1e GgttHC.h;);ften derObjette •n den l11form~tioncn.

81tiiiOttltk. Ar'ooitsbereich klfcwmaliOilen

<..._ Ha neUer & Code ... ~

\. Attribute festlegen

\ Webd i p- Symbol entwerfen

\. TUltn & Ffeigeben

o· "' e s

~~

-:-o

DeveiOped V<th Oas!CO<le

~ Abbildung 3.2: Eine Dashcode-Anwendung nach dem Hinzufügen des Parts Browser

Beim Hinzufügen des Browser - El ements zu einer Anwendung werden zwei benannte

Standardansichten in das Projekt eingefügt. Nachdem Sie eine dieser Ansichten im Pro­

jektbaum von Dashcode ausgewählt haben, sehen Sie die j ewei ligen Eigenschaften auf

der ersten roten Registerkarte des Informationsdialogs und können sie umbenennen. Ab­

bi ldung 3-3 zeigt die Beispielanwendung Hi stor y, nachdem die Ansichten in ma i nV i ew und pres i dents Vi ew um benannt wurden. Beachten Sie die Optionen + und - für die Liste

subv i ews innerhal b des Infor ma t ionsfenst er s nach Auswa hl von St ackl ayou t

im Projektbaum. M it diesen Schaltflächen können Sie weitere Ansichten hinzufügen und

nicht benötigte entfernen.

72

Page 74: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Listen- und browsergestützte Schnittstellen

Sämtliche Ansichten in der Anwendung werden in der Liste Subvi ews verwaltet. Beach­

ten Sie, dass sämtl iche Ansichten direkte Abkömmlinge des Stapellayouts sind, obwohl

die Navigation der Anwendung ma i nVi ew_Cont i nentsVi ew_SouthAmeri canV i ew

lautet. So sollten Anwendungen dieser Art entwickelt werden.

ln den beiden Listen Rounded Rectangl e und Edge - to - Edge lässt sich in der Schnitt­

stellenentwurfsansieht in Dashcode nur der j eweils erste Eintrag auswählen. Er dient als

Vorlage für die anderen Einträge. Alle Farb-, Inhalts- oder Größenänderungen, die Sie an

ihm vornehmen, werden auf die übrigen Listenelemente übertragen. Dazu gehören auch

die Ereignislistener, die Sie zuweisen. Alle Elemente in den Listen der Anwendung H i s to r y

haben denselben Listener für Klickereignisse, nämlich die Funktion cha n geV i ew.

Die Funktion c hange V i ew steht in der Datei ma i n . j s und kommt im folgenden Code vor. Sie ermittelt mith ilfe der im Attributbildschirm des Informationsfensters der Ansicht ein­

gegebenen Label und Werte, welche neue Ansicht angezeigt werden soll. Um die Funktion

einzusehen, wählen Sie nicht das erste Labelelement aus, sondern die Ansicht selbst. ln

Ihrer Anwendung ist dies die Stelle, an der Sie statische Listenelemente hinzufügen, wie

Sie in Abbildung 3-4 sehen.

@) ()() """"Y""""'""' ~. II CJ.

Au fehrc:n '~"''t o.f)(t1h.lfl9

.. E!!I ( (I(;tcf'lt

,.(E) t.-o ... ::;er

.. 8ht~~tl ~ Q:J ~l.l&l.ayoul

• S rt~l,..\l!tw

o- (i3 Pt-u .dc1n 'lie ...

o- (3 lth1oriu lri911U:)V •.

o- {3 COtltifl(fll$ViC:w

.. 83 SoJtl\>\mt"u~v,e.,..

U we: bd ip-S)'tl'lbol

-

:=

~- :: @ G'.' 111 {!: >:!

Presidan1s

Historlcal Flgures

Continents

Cantries

HistoricaJ Places

.,. Abbildung 3-3: Die Anwendung Hi s t oryExamp l e mit Ansichten und zwei Listen in Form

abgerundeter Rechtecke innerhalb der Hauptansicht

73

Page 75: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

f unction changeVi ew( event ) {

var subVi ewName = event. t arget .obj ect.val ue; va r displayName = event. t arget . i nnerText; var br owser = document.get Elementßy i dC'browser' ) .obj ect; browser .goForward( subVi ewName+'View'. di splay Name) ;

Verwenden Sie diese Werte und benennen die Ansichten entsprechend, wechselt die Me­

thode go Forwa r d des Obj ekts b rowse r korrekt zur nächsten Ansicht. Die Methode weist

zwei Parameter auf Der erste ist der Name der Ansicht, zu der geschaltet werden soll,

der zweite der im Header der Ansicht anzuzeigende Text. Wenn Sie versuchen, zu einer

Ansicht umzuschalten, und sich zwar der Header, aber nicht die Ansicht ändert, ist der

Name der Zielansicht in Ihrer Anwendung nicht vorhanden.

' ~ H i!otOryEJC.tn.p le

-r (3c:etltent

, 8 bi.O'Nfi(t'

•8 hudtr

• tä stael<LJ.;oout

•EJ rn~TIV<(W

.. Eil p!uu

,. 8 f'l'e!oiGt'ltSVitM

,. 8 H•S(~fiC.1!f • 9~o~f~SV<

"' 8 (OIIIIOl'tltSYttW

• (3 S&;t'liAfl'e~tUrV~

0 · :: 0 E:

~~ Llo~_ l I I I I I I l.~öl; I I I I I I I j0

1 I I I I I I I I itb_? I I I I I I I lzbJ I I I I I I I j ~!);' I I I I I I I j4U I I I I I I I j~i I I Ii

t " t r

r= w ~

;

~0 ~ ~ :: r! " c ~

~-

~ r-. ~~ c E ~ ü

P' c r F ~ ~ c

1111!: >=

() "' r. Attr Outc (oeoo;:~ d

~ r9 ..9 T ~ G

Klasse

AnU:iQ(I ~ !iclub.u "-"'=~----=---! lt . .S:...IiJ.otdtt.IJ.ltl.!e.<.cn

Historical Figures

Continems

Contrtes

Historical Places

C Ocslorr-Gv.c!e

Allswahl ei Au~W:l'll .3iro\'1f!l'en

J "4e"l·e•cer.~~obt

~ l.etfc- Ct lt ubM

Coru;nenu

6utidillu,mg Wtrt Pre!Oid :llt! P1uide.nt~

,, tt iSrofieal r-i9u·e' Hlu Otlc;JiriOu ti!S

"" Abbildung 3.4: Die Anzeige der Personenlistenattribute von mainView mit zwei hinzugefügten statischen Elementen

74

Page 76: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anwendungen mit nicht auf üsten beruhenden Ansichten

Achten Sie beim Erstel len von Iisten- und ansichtsbasierten Anwendungen darauf, die

Daten korrekt anzuordnen. Sind die Informationen in zu vielen Ansichten verstreut, emp­

findet der Benutzer die Navigat ion als übermäßig mühsam. Gehen Sie nicht sorgfä ltig

vor, erfinden Sie möglicherweise die auf DOS beruhende Navigationssteuerung aus den

197oer- und 198oer-Jahren neu.

Für Iisten- und ansichtsgestützte Anwendungen gibt es viele Einsatzgebiete, aber sie sind

nicht unbedingt die optisch ansprechendsten. Gelegentlich ist etwas anderes als eine

Liste erforderlich, um den Wechsel der Ansicht auszulösen. Solche Anwendungen werden

als Anwendungen mit nicht auf Listen beruhenden Ansichten bezeichnet.

3.3 ANWENDUNGEN MIT NICHT AUF LISTEN

BERUHENDEN ANSICHTEN

Obwoh l Iisten- und ansichtsgestützte Anwendungen zahlreiche Einsatzgebiete haben,

gibt es keine Regel, nach der al le ansichtsgestützten Anwendungen für den Zugriff auf

Informat ionen Listen benutzen müssen. Andere optische Indikatoren können darauf

hinweisen, dass bei Berührung eines Elements weitere Informationen angezeigt werden.

Die Beispielanwendung Pi cture Examp l e im QuickConnectiPhone-Download enthält

solche Hinweise.

Wird auf dem Display darauf hingewiesen, dass etwas berührt werden soll, neigt der

Benutzer dazu, Dinge zu berühren, um zu erfahren, ob sie aktiv sind. Wählen Sie diesen

Ansatz, sol lten Sie darauf achten, die Zielbenutzer durch diese Hinweise oder durch das,

was sie zum Steuern der Anwendung berühren sollen, nicht zu verwirren.

Der folgende Code unterscheidet sich in einigen Punkten vom vorhergehenden. Zum ers­

ten benötigt jedes Bild entweder einen onc l i c k- oder einen ontouchs ta rt -Listener, um

eine Änderung an einer Unteransicht auszulösen. ln diesem Beispiel werden beide berühr­

baren Bilder von einer einzigen Funktion, goSub, behandelt.

function goSub(event) {

var stacklayout = document.getEl ementBy l d( ' stack l ayout') .object; stack l ayout.setCurrentView(event . target .id+' View ' . fa l se ) ;

Dadurch, dass jedes Bild eine ID hat, die dem Namen der Ansicht entspricht, fü r die es steht,

ist es kein Problem, nur eine Methode zum Wechseln der Ansicht zu benutzen. Wie das

vorstehende Beispiel zeigt, hat das Stacklayout-Objekt eine Methode setCurrentV i ew,

75

Page 77: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

die zwei Parameter übernimmt: die ID der Ansicht, zu der gewechselt werden soll, und

ein Flag. Ist das Flag auf t r ue gesetzt, gibt es an, dass der beabsichtigte Wechsel rück­

wärtsgerichtet ist. Die beiden Parameter geben dem Programmierer die Möglichkeit, das

Verha lten der Übergänge zwischen den Ansichten zu steuern.

Im Unterschied zur Anwendung Hi st oryExampl e, die aus einer vorher erstellten Liste,

Ansichten und einem Navigationsheader besteht, besitzt die Anwendung Pi c t u re Exa mp l e

keine integrierte automatische Navigationsleiste. Deshalb muss der Programmierer, der An­

sichtswechsel von einer untergeordneten zurück zu einer übergeordneten Ansicht vorsieht,

den Code selbst schreiben.

Anders als die Bilder in der Hauptansicht sollen die BACK-Bi lder einen Wechsel zur Haupt­

ansicht veranlassen. Da es ungeschickt ist, einen rückwärtsgerichteten Übergang genau­

so aussehen zu lassen w ie einen vorwärtsgerichteten, erhä lt der zweite Parameter der

Funktion setCur rentV i ew den Wert true, was besagt, dass ein rückwärtsgerichteter

optischer Übergang erforderlich ist.

Der folgende Code von goMa in ist als on c l i c k-Listener mit der Scha ltfläche BACK ver­

knüpft. Ihm wird als zweites Argument true übergeben, was dazu füh rt, dass der mit

ma in Vi ew verkn üpfte Übergang in umgekehrter Richtung wie das Standardverhalten ab­

läuft. Auf diese Weise ist es mögl ich, dem Benutzer den Eindruck zu vermitteln, dass eine

vorhergehende Aktion rückgängig gemacht w ird.

f unction goMain (event ) {

II Di e aktuell e Ansicht ei nes Stackl ayout s f est l egen var Stack l ayout = document.get El ementßy l d( ' sta ckl ayout ' ) . obj ec t ; sta cklayout.setCur r entView( ' ma i nView', true) ;

Ein weiterer Unterschied zu browsergestützten Anwendungen sind die Optionen für die

Art der Animierung des Übergangs beim Wechsel der Ansicht. Sie ähneln den übrigen

Informationen, die der Benutzer bekommt. Wird für den Übergang zu einer Ansicht ein

anderer Typ gewählt als für die anderen, ist mit dieser Ansicht etwas anders. Abbildung 3-5

zeigt die Liste der Unteransichten und die Funktion goMai n in Dashcode.

Wie in Tabelle p gezeigt, können Sie in Ihren Anwendungen mehrere Übergangsarten ver­

wenden. Es ist zwar möglich, eine Vielzahl von Übergängen einzusetzen, wäre aber unklug.

76

Page 78: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anwendungen mit nicht auf üsten beruhenden Ansichten

~ !!,. EJ. AUsfGII~n ravs~ DotfSt~lung

·~intf02 • Gh )taÖ~I

• EJ nui!IV~w @S I.ondon

'ir UXl

~ Yelicrwuone

~ttl<t!

'E tfXI1

"EJ Lo•!don'v~ew

l!!l tmo5 l'$ buu <rl

~ lnl9

~ !mgl @!! o t~lg !

(g imgZ

@! 11'119"'

Jt li,u'<CiOM jS

'!• lfldt X.html

c• m.:in,<H

~ mdnJs ;s m.)l)l)inps.,s

~ ... '·'"'

II II r41ncliot~ locd() II Col'hd by lfnoll bti!Cy "\D'Mint ' ~; cntoad .. vont "'""" t-M v.flb II ( un.::tton leodO (

ful'lc·h o l'l goSuO(ovtn t ) (

vor ~tcckLayout .. docU!I!Cnt . geH lementiyld( ' ~tccktayout' ) .objecl; s tockloyout:. sttCvrf' tntVi.tlll(evtnt. tof'get. t d .. ' Yi nr' ):

AU! DUtt Ul~(~l3~·0~oU

c9&> T ~e

to ~utld...syout

Allttlgt E:1 Si tiltO.lf

Subview,

10

,." S.tl .. CJtl'lb Cl .1r2to~r

O outon-Gutde

G] rnJ.!nVICW

8 LondonV!ew

l3 Vcllow~toneVitw

~o .._ QCoP'hOI"'e ~-

( unctton gclNot n(event ) ( tlber'g3.rtg (SubV1Ew)

~~r s::o~~~o~~:~~t d:~:C~~ . :c::~r:~~~~~~d{ ' slc(kLoyowt' ) .objc:~t ; ~ -""',.-,-'"".."'--,"'.,.."-,'"' ""'"""'~~q stcu::lcl.oyout . ntCvrr(lntvio•('no\nV\(>~' , trvt): O..u.er 0.55 r:) s.ea:uAden

2titv<:r hod t c:n Hincirt-/Hin.aw5bt'""C9<:n 1)

~ Abbildung 3.5: Der Bildschirm Stacklayout Attributes mit dem Übergang

Quelle: http:! /creativecom mons.org!/icenses!by-sa/3. o!deed.de

Übergangstyp Verhalten

push (verschieben) Ein zweidimensionaler Übergang, bei dem sich die

anzuzeigende Ansicht in den sichtbaren Bereich schiebt,

während die alte ihn verlässt.

d i sso l ve (auflösen) Ein zweidimensionaler Übergang, bei dem die anzuzeigende

Ansicht undurchsicht iger w ird, die alte dagegen durchsichtiger.

s l i de (schieben) Ein zweidimensionaler Übergang ähnlich wie pus h. ln diesem

Fall bleibt die alte Ansicht an Ort und Stelle, während die neue

von oben darüber zu gleiten scheint. Der Benutzer gewinnt den

Eindruck, sich durch einen Stapel von Ansichten zu bewegen.

ln diesem Fall bedeutet ein rückwärtsgerichteter Wechsel, das

Heruntergleiten, eine Abwärtsbewegung durch die Ansichten der

Anwendung, ein vorwärtsgerichteter Wechsel, das Hinaufgleiten,

dagegen eine Aufwärtsbewegung durch den AnsichtsstapeL

77

Page 79: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

fade (überblenden) Ein zweidimensionaler Übergang ähnlich wie di s sol ve. ln

diesem Fall bleibt die alte Ansicht undurchsichtig, sodass

am Sch luss des Übergangs beide sichtbar sind. Erfolgt dieser

Übergang »rückwärts«, wird die neue Ansicht undurchsichtig,

und die ursprüngliche wird vol lständig angezeigt. Dieser

Übergang dient dazu, neue Informationen oder Funktionen

in eine Ansicht einzufügen, wei l beide Ansichten auf

Berührungsereignisse reagieren können.

f l i p (umdrehen) Ein dreidimensionaler Übergang, der eine Drehung um die

y-Achse des Geräts durch das Zentrum der alten und der

neuen Ansicht auslöst. Der Benutzer gewinnt den Eindruck,

die alte Ansicht sei die Vorderseite der Anwendung, die

neue die Rückseite. Dieser Übergang w ird normalerweise in

Anwendungen mit nur zwei Ansichten verwendet.

cube (Würfel) Ein dreidimensionaler Übergang, der fü r den Benutzer so

aussieht, als befänden sich alle Ansichten auf den Seiten eines

Würfels, der sich vor- und zurückdreht.

swap (vertauschen) Ein dreidimensionaler Übergang, bei dem die alte Ansicht zu

einer Seite zu gleiten und sich dann unter die neue Ansicht zu

schieben scheint. Während des Vorgangs ist der Hintergrund

der neuen Ansicht transparent; er wi rd beim Abschluss

undurchsichtig.

revo l ve (rotieren) Ein dreidimensionaler Übergang, bei dem sich die alte und die

neue Ansicht auf der y-Achse des Gerätedisplays um eine Seite

zu drehen scheinen. Der optische Eindruck ähnelt einer Drehtü r.

Tabelle 3.2: Standardübergänge in Dashcode

Die Dashcode-Schnittstelleerwecktden Eindruck,dass nurdie Richtungen r i ght - to - 1 eft

und l eft - t o - r i ght für diese Übergänge zur Verfügung stehen, die sich bewegen. Das stimmt nicht: Auch top - to - bo t tom und bo t t om - to - top ist möglich.

Der folgende Code stammt aus der Datei setup . j s der Beispielanwendung History Examp l e. Er wird von Dashcode erstellt. Wie Sie sehen, fi nden Sie hier die Über­

gangstypen und ihre Richtungen für sämtliche Ansichten. Wol len Sie sie ändern, müssen

Sie zuerst die Codeerstellung ausschalten. Dazu benutzen Sie in Dashcode die Option

( ODE-G ENE RATOR STOPPEN des Pu II-down-Menüs DARSTELLUNG.

78

Page 80: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anwendungen mit nicht auf üsten beruhenden Ansichten

var das hcodePartSpecs

" stack l ayout " : { " creati onFunction": "CreateSta ckl ayou t " , " subviewsTransitions": [ { "di rect ion " : "r ight-left " , "dura tion": n "

"timi ng": "ease - in-out ", "ty pe": "pus h" } , { "direction ":" right-left" ,

"duration":" ", "timing": "ease-in-out", "type ": "push" }, {

"direct i on": "r ight - left", "durat ion ": "", "t iming " : "ease- i n -out", " type ": " push " }, { "d i rect ion": "r i ght- l eft", "duration": " " , " timi ng": "ease - in-out", "ty pe": "pus h" }, { "direct ion ": "right­l eft", "dura t ion " : '"' , " t i ming " : "ease - i n - out ", " t ype " : "pus h" } ] }

} ;

Da Dashcode ziemlich viel Code fü r Sie erstellt und den Inhalt der Datei setup . j s re­

gelmäßig aktua lisiert, sollten Sie diese Datei erst ändern, wenn Ihre Anwendung fert ig

ist. Am einfachsten geht es, nachdem Sie sie in der Xcode-QuickConnectiPhone-Vorlage

untergebracht haben, wei l Dashcode dann nicht mehr beteiligt ist und deshalb keine

Änderungen Ihrerseits überschreiben kann. Möchten Sie die Datei bereits in Dashcode

ed it ieren, sol lten Sie aus dem Pu l I-down-Menü Da rs te l l ung den Eintrag Dateien aus­wäh len. ln der darauf erscheinenden Liste der Projekt dateien fi nden Sie im Unterordner

Parts u.a.die setup.js-Datei.

Der vorstehende Code ent hält die Deklaration von vier JavaScript-Objekten. Jedes beginnt

mit einer öffnenden geschweiften Klammer ({),endet mit einer sch ließenden geschweiften

Klammer (}) und enthält die Attribute d i rect i on, du ra t i on, t i mi ng und type. Das zweite

Objekt erscheint im Fettdruck, damit Sie es leichter von den anderen unterscheiden können.

Jedes dieser anonymen Objekt e definiert das Verhalten eines Übergangs zwischen

zwei Ansichten. Der fett gedruckte Objektcode deklariert einen Übergang des in Tabel­

le 3-2 beschriebenen Typs pus h. Die neue Ansicht schiebt sich mit allmählich steigender

Geschw indigkeit von links nach rechts hinein und bremst am Ende des Übergangs ab (ease - in - out).

79

Page 81: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

Weitere Zeitoptionen lauten ea se - in, eas e- out und de f aul t. Die letzte bedeutet

konstante Geschwindigkeit und wird benutzt, wenn das Attributtimi ng des Übergangs­

objekts in der Definition nicht gesetzt ist.

Wie bereits erwähnt, gibt es für die Richtung des Übergangs noch die Optionen

t op- bottom und bo t tom- top, die nicht bei allen Übergangsarten funktionieren, son­

dern nur bei s l i de und pu s h.

Entscheiden Sie sich dafür, diese Objektdeklarationen zu ändern, sollten Sie wissen, dass es

Probleme geben kann, wenn Ihre Anwendung komplexer ist. Anscheinend hat Apple keine

Möglichkeit vorgesehen, Opt ionen für die Übergangsdefin it ion zu wäh len, wei l sie zu

Feh lverhalten bei dem in Safari verwendeten WebKit-Modul und dem Objekt UIWebV i ew in Web-Apps führen.

3.4 IMMERSIONSANWENDUNGEN

Anwendungen in Immersionsart bedeuten eine deutliche Abkehr von Ansichten als Mit­

tel, um die Anzeige und Steuerung von Informationen in Gruppen zusammenzufassen.

Die gängigste Form derart iger Anwendungen finden Sie in Spielen, aber auch aktuel le

Beispiele von medizinischen iPhone-Anwendungen nutzen diesen Ansatz. Dahinter steht die Auffassung, dass das Zusammenwirken von Benutzer und Anwendung natürlich, fl ie­

ßend und nach Mögl ichkeit innerhalb einer Ansicht stattfinden soll.

Obwohl dieser Ansatz in seiner extremen Form in Spielen verwendet w ird, kann er auch

auf andere Art eingesetzt werden. Die medizinischen lmaging-Anwendungen zum Bei­

spiel benutzen ihn und die Berührungsfähigkeiten des iPhones, um die Interaktion von

Ärzten mit medizinischen Bildern erheblich zu verändern.

Es gibt keinen Grund daf ür, dass innovative Anwendungsersteller diesen Ansatz nicht im Geschäftsleben oder in der Wissenschaft nutzen sollten. Ein Grund fü r sch lechte Unter­

nehmensentscheidungenliegt darin, dass sich miteinander zusammenhängende kompl i­

zierte Daten mit den einfachen Diagrammen und Graphen, die heute verwendet werden,

nur schwer sichtbar machen lassen. Um sie auf andere Art zu betrachten, muss eine neue

Methode der Darstellung herangezogen werden.

Lassen sich Daten optisch in einer nichtlinearen Form anzeigen, die den gesamten Bildschi rm

umfasst, können damit zusammenhängende Daten als Overlay benutzt werden, um Bezie­

hungen zu finden. Eine einfache Form dieses Ansatzes ist die Fähigkeit der Kartenanwend ung,

nicht nur eine Route von einem Ort zu einem anderen auszugeben, sondern auch die Ver­kehrsdichte auf und in der Nähe der Route. Dabei werden zwei Informationsteile übereinan­

dergelegt, damit der Benutzer ein sinnvolles Muster erkennen kann.

80

Page 82: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

lmmersjonsanwendungen

Dieses Buch gibt nicht vor, einen Ansatz f ür die Bearbeitung von Daten f ür die Anzeige zu

liefern. Es legt lediglich nahe, dass es gemacht werden kann und gemacht wird. Als Bei­

spiel in diesem Abschnitt dient ein Spiel.

Das SpielDol l a r Sta sh ist eine Variante der Beispiel-Webanwendung Leaves von Apple,

in der eine Folge von Bildern in eine Seite eingefügt wird, die allmäh lich auf den Boden

des Bildschirms fallen und sich dabei winden und drehen. Um daraus ein Spiel zu machen,

wurden aus den Blättern Symbole f ür Geld gemacht.

Berührt der Benutzer einen Schein, dann steigt der Geldbetrag auf seinem Konto um 1.

Wenn ein Schein vollkommen verblasst und verschwunden ist, bevor er berührt wird, sinkt

der Kontostand des Spielers um 1. Am oberen Bildschirmrand erscheinen Gruppen von

Scheinen in Wellen. Jede Welle enthält einen Schein mehr als die vorige. Sinkt der Konto­

stand des Spielers unter o, ist das Spiel zu Ende. Abbildung 3.6 zeigt ein laufendes Spiel.

Obwohl das Spiel schnell erstellt w urde, zeigt es deutlich eine der Einschränkungen derar­

tiger Anwendungen in einer Webumgebung auf.

~ Abbildung 3.6: Das Spiel DollarStash

in Betrieb

Das Obj ekt U I WebVi ew verwendet dasselbe WebKit-Modul wie Safari und andere Anwen­

dungen, um den Bi ldschirm zu berechnen. Dieses und andere ähn liche Module haben in

den vergangenen Jahren erhebliche Fortschritte gemacht. Ein ihnen gemeinsames Prob­

lem besteht darin, dass Benut zerschnittstellenereignisse wie Klicks und Berührungen

ignoriert werden, wenn der Prozessor stark belastet wird. Wenn Sie DollarStash nicht im

Simulat or, sondern auf Ihrem Gerät spielen, stellen Sie fest, dass es st immt.

81

Page 83: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

Mit zunehmender Anzah l von Scheinen steigt auch die Anzahl der Berührungen, die das

Modul nicht ausführt. Dem Benutzer solche Unannehmlichkeiten zuzumuten, verletzt

eine Grundregel unseres Schnittstel lenentwurfs, die im ersten Abschnitt dieses Kapitels

genannt wurde: schnel le Reaktion auf Benutzereingaben.

Die benutzeraktiven Tei le dieser Art von Anwendungen lassen sich am besten in Objective-C

schreiben, was nicht heißt, dass Anwendungen kein U I WebV i ew-Modul für komplexes Text­

layout oder einfache Bi ldausgaben benutzen können, sondern dass es nicht sinnvol l ist, die nativen (55-Transformationen und -Animationen (Cascading Style Sheet) zum Erstel len

komplexer Spiele zu verwenden, bevor die iPhone- und iPod touch-Prozessoren wesentlich

höhere Geschwindigkeiten erreichen.

Das Wissen um die Einschränkungen Ihres Geräts kann Sie zu besseren Entwürfen füh­

ren. Auch wenn in Web-Apps keine prozessorintensiven Spiele rea lisierbar sind, lassen sich

(55-Transformationen und -An imationen für Drag&Drop, Skalierung und Drehung einset­

zen, solange nur ein einziges Schnittstellenelement betroffen ist.

3.5 ßENUTZERDEFI NIERTE (55-TRANSFORMATIONEN

ERSTELLEN UND VERWENDEN

in diesem Abschnitt erfahren Sie, wie Sie mithilfe der neuen (55-Transformationen im

WebKit -Modul, das von Safari und dem U IWebVi ew-Objekt benutzt wird, Drag&Drop-,

Skalierungs- und Drehfähigkeiten erstellen. Mehr über CSS-Übergänge, -Transformatio­

nen und -Animationen erfahren Sie in der Benutzeranleitung von Apple unter folgender

Adresse: http:l!developer.apple.com/safarilfibrary!documentation/lnternetWeb/Conceptu­ai!SafariVisuaiEffectsProgGuide!lntroduction/lntroduction.html.

Zum Herunterladen stehen mehrereJavaScript-Umsetzungen des Verhaltens in Drag&Drop­

Art zur Verfügung, die sich hervorragend für die browserübergreifende Nutzung auf stati­

onären Rechnern eignen. Auf dem iPhone und dem iPod t ouch versagen sie jedoch, wei l sie

prozessorintensiv sind. Eine gute Alternative stellen j edoch (55-Transformationen dar. Web­

Kit, das von Safari und U I WebV i ew in Web-Apps verwendete Modul, kann Übergänge in CSS definieren. Sie sind hardwarebeschleunigt, wodurch sie effizienter werden als Änderungen

mithilfe von JavaScript wie in anderen Bibliotheken.

Ein einfaches Beispiel ist das Verschieben eines HTML-d i v-Eiements nach unten. Mit

herkömmlichem JavaScript müssen Sie das Attribut top des d i v-Styles verändern. Ange­

nommen, dem d i v ist eine CSS-Kiasse zugewiesen, die das Attribut auf so Pixel von der

Oberkante der Seite setzt, dann wi rd eine Verschiebung um weitere so Pixel nach unten

erreicht, indem man das Attri but auf 100 Pixel setzt:

adi v.sty l e.top = ' lOOpx';

82

Page 84: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Benutzerdefin ierte ( 55-Transformationen erstellen und verwenden

Diese Deklaration wird als JavaScript-Befehl interpretiert und vom Modul mit derselben

Geschwindigkeit und denselben Prozessorressourcen ausgeführt wie jeder andere Ja­vaScript-Befehl. Die (55-Transformation als Alternative funktion iert anders.

(55-Transformationen für eine Änderung der ursprünglich deklarierten Position um so Pixel erfordern ebenfalls die Verwendung der Deklaration des d i v-Stils; es wird jedoch ein

vollkommen anderes Attribut benutzt.

Eins der neuen Attribute in CSS-Kiassen und deshalb auch ein Stilattribut von Element ­

objekten in JavaScript ist webKi tTransform. Korrekt gesetzt ruft es hardwarebeschleu­

nigte native Funktionen auf. Es w ird nicht als JavaScript interpretiert, weshalb definierte

CSS-Attributänderungen wesentlich schneller ausgeführt werden als im vorstehenden

JavaScript-Beispiel.

Das hier gezeigte Beispiel fü r eine Transformation benötigt ebenfa lls nur eine Codezeile:

adiv.styl e.webKitTransform = ' trans l ateY(50px) ' ;

Aufden ersten Blick scheint das Transformationsattribut ein Funktionszeigerwie on c l i c k,

ontouc h und andere Ereignislistener zu sein, ist es jedoch nicht.

Der wesentliche Unterschied zwischen webK i tT ra n s form und den Ereignislistenern be­

steht darin, dass keine innerhalb der Zeile oder als Fensterf unktion deklarierte JavaScript­

Funktion zugewiesen wird, sondern einString mit einer Beschreibung, welche Standard­

funkt ion mit welchen Parametern aufgerufen werden soll. Anschließend w ird dieser

String vom WebKit-Modul in einem Codeabschnitt analysiert, in dem keine JavaScript­

l nterpretat ion stattfindet.

Beachten Sie außerdem, dass der deklarierte Betrag derVersch iebu ng relativ zur ursprü ng­

lichen Position des d i V-Elements ausgedrückt ist. Der Parameter fürtrans l ateY ZurVer­

sch iebung eines Elements um so Pixel nach unten lautet 50 px. Außerdem ist w ichtig, dass die Originaldefin it ion der Position nicht geändert wurde. Dem d i v wi rd im mer noch

der Originalwert 50px fü r top zugewiesen. Geändert hat sich nur die Position, an der

es wiedergegeben wird. Fragen Sie das Objekt nach der Verschiebung ab und geben den

Wert top aus, lautet er weiterhin nicht lOOpx, sondern 50 px.

Die Beispielanwendung Drag zeigt, w ie ein div-Eiement mithilfe einer trans l ate­

Funktion veranlasst wi rd, sich über das Display zu bewegen. Dazu werden dem zu ver­

sch iebenden Element Listener für die Ereignisse ontouc hsta rt, ontouchchange und

ontouc hend zugewiesen.

Berührungsereignisse unterscheiden sich von den in herkömmlichen Drag&Drop-lmple­

mentierungen in JavaScript verwendeten Standardereignissen onc l i ck, onmousedown

und onmouseup. Da eine Berührung aus zwei oder mehr einzelnen Berührungen beste-

83

Page 85: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

hen kann, beispielsweise wenn ein Benutzer zwei oder mehr Finger auf das Display legt,

muss ein Berührungsereignis Informationen über jede einzelne Berührung enthalten.

Jede einzelne Berührung w ird mit ihren Daten in einem Array abgelegt, das ein Attribut

eines Ereignisobjekts mit dem Namen ta rgetT ouches ist. Die Größe dieses Arrays ent­

spricht der Anzahl der Finger, die der Benutzer auf das Element auf dem Display gelegt

hat. Ist es nur ein Finger, beträgt die Größe des Arrays also 1, bei zwei Fingern 2.

Jedes im Array gespeicherte Obj ekt ist vom Typ Touch und besitzt viele der Attribute, die

üblicherweise mit einem Mausereignis in JavaScript verknüpft sind. Tabelle 3-3 beschreibt

die einzelnen Attribute.

Die hier gezeigte Drag&Drop-Umsetzung benutzt die Attribute cl i entX und cl i entY,

weil in der Beispielanwendung kein Bildlauf zulässig ist. ln Verbindung mit Bildlauf wer­

den die Attri bute pageX und pageY verwendet.

Attribut

pageX

pageY

sc reen X

sc reenY

c l i entX

c l i entY

target

Beschreibung

Horizontalabstand von der linken Seite des Gesamtdokuments

einsch ließl ich horizontaler Bi ldlaufdaten

Verti kalabstand von der Oberkante des Gesamtdokuments

einsch ließl ich vert ikaler Bild laufdaten

Horizontalabstand von der linken Seite des Gerätedisplays

Verti kalabstand von der Oberkante des Gerätedisplays

Horizontalabstand von der linken Seite des Anwendungsfensters

Verti kalabstand von der Oberkante des Anwendungsfensters

Das DOM-Objekt fü r das berührte HTML-Eiement

Tabelle 3-3: Attribute der Klasse Touch

Ein Problem bei der Umsetzung von Drag&Drop ste llen »hüpfende« Elemente dar, die zu

Beginn des Ziehens auftreten. Das Hüpfen erfolgt, weil der Benutzer das Obj ekt durch

Berührung irgendwo innerhalb seiner Grenzen ausgewählt hat, die Verschiebung jedoch

auf die linke obere Ecke angewendet wi rd. Wird diese Unterschiedlichkeit nicht behandelt,

»hüpft« die linke obere Ecke des gezogenen Objekts an die Ste ll e, an der der Finger des

Benutzers zu Beginn des Ziehvorgangs liegt.

84

Page 86: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Benutzerdefin ierte ( 55-Transformationen erstellen und verwenden

Der Benutzer betrachtet dies natürlich als nicht normal. Wählt er beispielsweise den Mit­telpunkt des Objekts aus, um den Vorgang zu starten, erwartet er vernünftigerweise, dass sein Finger während des Ziehens im Mittelpunkt verbleibt. Alles andere wirkt verwirrend. Abbildung 3·7 zeigt die Beispielanwendung Drag in Betrieb.

Um dies zu beheben, weist die Beispielanwendung dem JavaScript-Ereignishandler ontouch sta rt die Funktion setSta r tlocat i on zu, die Sie im folgenden Code und in der Dateimai n. j s des Beispiels finden. Sie fragt die Position des ursprünglichen Berüh­rungsereignisses in x- und y-Richtung von der linken oberen Ecke des Anwendungsfens­ters in Pixeln ab und speichert sie.

1 funct i on setStar t l ocat ion( event ) 2 { 3 var el ement = event . ta rget; 4 el ement.offsetX event . ta r getTouches [O ].cl i entX; 5 el ement.offsetY = event . ta r getTouches [O ].cl i entY; 6

Indem sie diesen Abstand in Form der Attribute offsetX und offsetY des berühr­

ten Elements festhä lt, kann er später beim Ziehen des Elements benutzt werden, um

das Hüpfen zu verhindern. Die eigentl iche Bewegung des Elements erfolgt nicht in der Funktion setSta r tlocat i on, sondern in der Funktion drag, die als Ereignislistener ontouch chan ge zugewiesen w urde. Sie steht ebenfal ls in der Datei ma i n. j s.

I I

~ Abbildung 3-7: Die Beispielanwendung Drag nach der Verschiebung des grünen div-Eiements

85

Page 87: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

Wie im folgenden Code gezeigt, ist Zeile 3 in der Ziehfunktion wesentlich für alle Drag&Drop­Umsetzungen für iPhone und iPod touch. Wenn ein Änderungsereignis aufgrund von Berührung ausgelöst wird, erfolgt im Browser Safari oder in UIWebView normalerweise ein Bildlauf Um dieses Verhalten auszuschalten, muss das Ereignis eine entsprechende Anweisung erhalten, was durch den Aufruf der Ereignismethode preventDefaul t ge­

schieht. Wird die Methode innerhalb eines ontouc hchange-Listeners aufgerufen, läuft die Ansicht bei einer Fingerbewegung innerhalb des Elements, dem der Listener zugewie­sen ist, nicht weiter.

Die Befreiung vom Standardbildlaufverhalten gibt Ihnen die Möglichkeit, die Position, an der das Element wiedergegeben wird, mith ilfe von webKi tTransform zu ändern. Dazu

muss die aktuelle Position der Berührung festgestellt und mit der ursprünglichen ver­glichen werden, die in der Funktion setSta rtlocati on abgelegt ist.

1 function drag(event) 2 { 3 event .p reven t Defaul t ( ) ; 4 var el ement = event . t arget; 5 el ement.x event . targetTouches [ O].c l ientX 6 - event .target.offsetX: 7 el ement.y event . targetTouches [ O].c l ientY 8 - event.target .offset Y: 9 if( el ement . l astX I I el ement . l astY) { 10 el ement.x += el ement. l astX; 11 el ement.y += el ement. l astY : 12 13 el ement . sty l e .webkitTransform = ,trans l ate ( . 14 + el ement.x + ,px, . 15 + el ement.y + . px)': 16

ln Zeile 5 bis 8 des vorstehenden Codes wird der Betrag f ür den Abstand in x-u nd y-Rich­t ung bei der Wiedergabe des Elements berechnet. Diese Abstände in Pixeln werden zur

späteren Verwendung in den Attributen x und y des aktuellen Elements gespeichert und anschließend in Zeile 13 bis 15 fü r die Änderung der Anzeige mithilfe der bereits beschrie­benen Funktion trans l ate benutzt.

Da dieser Ziehvorgang möglicherweise nicht der erste ist, den der Benutzer für ein Ele­ment durchgeführt hat, ist es erforderlich, die früher verwendeten Abstände zu verfolgen

86

Page 88: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Benutzerdefin ierte ( 55-Transformationen erstellen und verwenden

und zu berücksichtigen. Sie werden in Zeile 9 bis 11 des vorstehenden Codes angewendet

und in der Methode done abgelegt, die folgt. Sie ist als Listener ontouch zugewiesen.

function done(event ) {

var el ement = event.target; element. l astX el ement . x: element. l astY = el ement .y ;

Die Methode done ist nur aus einem einzigen Grund vorhanden: um den aktuellen Betrag

des Abstands zu speichern, falls der Benutzer das Element noch einmal zieht. Dazu legt

sie die aktuellen Attribute x und y des Elements in den Attributen l astX und l astY ab.

Dadurch stellt sie sicher, dass sie verfügbar sind, wenn der Benutzer seinen Finger über

das Display bewegt und eins der on t ouc hc hange-Ereignisse ausgelöst wi rd.

Dadurch, dass Sie diese drei Methoden als Listener in die Elemente Ihrer Benutzerschnitt­

stel le eingefügt haben, kann der Benutzer die Elemente auf einfache Art ziehen. Im nächs­

ten Abschnitt erfahren Sie, w ie Sie ein leichterverwend bares, wen iger banales Drag&Drop­

Modul erstel len und einsetzen.

Außer Drag&Drop benötigen iPhone-Anwendungen häufig die Fähigkeit , Elemente der Schnittstelle zu skalieren und zu drehen. Dabei kann es sich um d i V-Elemente, Schalt ­

flächen, Bilder oder andere Anordnungs- oder optische Elemente handeln. Der dazu erfor­

derliche Code ist interessanterweise wesent lich knapper alsfür Drag&Drop. Es ist kla r, Apple

möchte, dass Techniker und Entwickler dieses Verhalten in ihre Anwendungen integrieren.

Die Beispielanwendung Gestures zeigt, wie sich Ska lierung und Drehung einfach verwirk­

lichen lassen. Gesten unterscheiden sich von Berührungen darin, dass sie grundsätzlich von

der Betei ligung mehrerer Finger ausgehen und Benutzerverhalten w ie Pinch einschließen.

Um diese Gesten darzustellen, wi rd ein GestureEvent an eine auf Gesten lauschende

Funkt ion übergeben. Weil es sich um Gesten handelt, entha lten diese Ereignisse keine

Positionsinformationen wie Berührungsereignisse. Wie Sie in Tabel le 3·4 sehen, umfassen

sie drei interessante Informationen.

87

Page 89: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

Attribut

sca l e

Beschreibung

Ein positiver oder negativer doubl e-Wert, der die Abstandsänderung

zwischen zwei Fingern wiedergibt, die bei einer Geste benutzt werden.

Negative Werte besagen, dass die Finger gekreuzt sind. Dieses Attribut

wird bei der Behandlung von Pinch-Gesten verwendet.

rota ti on Ein positiver oder negativerdoubl e-Wert in Grad, der den Drehabstand

zwischen der Position von zwei Fingern und einer senkrechten Linie

wiedergibt, die bei einer Geste benutzt werden. Dieses Attribut w ird bei

der Behandlung von Drehgesten verwendet.

target Das DOM-Objekt für das HTML-Eiement, in dem die Geste erfolgt ist.

Tabelle 3.4: Die wichtigen Attribute von GestureEvent

Die Beispielanwendung Gestures verwendet diese drei Ereignisse, um ein d i V-Element

zu skalieren und zu drehen. Dazu fügt sie dem Element selbst einen onges t urechange­

Ereignishandler mit dem Namen changelt hinzu. Dies geschieht mithilfe der Register­

karte Beha v i o rs des lnformationsfensters. Der Code dafür lautet wie folgt:

function change l t ( event) {

event . pr even t De f aul t () ; var el ement = event.ta rget;

el ement.sty l e . webki t Tr ansf orm= ' r otateZ ( '+event .rotat ion + ' deg ) sca l e( ' +event.scale+ ' ) ':

Beachten Sie, dass das Standardverhalten des Ereignisses genau wie in der Beispiel­

anwendung Drag ausgeschaltet werden muss, um den Bi ldlauf zu verh indern. Im Gegen­

satz zur Anwendung Dr ag werden die Dreh- und Skalierungsdaten nicht gespeichert. Das

Speichern der Drehinformationen ist nicht erforderl ich, weil es nicht relativ zum transfor­

mierten Obj ekt, sondern zu einer Grundlinie erfolgt.

Die Skalierungsdaten sollten gespeichert werden, damit sie bei der nächsten Geste be­

nutzt werden können, wei l sie relativ zum transformierten Element sind und kumulativ

w irken. ln der Beispielanwendung und im vorstehenden Code wurde darauf verzichtet,

um Ihnen den Skal ierungsfehler zu zeigen, den der Benutzer der Anwendung sieht, wenn

es nicht geschieht. Der nächste Abschnitt zeigt Ihnen, wie Sie Skal ierungsdaten speichern

und wiederverwenden.

88

Page 90: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Benutzerdefin ierte ( 55-Transformationen erstellen und verwenden

Beachten Sie, dass in dem String, der das Attribut webKi t Tra ns form defin iert, zwei Funk­

tionen benutzt werden. Damit können Sie das d i V-Element in einem Aufruf drehen und

ska lieren. Sie lassen sich auch trennen und bedingt einsetzen.

Beim Erstellen Ihrer Anwendung stehen Ihnen drei Drehfunktionen zur Verfügung. Jede

dreht das Element Ihrer Wahl um eine der Achsen Ihres iPhones. Die x-Achse verläuft

horizontal, die y-Achse vertikal, und die z-Achse ragt aus dem Display heraus. Die Funktion

rota teZ besagt, dass sich das d i v-Eiement auf der x-y-Ebene des Geräts drehen soll wie

in Abbi ldung 3-8.

~ Abbildung 3.8: Die Funktion rotatel von webKitTransform

Die Drehung lässt sich leicht ändern, sodass sich das d i v-Eiement anders dreht. Verwen­

den Sie im Beispiel rotateY, dreht es sich um die y-Achse und scheint näher zu kommen,

bevor es seine Rückseite zeigt. Ändern Sie die Drehung in r otateX, dreht sich das d i V­

Element um die x-Achse und scheint kürzer zu werden, bevor es seine Rückseite zeigt.

Möglicherweise erwägen Sie, mithilfe der Drehung einen Cover-Fiow zu implementieren.

Als dieses Buch geschrieben wurde, war dies nicht ratsam. Wegen der für ein derartiges

Verhalten erforderlichen Anzahl von Transformationen überlastet jede Umsetzung den

iPhone- oder iPod touch-Prozessor, sodass der Benutzereindruck unbefriedigend ausfällt.

Nachdem Sie bisher banale Implementierungen von Drag&Drop, Ska lierung und Drehung

kennengelernt haben, sind Sie in der Lage, ein ausgefeiltes Umsetzungsmodell zu verstehen.

89

Page 91: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

3.6 EIN MODUL FÜR DRAG&DROP, SKALIERUNG UND

DREHUNG ERSTELLEN UND VERWENDEN

Wie in Kapitel2, »Die Modularität von JavaScript für iPhone-Anwendungen«, beschrieben,

sind Module in ihren Funktionen vollständig und unabhängig. Anders ausgedrückt: Sie

sind lose an den übrigen Code der Anwendung gekoppelt und weisen engen Zusammen­

halt auf. Gut gestaltete Module sind mit einer API ausgestattet.ln Tabelle 3-5 sehen Sie die

API, die in diesem Abschnitt implementiert wird.

Funktion Parameter Beschreibung

ma keDraggable e l emen t (erforderlich)- Diese Funktion richtet die das zu ziehende DOM-Element Ereignisl istener für das

sta rtDragCmd (optional) -übergebene Element ein,

ein Befehl, der Steuerfunktionen sodass der Benutzer es

zugewiesen wi rd, die am Ende ziehen kann.

des Ereignisses on t ouchsta rt

aufgerufen werden

dragCmd (opt ional)-ein Befehl, der

Steuerfunktionen zugewiesen w ird, die am Ende aller ontouc hmove-

Elemente aufgerufen werden

d ropCmd (opt ional)- ein Befehl,

der Steuerfunktionen zugewiesen

w ird, die am Ende des Ereignisses

on t ouchend aufgerufen werden

ma keChangeabl e e l emen t (erforderlich) - Diese Funktion richtet

das zu skalierende und zu drehende die Ereignisl istener für DOM-Element das übergebene Element

sta rtChangeCmd (opt iona l)-ein, sodass der Benutzer

ein Befehl, der Steuerfunktionen es skalieren und um die

zugewiesen wi rd, die am Ende x-Achse drehen kann.

Der Benutzer kann damit des Ereignisses ongesturesta r t

hoffentlich nicht skaliert aufgerufen werden

werden!

90

Page 92: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Ein Modul für Drag&Drop, Skalierung und Drehung

{Fortsetzung) d ragCmd (optional)- ein

Befeh l, der Steuerfunktionen

zugewiesen wird, die am Ende aller ongesturechange-Eiemente

aufgerufen w erden

doneChangeCmd (optiona l)-

ein Befehl, der Steuerfunktionen

zugewiesen wird, die am Ende

des Ereignisses engestureend

aufgerufen werden

Tabelle 3-5: Die API für Drag&Drop, Skalierung und Drehung

Diese beiden Funktionen sind alles, was der Code aufrufen muss, um Ihrem Benutzer

Drag&Drop, Skalierung und Drehung zu ermöglichen {siehe Abbildung 3-9). Die Beispiel­anwendung dragAndGes t ure finden Sie im Verzeichn is Exampl es, das Sie als Teil von

QuickConnectiPhone von folgender Adresse herunterladen können: https:l/sourceforge.netl project/showjiles.php?group _id=213586.Die Funktionen stehen in der Datei QCUt i l i t i es. j s

des Framewerks im selben Download.

~ Abbildung 3.9: Die Beispielanwendung dragAndGesture wird ausgeführt und ein Element gedreht und verschoben.

91

Page 93: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

Die Ladefunktion aus der Datei ma in . j s, die im folgenden Code enthalten ist, zeigt, wie

diese Funktionen für Elemente in einer Benutzerschnittstelle eingesetzt werden.

f unct ion l oad()

var an El ement = document .get ElementByld( ' button ' ) ; makeDraggable(anElement); makeChangeabl e(anElement); anElement = document.get El ementByld('imageßox'); makeDraggabl e(anElement); makeChangea bl e(an El ement);

anEl ement = document.get El ementßyld('box' ) ; makeDraggabl e(anEl ement); makeChangea bl e(an El ement);

anEl ement = document.get El ementßyld('stuff'); makeDraggabl e(anEl ement);

Im vorstehenden Beispiel werden drei verschiedene Elemente der Benutzerschnittstelle

so geändert, dass sie sich ziehen, skalieren und drehen lassen; das vierte kann nur ge­

zogen werden. Beachten Sie, dass zunächst eine Referenz auf das Schnittstellenelement

abgefragt und der jewei ligen Funktion bzw. den Funktionen der API übergeben wird. Das

genügt, um Ihre Benutzerschnittstellenelemente zu aktivieren.

Die bisher gezeigten banalen Umsetzungen von Drag&Drop, Skalierung und Drehung

in diesem Abschnitt laufen unabhängig voneinander ab. Wie Sie sehen, läuft das vorste­

hende Beispiel darauf hinaus, dass sie in der Lage sein sollen, zusammenzuwirken. Dazu

müssen Sie ggf. die Auswirkungen kennen, die die anderen Aktionen auf das Element

gehabt haben. Die erwähnte Änderung beginnt m it den Funktionen makeDraggable

und ma keC hangeab l e.

Die erste ist fü r die Einricht ung und Verwa ltung der ontouchsta rt-Ereignislistener und

aller Befehle zuständig, die für die Behandlung nach dem Ereignis gesendet wurden.

92

Page 94: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Ein Modul für Drag&Drop, Skalierung und Drehung

function makeDraggab l e(anElement, startDragCmd, d ragCmd, dropCmd ){

anElement .ontouchstart = pr epa reDrag; anElement . isDraggab l e = true; if(startDragCmd){

anEl ement . startDragCmd = startDragCmd:

if(dragCmd) { anEl ement .dragCmd = dragCmd:

if(d r opCmd) { anEl ement .dropCmd = dropCmd:

Beachten Sie, dass das Attribut i sOraggabl e des Elements auf t rue gesetzt ist. Dies ist die

erste Information, die gespeichert w urde, um die Zusammenarbeit der beiden Funktionen

zu ermöglichen. Beachten Sie außerdem, dass in dieser Funktion nur ein Berührungslistener

gesetzt wird, ontouch sta rt. Wenn ein Element skal iert oder gedreht wird, sollen Berührun­

gen nämlich ignoriert werden; weiter hinten in diesem Abschnitt erfahren Sie mehr dazu.

Die Funktion ma keCha ngea b l eist ähn lich. Sie legt die Gestenl istener fest, setzt das Attri­

but i s Cha ngea b l e auf t rue und speichert Befehle nach dem Ereignis zur späteren Ver­

wendung. Anders als die Funkt ion ma keDraggab l e legt sie Gestenlistenerfest, weil beim

Auslösen von Berührungsereignissen wegen der Einzelberührungen beim Ziehen keine

Gestenereignisse ausgelöst werden. Ist ein Element ziehbar und w ird es gezogen, werden

Berührungsereignisse ausgelöst und behandelt. Ist ein Element änderbar und erfolgt eine

Geste, werden sowohl Berührungs- als auch Gestenereignisse ausgelöst, die Berührungs­

ereignisse jedoch ignoriert und die Gestenereignisse behandelt .

function ma keChangeabl e(an El ement, startChangeCmd, changeCmd, doneChangeCmd ){

an El ement.ongesturestart = prepareGesture; an El ement.ongesturec hange = change l t; an El ement.ongestureend = gestureDone; an El ement. i sChangeab l e = true; an El ement.oldRotation = 0; an El ement.oldScal e = 1 : an El ement.startChangeCmd = startChangeCmd: an El ement.changeCmd = changeCmd: an El ement.doneChangeCmd = doneChangeCmd;

93

Page 95: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

in der Methode makeChangeabl ewerden zwei weitere Informationen initia lisiert, näm­

lich die Akkumulatoren o l dSca l e und o l d Rotat ion fü r Ska lierung und Drehung.

in der Beispielanwendung für Gesten nimmt das Element bei jeder Skalierung und Dre­

hung sofort w ieder seine Originalgröße an, weil keine automatische Speicherungfrüherer

Skalierungen zur Verfügung steht. Das Attribut o l dSca l e soll dieses Problem beheben.

Das Attribut o l dSca l e wird mit 1 initialisiert, weil Skalierung ein Mult iplikator für die

Höhe und Breite eines Elements ist (siehe weiter hinten in diesem Abschn itt). Liegt der

Skalierungsfaktor zwischen o einsch ließlich und 1 aussch ließl ich, wird das Element kleiner.

Beträgt er 1, bleibt es unverändert, bei allen anderen Werten wird es größer.

Wenn ein Element bereits skaliert wurde, muss der Ska lierungsfaktor mit dem neuen kom­

biniert werden, um auf die korrekte Größe zu kommen. Wurde das Element beim ersten

Mal beispielsweise doppelt so groß, w ird der Wert von o l dSca l e auf2 gesetzt. Wenn der

Benutzer das Element auf go Prozent seiner Größe zusammendrückt, lautet der aktuel le

Ska lierungswert 2 * o.g, was 1.8 ergibt. Wenn der Wert nicht in o l dSca l e festgehalten

wäre, würde er sofort auf o.g gesetzt, was der Benutzer nicht wollte.

Weiter oben wurde die Funktion prepa reDrag dem on t ouc hsta rt-Ereignislistener

zugeordnet. Wie der folgende Code zeigt, enthä lt sie einige interessante Dinge. Das erste

ist die Speicherung eines Arrays mit Touch-Objekten, w ie sie weiter vorn in diesem Ab­

schnitt beschrieben wurden, damit die Listenerfunktionen der Gestenereignisse Zugriff

auf die berührungsspezifischen Informationen bekommen. Berührungsereignisse müs­

sen zum Beispiel mögl icherweise erfahren, wie viele Berührungen das Gestenereignis

auslösen, was sie nicht aus den Ereignissen entnehmen können, die den Gestenlistenern

übergeben wurden.

1 function prepareDrag(event ){ 2 st opDefaul t (event ) ; 3 t his. t ouches = event .targetTouches; 4 var se l f = th is ; 5 t his. t imeüut = setTimeout(funct ion (){ 6 if(self .changing ){ 7 8

return ;

9 se l f .draggi ng = t rue; 10 se l f . on t ouchmove = dragl t; 11 se l f . on t ouchend = dragDone ; 12 se l f . offse t X = event.targetTouches [ O] .cl i ent X; 13 se l f . offse tY = event.targetTouches [ O] .cl i ent Y; 14 se l f . ol dZindex = self .sty l e . z l ndex;

94

Page 96: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Ein Modul für Drag&Drop, Skalierung und Drehung

15 sel f . sty l e.z l ndex = 50: 16 i f (se l f . sta r tDragCmd ){ 17 va r params = new Array() ; 18 pa r ams.push (event) ; 19 pa r ams .push (se l f ) ; 20 handl eRequest ( sel f .s t artDragCmd . params ) ; 21 } 22 }. 75 ) ; 23 }

Ein weiterer interessanter Punkt im vorstehenden Code erscheint in Zei le 5· Anstatt die

Ausgangsposition der Berührung sofort als Attribute off setX und offset Y des zu zie­

henden Elements zu speichern, wird ein Timer benutzt, um das Setzen dieser und anderer

Werte zu verschieben. Dies geschieht, wei l möglicherweise als Reaktion auf eine Geste des

Benutzers die Funktion prepa reDragaufgerufen wurde.

Es wurden Berührungsereignisse ausgelöst, wei l vor dem Auslösen von Gestenereignissen

immer Gesten stattfinden. Ist das an prepa reDrag übergebene Ereignis tatsäch lich das

Ergebnis einer Geste, brauchen die Ereignisl istener ontouchmove und ontouc hend nicht

gesetzt zu werden oder werden aufgerufen, wenn sich die Geste ändert und beendet wi rd.

Würden die Listener aufgerufen, dann w ürden sie Ziehverhalten ausführen und bewirken,

dass das Gestenverhalten nicht f unkt ioniert.

Der erstellte Timer m uss eine ausreichende Verzögerung vorsehen, damit die Gesten­

listener-Funktion pr epa reGe sture aufgerufen werden kann, weil diese das Attribut

chang i ng des zu ändernden Elements aktual isiert.

Zei le 22 legt eine Verzögerung von 75 Millisekunden fest. Das reicht aus, um den Gesten­

listener aufzu rufen und bei einer Geste auszuführen, ist aber ku rz genug, um den Benut ­

zer nicht zu ärgern, fa lls es sich um einen Ziehvorgang handelt. Ist die Verzögerung zu

lang, kann der Benutzer ohne Weiteres den Finger vom Element nehmen, bevor es sich

bewegt. Der letzte interessante Punkt ist das Füllen eines Arrays mit dem Namen pa rams

und der Aufrufvon hand l eRequest.

Der Aufruf der Funktion handl eReques t in Zeile 20 gibt Ihnen die Möglichkeit, Callout­

Funktionen zu erstellen, die jedes Mal ausgeführt werden, wenn ein Berührungsereignis

ein Ziehvorgang ist. Sie werden mit hilfe von mapCommandTo* -Funktionen in der Zuord­nungsdatei definiert (siehe Kapitel 2). Sie können eine beliebige Anzah l von Geschäfts- und

Ansichtssteuerfunktionen aufrufen, wenn ein Ziehvorgang gestartet wi rd. Möglicherweise

wollen Sie damit zum Beispiel das Element aus dem übergeordneten Element entfernen,

seine Hintergrundfarbe oder seine Umrandungen ändern oder noch etwas anderes t un.

95

Page 97: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

Da nicht bekannt ist, ob oder wie Sie diese Callout-Funktionen benutzen, enthält das Array

pa ram s, das übergeben wird, einige Informationen. Wie im vorstehenden Code zu sehen,

handelt es sich um das gezogene und das ziehende Element. Es ist nicht bekannt, ob Sie

Callout-Funktionen erstellen, in denen Sie sie möglicherweise benötigen, aber der Ein­

fachheit halber wurden sie hinzugefügt.

Wenn der Benutzer seinen Finger über das Display bewegt, wird w iederholt der on touc h­

Ereignislistener d r ag I t aufgerufen. Diese Funktion dient wie die Funktion d ra g in der Bei­

spielanwendung D r a g dazu, das Element entsprechend der Fingerbewegung des Benutzers

zu verschieben. Sie sehen hier jedoch die Anwendung der zuvor in den Gestenlistener-Funk­

tionen und in prepar eDrag gespeicherten Daten.

Da sowohl zum Ziehen als auch zum Ablegen eine Transformation verwendet wird, muss

bei einem Ziehvorgang zusätzlich zur Versch iebung das vorherige Drehen und Skalieren be­

rücksichtigt werden, wei l das Attri but webK i tT ra ns f orm des Sti ls bei jeder Verwendung

zurückgesetzt wird. Fehlen Dreh- und Skalierungsdaten im Transformationsstring, nimmt

das Element seine ursprüngliche Größe und Ausrichtung an, sobald es gezogen w ird.

Ein Transformationsstring, der in seiner Gesamtheit zu einer Versch iebung, einer Drehung

und einer Skalierung f ührt, enthä lt mehrere Funktionen:

" transl ate ( - l px , Spx) rot ateZ ( 2ldeg) sca l e ( 0.9 ) "

Diese Codezei le versch iebt das Element um 1 Pixel nach links und 5 Pixel nach unten. Ansch ließend dreht sie es um seine z-Achse. Sch ließlich verkleinert sie es auf go Prozent

seiner Origina lgröße.

Die Reihenfolge der Funktionsbeschreibungen ist von Bedeutung. Steht die Drehung im

String links von der Versch iebung, erfolgt sie zuerst , und die Versch iebung fi ndet im Win­

kel zu r x- und y-Achse anstatt an diesen ent lang statt. Das wäre fehlerhaftes Drag&Drop­

Verha lten, weil sich das gezogene Element im Winkel zu r Fingerbewegung des Benutzers

bewegt anstatt mit dieser.

Den Code, der den String für das Modul zusammenset zt, fi nden Sie in Zeile 13 bis 25. Die

Zeilen enthalten die Verkettung eines Tei lstrings, der zu einem String hinzugefügt wird,

welcher die Funktionsdeklaration für die Verschiebu ng enthält.

1 f unct ion d rag l t ( event) { 2 stopDe f aul t ( event ) ; 3 4 5 6

96

th i s. x th i s. y

event.ta rgetTouches [O].cl i ent X - this. offsetX; event.ta rgetTouches [O].cl i ent Y - this. offsetY;

Page 98: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Ein Modul für Drag&Drop, Skalierung und Drehung

7 i f ( this . lastX I I this . lastY ) { 8 this.x += t his .lastX; 9 this .y += t his .lastY ; 10

this .sty le .webkitTransfo r mOr i gi nX this.style .webkitTransfo r mOr i gi nY var modStringFragment = i f( this. isChangea ble ){

if(this.rotation){ modStringFragment +=

I 50% I; I 50% I ;

11 12 13 14 15 16 17 18

I rotateZ( 1 +this .ol dRotat ion+ldeg) 1:

19 20 21 22 23 24 25 26

if(this .ol dScale){ modStr i ngFragment +=

I sca l e( 1 +th i s .ol dSca l e+ l ) l;

var modString l trans l ate(, + t his . x + ,px , • + t his .y + ,px) l+modStr i ngFragment ;

27 this . sty l e .webkitTransfo r m = modStr ing ; 28 i f(thi s.dragCmd){ 29 var params = new Array() ; 30 pa rams . pus h(even t ) ; 31 pa rams . pus h(this ) ; 32 handl eRequest(t his .dragCmd , pa rams ) ; 33 34

EtwasBedeutsamesgeschiehtauch inZeile11und12.DieAttributewebk i tTrans fo r mO r i gi nX

und web k i tTra n s fo r mO r i g i nY werden auf ihre Standardwerte gesetzt, was erforderlich

ist, wenn Drehung oder Ska lierung vorgesehen ist, wie Sie weiter hinten in diesem Abschnitt

sehen. Erfolgt es nicht, dann hüpft das Element zu Beginn des Ziehens, und der Finger des Benutzers befindet sich nicht am selben Punkt des Elements wie ursprünglich.

Wenn der Benutzer einen Finger vom Display des Geräts nimmt, wi rd ein ontouchend­

Ereignis ausgelöst und die Listener-Funktion drag Done aufgerufen. Der Zweck dieser

Funkt ion aus der Datei QCUt i l i t i es . j s, die Sie im folgenden Code sehen, besteht darin,

einige Attribute des Elements auf die Originalwerte zurückzusetzen und andere Daten zur

späteren Verwendung zu speichern.

97

Page 99: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

f unct i on dragDone( event){ t his .dragg i ng = fa l se ; t his .on t ouchmove =null; t his . on t ouchend =nul l: t his . l astX = t his . x : t his . l ast Y = th is .y ; t his . st y l e .z l ndex = t his .ol dZ index ;

if ( t hi s .dropCmd){ va r params = new Ar r ay() ; params .push( even t ) ; params .push( th i s ) ; handl eReques t (t his . dropCmd , params) ;

ln dieser Funktion werden der ontouc hmove- und der ontouchend-Listener auf ihren

Leerzustand zurückgesetzt, um die Gestenbehandlung nicht zu stören, wie bereits erör­

tert wurde. Der aktuelle x- und y-Wert des Elements w ird gespeichert und, fal ls vorhan­

den, ein Befehl ausgeführt .

Nachdem Sie den vollständigen Ablauf der ausgefeilten Drag&Drop-Methoden gesehen

haben, ist die entsprechende Gestenhandhabung besser verständlich. Genauso, wie sich die

Gestenbehandlung auf den fü r Drag&Drop erforderlichen Code auswi rken kann, kann auch

die Drag&Drop-Handhabung Einfluss auf den Code zum Skal ieren und Drehen haben.

Die Funktion pr epareGes t ure aus der Datei QCUtil it ies . js, die Sie im folgenden

Code sehen, ist einfacher als die weiter vorn in diesem Abschnitt erörterte Funktion

p repa r eDrag. Sie setzt einige Attribute, braucht aber nicht w ie die andere Vorbereitungs­

funktion f ür eine Verzögerung zu sorgen, was bereits erläutert wurde.

f unct ion pr epa reGes t ure(event) { stopDefau l t(even t ) ;

98

t his . changi ng = t rue ; t his . ol dZi ndex = t hi s . styl e .z lndex ; t his . st y l e . z l ndex = 50 ;

if (thi s . startChangeCmd ){ var pa r ams = new Array() ; params . push(even t ) ;

Page 100: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Ein Modul für Drag&Drop, Skalierung und Drehung

params .push(this); handleRequest( this .sta r tChan geCmd . params ) ;

Wie alle Behandlungsfunktionen für Gestenereignisse weist auch diese das Framework

an, einen Befehl durch Aufrufen der Funktion hand l eReq uest zu handhaben. Sie können

eine beliebige Anzah l von Callout-Funktionen ausführen, nachdem ein Gestenereignis­

listenerfertig ist. ln Kapitel2 wird erörtert, wie Sie Funktionen Befehle zuordnen.

Wenn der Benutzer seinen Finger über das Display bewegt, wird wiederholt ein

onges t ur echange-Ereignis ausgelöst, was zum Aufruf der Funktion cha ngelt aus der

Datei QCUt i l i t i es. j s führt, die Sie im folgenden Code sehen. Sie istfür die Skalierung und

Drehung des Elementsanhand der Interaktion des Benutzers mit dem Gerät zuständig.

" rota t eZC2l deg) sca l e(0.9) t rans l ate( -lpx , Spx) "

Beachten Sie, dass Fingergesten auf zwei oder mehr versch iedenen Elementen möglich

sind. Dabei handelt es sich normalerweise um ein Versehen des Benutzers, weshalb Zeile

5 bis 8 die Reaktion der Elemente bei Berührung verhindert.

Außerdem kann der Benutzer einen Pinch machen, was dazu führen kann, dass ein Element

für zwei Finger zu klein wird. Wäre dies zulässig, könnte der Benutzer die Größe des Ele­

ments nicht mehr ändern, was weitere Modifizierungen verhinderte. Die Zei len 14 bis 19

sorgen dafür, dass der Benutzer ein Element nicht versehentlich zu klein zum Vergrößern

machen kann.

Wie bereits erörtert, ist die Reihenfolge der Funktionsdeklarationen im Transformations­

string von Bedeutung. Um ein Element erfolgreich zu drehen und zu skalieren, muss die

Verschiebung erfolgen, aber am Ende des Strings deklariert werden.

Erfolgt die Verschiebung zuerst, wenn der Benutzer versucht, ein Element zu drehen, wür­

de das Element während der Drehung allmählich verschoben. Ist keine Verschiebung ent­

halten, dreht sich das Element um seine ursprüngliche linke obere Ecke, wie es in der ihm zugewiesenen CSS-Kiasse defin iert ist. Beide Verhaltensweisen sind nicht akzeptabel.

1 function changelt(event){ 2 stopDefa ul t(event); 3 //der Benutzer hat mögl icherwe ise 4 //nur einen Finger i n das Ziel gesetzt . 5 i f ( this.dragging 6 I I ( this.touches && t his .touches. l ength < 2)){ 7 8

return :

99

Page 101: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

9 10 thi s . rotat ion = event . rota t i on : 11 var rota t ionVa l ue = this . ro t at i on + thi s .ol dRotation : 12 var sca l eVa l ue = event . sca l e * th is . ol dSca l e: 13 / /es darf ni cht zu kl ein für zwei Berührungen werden 14 if( t his.offse t Wi dth * sca l eVa l ue < 150 ){ 15 sca l eVa l ue = 150/this.offsetWidt h: 16 17 el se if( this . off setHei ght * scal eVal ue < 150){ 18 sca l eVa l ue = 150/this .offset Hei ght : 19 20 thi s . scal e = sca l eVa l ue ; 21 22 var modSt ring = lrotateZ( ,+rota t ionVa l ue+ 23 ,deg) sca l e( l+scal eVa l ue+l ) I; 24 if( t his . l astX I I th is . l astY){ 25 modSt ring += I trans l at e( , + t his . l astX + ,px, . 26 + th is . l astY + ,px) l: 27 //den Drehpunkt aktual isieren 28 thi s .xCen t erOffset =50 29 + (thi s . l as t X/this . offset Width) 30 * 100 : 31 thi s .yCen t erOffset =50 32 + (thi s . las t Y/ th i s.offset Height ) 33 * 100 : 34 35 36 37 38

39

thi s . styl e .webkitTransformOrigi nX (this . xCenterOf fset )+1 %1

:

thi s . styl e .webkitTransformOrigi nY = (this .yCenterOf fset )+1 %1

:

40 t hi s . styl e .we bki tTransform = modStr i ng ; 41 42 if( t his . changeCmd){ 43 44 45 46 47 48

100

var params = new Ar ray(); params . pus h(event ) ; params . pus h(this ) ; handl eRequest(thi s . changeCmd , params);

Page 102: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Ein Modul für Drag&Drop, Skalierung und Drehung

ln Zeile 22 bis 39 werden der Transformationsstring erstellt und die Werte für webki tTrans fo rmOr i gi n gesetzt, sodass die Skalierung und die Drehung auf der Grundlage des geänderten optischen Mittelpunkts des Elements stattfinden können. Die Ursprungsänderungen im vorstehenden Code haben es erforderlich gemacht, sie in derbe­reits erörterten Methode d ra g I t zurückzusetzen. Als Transformationsursprung dient aus­

gehend vom aktuellen Abstand von der Ausgangsposition der Mittelpunkt des Elements.

Wenn der Benutzer seine Finger wegnimmt, wird ein ongestureend-Ereignis ausgelöst und der unten stehende gestureDone-Ereignishandler aufgerufen. Abgesehen von einer Ausnahme entspricht er der Methode dragDone; wie die Funktion prepa reDrag enthält er einen Timer.

1 function gestureDone(event){ 2 th is .sty l e.zlndex = this.o l dZindex; 3 II Mögl icherweise hat der Benutzer ke i ne Drehung durc hgeführt. 4 II Dann ist r ota t ion undefiniert. 5 i f ( this . rotation){ 6 this. ol dRota t ion += this.rotation; 7 } 8 II Mög l icherweise hat der Benutzer keine Ska l ierung 9 II durchgeführt . Dann ist sca l e undefin iert . 10 i f( this.sca l e){ 11 12 13

this.ol dScal e = th is . sca l e;

14 if ( this.doneChangeCmd) { 15 16 17 18 19

var params = new Array() ; pa rams . push (even t ) ; pa rams . push (this ) ; handleReques t (t his .doneChangeCmd, params ) ;

20 var sel f = this; 21 this.timeOut = setTimeout(function(){ 22 sel f .changing = fa l se; 23 } '75 ) ; 24

101

Page 103: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 3 Benutzerschnittstellen für das iPhone erstellen

DieserTimer (Zeile 21 bis 23) ist aus demselben Grund vorhanden wie der in p r epa reD rag.

Beim Auslösen der ongestureend-Ereignisse sind einige Berührungsereignisse noch

unbehandelt. Wird das Attributcha nging des Elements sofort auf fa l se gesetzt (siehe Zeile 22), werden durch den Code in prepa r eDrag (siehe weiter vorne) die Ereignisliste­

ner für den Ziehvorgang aktiviert.

Geschieht dies fü r eine Skalierungs- oder Drehgeste, hüpft das Element ungewollt auf

dem Display, was dem Benutzer negativ auffällt.

Drag&Drop, Skalierung und Drehung müssen zwar voneinander wissen, ihr Verhalten

muss jedoch streng getrennt werden, weil sich die Anwendung sonst verwirrend und nicht

vorhersehbar verhält. Der Code in diesem Abschn itt und in der Datei QCUt i l i t i es. j s

stellt Ihnen eine einsetzbare fertige Implementierung von Drag&Drop-, Skalierungs- und

Drehungsverha ltensweisen zur Verfügung.

3.7 ZUSAMMENFASSUNG

Aus Benutzersicht ist die Schnittstelle Ihrer Anwendung die Anwendung. Eine schlechte

Gesta ltung wie in dem abschreckenden Beispiel des Spiels DollarStash kann zum Unter­

gang Ihrer Anwendung führen, bevor sie eine Chance zur Verbesserung oder Korrektur

bekommt . Wie in diesem Kapitel beschrieben, beruht eine kluge Schnittstellengesta ltung

auf drei Prinzipien:

> Überraschen Sie den Benutzer nicht. Verwenden Sie gängige Verhaltensweisen für

die Interaktion.

> Gestalten Sie die Schnittstelle intuitiv. Es sollte nicht notwendig sein, die Anleitung

zu lesen.

> Stellen Sie keine Anforderungen an Ihre Geräte, die sie nicht erfüllen können. Pro-

zessor- und Speicherressourcen sind begrenzt. Gehen Sie klug damit um.

Wenn Sie sich an diese Grundregeln und an die Schnittstellenrichtlinien von Apple halten,

stehen die Erfolgschancen Ihrer Anwendung wesentlich besser. Die Regeln mögen zwar

streng wi rken, lassen aber dennoch Raum für Kreativität, wie das Modul für Drag&Drop,

Skalierung und Drehung zeigt.

Wird es überlegt erstellt und benutzt, kann es den Eindruck des Benutzers von Ihrer An­

wendung gewaltig verbessern, weil es auf der integrierten Mehrfachberührungsfähigkeit

der Geräte iPhone und iPod touchsowie den Schnittstellenrichtlinien von Apple aufbaut.

102

Page 104: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

GPS, Beschleunigungs­messung und andere systemeigene Funktionen von OuickConnect -Das iPhone besitzt zahlreiche einzigart ige Fähigkeiten, die Sie in Ihren Anwendungen ein­

setzen können, beispielsweise den Vibrat ionsalarm, das Abspielen von Systemklängen,

die Beschleunigungsmessung und die Nut zung von GPS-Ortsinformat ionen. Außerdem

können Sie in Ihrer Anwendung vorsehen, Meldungen zur Feh lerbehebung in der Xcode­

Konsole auszugeben. Der Zugriff auf diese Fähigkeiten ist nicht auf Obj ective-C-Anwen­

dungen beschränkt; lhreWeb-Apps erreichen Sie ausJavaScript heraus. Im ersten Abschnitt

dieses Kapitels w ird erklärt, wie Sie sie und andere syst emeigene iPhone-Funktionen mit ­

hilfe der JavaScript-API von QuickConnect iPhone benutzen. Der zweite Abschnitt zeigt den

Obj ect ive-C-Code, der der JavaScript-Bibliothek von QuickConnectiPhone zugrunde liegt.

Page 105: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

4.1 GERÄTEAKTIVIERUNG IN JAVASCRIPT

Das iPhone ist ein Gerät, das wesentliche Veränderungen bringt. Einer der Gründe da­

für ist der Umstand, dass Autoren von Anwendungen auf Hardware wie die Beschleuni­

gungsmessung zugreifen können. Mit diesen systemeigenen iPhone-Funktionen lassen

sich innovative Anwendungen erstellen. Die Entscheidung, wie Ihre Anwendung auf eine

Änderung der Besch leunigung oder der GPS-Ortsdaten reagiert, liegt in Ihrer Hand. Sie

entscheiden auch, wann das Mobi ltelefon vibriert oder eine Audiodatei abspielt.

Die QuickConnectiPhone-Datei com . j s enthält eine Funktion, mit der Sie auf einfache,

leicht verwendbare Weise auf dieses Verhalten zugreifen können. Es handelt sich um die

Funktion ma keCa 11, mit der Ihre Anwendung Anforderungen an das Mobiltelefon stellt.

Sie benötigt zwei Parameter: Der erste ist ein Befehlsst ring, der zweite eine Stringversion

aller Paramet er, die zur Ausführung des Befehls erforderlich sind. ln Tabelle 4.1 sind al le

Standardbefehle mit den erforderlichen Parametern und der Verhaltensweise des iPhones

bei Ausf ührung des Befehls aufgeführt .

Befehlsstring Meldungsstring Verhalten I

1ogMessage Al le im X-Terminal zu Die Meldung erscheint im

prot okol lierenden Informationen Xcode-Terminal, wenn der Code

ausgef ührt w ird.

rec Ein JSON-String eines JavaScript- Es wird eine caf -Audiodatei

Arrays mit dem Namen der zu m it dem im String definierten

erstellenden Audiodatei als erstes Namen angelegt .

Element. Das zweite Element des

Arrays laut et j e nachdem, ob Sie

die Aufzeichnung von Aud iodaten

starten oder stoppen wol len,

s ta r t oder s top.

p1ay Ein JSON-String eines JavaScript- Wenn die Audiodat ei

Arrays mit dem Namen der vorhanden ist, w ird sie über die

abzuspielenden Audiodatei Lautsprecher des Geräts oder

als erstes Element . Das zweite den Kopfhörer abgespielt .

Element des Arrays lautet je

nachdem, ob Sie das Abspielen der

Audiodatei starten oder st oppen

wollen, sta r toder stop.

104

Page 106: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in JavaScript

l oc Keine Die Ortsbestimmung des

Geräts wird ausgelöst,

und es werden Daten über

geografische Breite, Länge

und Höhe an die JavaScript-

Anwendung übermittelt.

pl aySound -1 Das Gerät vibriert.

pl aySound 0 Die Audiodatei l aser. wav

wird abgespielt.

showDate DateTime Die systemeigene Datums- und

Uhrzeitabfrage wird abgespielt.

showDate Date Die systemeigene

Dat umsabfrage wird

abgespielt.

Tabelle 4 .1: Die Befehls-AP/für MakeCa/1

Die Beispielanwendung Dev i ceCa ta l og enthä lt eine Schaltfläche VI BRATE, die das Mobil­

telefon beimAnklicken vibrieren lässt. Die onc l i ck-Ereignishandlerfunktion der Scha lt ­

fläche heißt v i bra teDevi ce; Sie sehen sie im folgenden Beispiel. Sie ruft die Funkt ion

ma keCa l l auf und übergibt ihr den Befehl p l aySound mit dem Zusatzparameter - 1. Der Befehl veranlasst, dass das Mobi ltelefon vibriert. Der Befehl p l aySound wi rd verwendet,

wei l das iPhone Vibrationen und ku rze Systemklänge als Klänge behandelt.

function vibrateDevice(event) {

//der I ndi kator - 1 veran l asst, dass das Te l efon vibriert makeCal l ( " pl aySound ", - 1) ;

Da Vibration und Systemklänge gleich behandelt werden, läuft das Abspielen eines Sys­

temklangs fast genauso ab. Der onc l i ck-Ereignishand ler der Schaltfläche SouND heißt

p l aySound. Wie Sie im folgenden Code sehen, besteht der einzige Unterschied zwischen

ihm und v i brateDevi ce im zweiten Parameter.

Wird als zweiter Parameter 0 übergeben, wird die Datei l aser. wav aus den Ressourcen

des Projekts Dev i ceCa ta l og als Systemklang wiedergegeben. Audiodateien f ür System­

klänge dürfen maximal f ünf Sekunden lang sein, damit sie als Klang abgespielt werden

105

Page 107: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel4 Systemeigene Funktionen von QuickConnect

können. Längere Dateien werden mithilfe des Befehls p l ay wiedergegeben, der weiter

hinten in diesem Abschnitt behandelt wird.

function pl aySoundCevent) {

//der Indi kator 0 veranlasst, dass das Telefon den Kl ang // " laser" abspie l t makeCa llC "pl aySound", 0 ) :

Die im vorstehenden Code verwendete Funktion ma keCa ll liegt vollständig in JavaScript

vor und ist im folgenden Code zu sehen. Sie besteht aus zwei Teilen. Der erste stel lt die

Meldung in eine Warteschlange, wenn sie nicht sofort gesendet werden kann. Der zweite

sendet sie zur Behandlung an den zugrunde liegenden Objective-C-Code. Die Meldung

w ird übergeben, indem die Eigenschaft wi ndow. l ocat i on in einen nicht vorhandenen

URL, ca l l , umgewandelt w ird und die beiden Parameter der Funktion als Parameter des

URL übergeben werden.

function ma keCa l l ( command, dataString ) { var messageString = " cmd="+command+"&msg="+dataString; if( StoreMessage I I ! canSend ){

messages.push (messageString);

el se { storeMessage = true; window. l ocation = "ca l l ?"+messageString;

Diese Art, den URL zu setzen, führt dazu, dass eine Meldung mit dem URL und seinen

Parametern an eine Objective-C-Komponente gesendet wird, die zum zugrunde liegen­

den QuickConnectiPhone-Framework gehört. Diese Komponente dient dazu, das Laden

der neuen Seite zu beenden und den Befehl und die Meldung, die sie erhalten hat, an

den Befehlsbehandlungscode des Framewerks zu leiten. Wie dies geschieht, können Sie in

Abschnitt 2 lesen.

Die Befehle pl aySound, l ogMessage, rec und pl ay sind unidirektional, d.h., dass die

Kommunikation von JavaScript an Objective-C gerichtet ist, ohne dass Daten zurück­

erwartet werden. Die übrigen unid irektionalen Standardbefehle führen dazu, dass Daten

von den Obj ective-C-Komponenten zurück an JavaScript gesendet werden.

Die Datenübergabe zurück an JavaScript erfolgt auf zwei Arten. Ein Beispiel für die erste

bildet die Übertragung von Beschleunigungsdaten in die x-, y- und z-Koordinate durch

106

Page 108: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in JavaScript

einen Aufruf der JavaScript-Funktion handl eRequest, die in Kapitel 2, »Die Modularität

von JavaScript für iPhone-Anwendungen«, beschrieben wurde. Der Aufruf verwendet den

Befeh I a c c e l sowie die von den Objective-C -Korn ponenten des Fra meworks als JavaScript­

Obj ekt übergegebene x-, y- und z-Koord inate.

Die Datei ma pp i ngs. j s bewirkt, dass der Befehl a cce l der Funktion d i s p l ay Acce l e ­

rat i on V CF zugeordnet wird, wie Sie in der folgenden Zeile sehen:

mapCommandToVCF('accel ', displayAccel erationVCF);

Dadurch wird displ ayAccelerationVCF jedes Mal aufgerufen, wenn die Beschleuni­

gungsmessung eine Bewegung feststellt. Die Funktion ist für die Behandlung der Besch leu­

nigungsereignisse zuständig.ln der Beispielanwendung Dev i ceCa ta l og setzt sie einfach

die Beschleunigungswerte fü r x, y und z in ein HTML-di v-Eiement ein. Sie sollten sie so

ändern, dass sie diese Werte für Ihre Anwendung benutzt.

Die zweite Methode, Daten an JavaScript zu rückzusenden, bedient sich der JavaScript­

Funkt ion hand l eJSONRequest, die weitgehend ähnlich f unktioniert wie die in Kapitel 2

beschriebene Funktion h a nd l eReques t, j edoch als zweiten Parameter einen JSON-String

erwartet. Sie stellt eine Fassade fü r h a nd l eReques t dar. Wie im folgenden Code zu sehen,

wandelt sie einfach den JSON-String, der ihr zweiter Pa rameter ist, in ein JavaScript-Obj ekt

um und übergibt den Befehl und das neue Objekt an die Methode hand l eRequest. Diese

Art der Datenübert ragung w ird als Reaktion auf eine GPS-Ortsanforderung verwendet,

die von einem Auf rufvon ma keCa l l ( " l oc") ausgeht, sowie auf die Anforderung, einen

Pickerfür Datum und Uhrzeit anzuzeigen.

function handl eJSONRequest(cmd , parametersString){ var paramsArray =nul l : if(parametersStr i ng) {

var paramsArray = JSON . parse( parametersString);

handl eRequest(cmd , paramsArray);

ln beiden Fä llen werden die Ergebnisdaten in einen JSON-String umgewandelt und an

handl eJSONRequest übergeben. Weitere Informationen über JSON finden Sie in Anhang A, »Einführung in JSON«.

Da sowohl in JavaScripta ls auch in Objective-C JSON-Bibliotheken zur Verfügung stehen,

stellt JSON eine günstige Methode dar, um komplexe Informationen zwischen zwei Spra­

chen in einer Anwendung zu übermitteln. Ein einfaches Beispiel daf ür sind die onc l i c k­

Handler zum Starten und Stoppen der Aufzeichnung bzw. Wiedergabe von Aud iodateien.

107

Page 109: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

Der Handler pl ay Record i ng ist typisch für alle Scha ltflächenhandler in der Benutzer­

schnittstelle, die Geräteverhalten aktivieren. Wie im folgenden Beispiel gezeigt, legt er ein

JavaScript-Array an, fügt zwei Werte hinzu, konvertiert das Array in einen JSON-String und

führt danach die Funktion ma keCa l l mit dem Befeh l p l ay aus.

f unct i on pl ay Record ing( event) {

va r params = new Array ( ) ; params[ OJ = "recordedFi l e . ca f": params[l ] = " start": makeCallC "pl ay ", JSON. stri ngify(params )) ;

Um das Abspielen einer Aufzeichnung zu beenden, wi rd ebenfalls die Funktion makeCa ll

mit dem Befehl p l ay gestartet, aber als zweiter Parameter fungiert nichts ta rt, sondern

stop. Die Funktion termi natePl ay in der Dateimai n. j s setzt dieses Verhalten um.

Das Starten und Stoppen der Aufzeichnung von Audiodaten erfolgt auf dieselbe Weise

w ie pl ayRecord i ng und ter mi natePl ayi ng abgesehen davon, dass an die Stelle des

Befehls p l ay der Befehl rec t ritt. Dass die Implementierung dieser verwandten Fäh ig­

keiten ähnlich aussieht, macht es Ihnen erheblich einfacher, die Verhaltensweisen in Ihre

Anwendung aufzunehmen.

iijiiijjijijj CUrrerv LOcanon: IIIIUJde: 37.331688 klnglnlclo: -122.030731 a1111Ude: o

Acceleromelef Values:

Aooio

108

~ Abbildung 4.1: Die Beispielanwendung DeviceCatalog mit der Anzeige von GPS-Daten

Page 110: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in JavaScript

Wie Sie weiter vorn in diesem Abschnitt gesehen haben, setzen ein ige Verhaltensweisen

des Geräts wie die Vibration lediglich die Kommunikation vom JavaScript-Code zu den

Objective-C-Handlern voraus. Andere wie das Abfragen der aktuellen GPS-Koordinaten

oder der Ergebnisse eines Pickers benötigen die Kommunikation in beide Richtungen.

Abbildung 4.1 zeigt die Anwendung Devi ceCata log mit GPS-Daten.

Wie bei einigen der bereits untersuchten unidirektionalen Beispiele beginnt die Kommuni­

kation im JavaScript-Code Ihrer Anwendung. Die Funktion getGPSLocati on in der Datei ma in. j s initiiert die Kommunikation mit der Funktion ma keCa ll. Beachten Sie, dass die­

se wie in den früheren Beispielen nichts zurückgibt. Sie verwendet für die Kommunikation

mit der Objective-C-Seite der Bibliothek ein asynchrones Protokoll, selbst wenn die Kom­

munikation bidi rektiona I verläuft, sodass kein Rückgabewert zur Verfügung steht.

func t ion getGPS Locat i on(event) {

document.getEl emen tßyld( ' l ocDispl ay') . innerText makeCa l l ( " l oc " );

Da die Kommunikation wie AJAX asynchron ist, muss eine Rückruffunktion erstellt und

aufgerufen werden, um die GPS-Daten zu empfangen. Im QuickConnectiPhone-Frame­

work geschieht dies durch eine Zuordnung in der Zuordnungsdatei, die den Befehl s how­

Loc einer Funktion zuordnet:

mapCommandToVCF( ' showloc '. displ ayLocationVCF);

in diesem Fall wird er der Ansichtssteuerfunktion d i sp l ay l ocati onVC F zugeordnet.

Diese einfache Beispielfunktion wird lediglich verwendet, um den aktuellen GPS-Ort in

einem d i V-Element auf dem Display auszugeben. Diese Werte können natürl ich auch ein­

gesetzt werden, um Entfernungen zu berechnen und in einer Datenbank abzu legen oder

mit dem in Kapitel 7, » Datenzugriff über das Netzwerk«, beschriebenen Se rve rAcces s ­

Obj ec t an einen Server zu senden.

func t ion displ aylocat ionVCF(data, paramArray){ document.getEl emen tßyld( ' l ocDispl ay ' ).innerTex t = , l at itude: '+paramArray[OJ+ ' \n l ongitude: ' +paramArray[l]+'\nal t itude: ,+paramArray[2];

109

Page 111: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

Die Anzeige eines Pickers, beispielsweise des Standardpickers für Datum und Uhrzeit,

und anschließend der ausgewählten Ergebnisse erfolgt ähnlich wie im vorstehenden Bei­

spiel. DerVorgang beginnt ebenfalls m it einem Auf ruf des Gerätebehandlungscodes aus

JavaScript heraus.ln diesem Fall ist die Funktion showDateSe l ector in der Datei mai n .

j s der Ereignishandler der Schaltfläche.

f unct ion showDateSel ector(event) {

makeCall ( "showDate", "DateTime " ) ;

Wie beim GPS-Beispiel wi rd auch hier eine Zuordnung benötigt. Sie ordnet den Befehl

s howPi c kResu l ts der Ansichtssteuerfunktion d i s p l ay Pi c kerSe l ect i onVC F zu:

mapCommandToVCF( ' showPi ckResul ts', di sp l ayPickerSe l ectionVCF) ;

Die Funktion, der der Befehl zugeordnet wi rd, f ügt die Ergebnisse der Auswah l des Benut­

zers in ein einfaches d i v-Eiement ein, wie der folgende Code zeigt. Diese Daten können

natürlich aufvielfache Weise genutzt werden.

f unct i on dis pl ayPic kerSel ect ionVCF(data , pa ramArray){ document.getEl ementBy l d('pickerResul ts ' ) .innerHTML pa ramArray [ OJ :

Einige Verwendungen von ma keCa l l kommun izieren wie die f rühen Beispiele in diesem

Abschn itt unid irektiona l vom JavaScript-Code zu den Obj ective-C-Gerätehandlern, die ge­

rade untersuchten dagegen bid irektional zu und von den Handlern.Außerdem ermögl icht

das Gerät die unidirektionale Kommun ikation vom Gerät zum JavaScript-Code, etwa bei

der Verwendung von Beschleunigungsmessdaten.

Der Obj ective-C-Handler für Besch leunigungsereignisse (Code siehe Abschnitt 2) ruft die

JavaScript-Funktion handl eRequest auf und übergibt ihr di rekt den Befehl acce l . Der

folgende Befehl acce l ist der Ansichtssteuerfunktion d i s p l ay Acce l era t i on VC Fzuge­

ordnet.

mapCommandToVCF( ' acce l '. displ ayAcce l erat i onVCF);

Wie die anderen Ansichtssteuerfunktionen setzt auch diese die Beschleunigungswerte in ein d i v-Eiement ein.

}

f unct i on dis pl ayAcce l erationVCF(data , param) { document.getEl ementBy l d('accel Displ ay') . innerText ' x : '+pa ram. x+' \ny : '+pa ram .y+' \nz: ,+pa ram.z:

110

Page 112: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in Objective-c

Ein Unterschied zwischen dieser Funktion und den anderen besteht darin, dass ihr kein

Array, sondern ein Objekt als Parameter pa ram übergeben wird.ln Abschnitt 2 wird gezeigt,

wie es aus Informationen erstellt wurde, die der Objective-C-Handler für Besch leunigungs­

ereign isse übermittelt hat.

ln diesem Abschn itt haben Sie erfahren, wie Sie einige der meistverlangten iPhone-Ver­

haltensweisen in Ihre auf JavaScript basierende Anwendung integrieren. Abschn itt 2 stel lt

Ihnen die Objective-C-Teile des Frameworks vor, die diese Fähigkeit unterstützen.

4.2 GERÄTEAKTIVIERUNG IN ÜBJECTIVE-(

Dieser Abschn itt setzt voraus, dass Sie mit Objective-C und seiner Verwendung zum Er­

stellen von iPhone-Anwendungen vertraut sind. Sollte dies nicht der Fall sein, können

Sie The iPhone Developer's Cookbook von Erica Sadun aus dem Verlag Pearson Publishing

lesen. Fa lls Sie das QuickConnectiPhone-Framework led iglich verwenden wollen, um

JavaScript -Anwendungen f ür das iPhone zu schreiben, brauchen Sie diesen Abschnitt

nicht durchzuarbeiten.

Das iPhone mithilfe von Objective-C vibrieren zu lassen, ist eine der am einfachsten um­zusetzenden Verha ltensweisen. Wenn Sie das Aud ioToolbox-Framework in die Ressourcen

Ihres Proj ekts einbinden, benöt igen Sie dazu nur die folgende eine Codezeile.

Audi oServices Pl aySystemSound(kSys t emSoundi D_Vi brate);

Die Frage lautet dann; »Wie bekomme ich die Funktion Audi oServi cesPl aySystem ­

Sound aufgerufen, wenn die U IWebVi ew angewiesen wird, sich mithilfe des JavaScript ­Befehls wi ndow . l oca t ionneu zu laden?«

Der QuickConnectViewController implementiert die Delegatmethode shoul dSt a r tload ­

WithRequest. Da der Delegat der eingebetteten UIWebView, aWebVi ew, als QuickCon­

nectViewCont roller best immt ist, w ird diese Methode immer dann aufgerufen, wenn die

eingebettete UIWebView ihren Ort ändern soll. Der folgende Code und Zeile 133 der Datei

Qu i ckConnect Vi ewCont roll er zeigen, wie dieser Delegat gesetzt wird.

[aWebView setDel ega t e : se l f ] ;

Das Grundverhalten der Funkt ion s houl dSta rt Loa dWit h Req ues t ist unkompliziert.

Sie dient zum Schreiben von Code, der entscheidet, ob die angeforderte neue Seite tat­

säch lich geladen werden soll. Das QuickConnectiPhone-Framework nutzt die Entschei­

dungsfähigkeit, um das Laden von Seiten durch Anforderungen der in Abschnitt 1 gezeig­

ten JavaScript -Aufrufe abzu lehnen und anderen Obj ective-C-Code auszuführen.

111

Page 113: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

Die Methode shoul dSta r tloadWi t hReques t bietet einige Parameter:

> curWebVi ew - Die UIWebView, die Ihre JavaScript-Anwendung enthält.

> request - Ein Objekt vom Typ NSURLRequest,das unter anderem den neuen URL

enthält.

> na v i ga t ionType - Einen UIWebViewNavigationType, der eingesetzt werden

kann, um zu ermitteln, ob die Anforderung auf die Auswahl eines links durch den

Benutzer oder auf etwas anderes zurückgeht.

- CBOO L)webView : CUIWebView *)curWebV i ew shou l dStartloadWithRequest:CNSURLRequest *)reques t nav i gat i onType : CUIWebViewNavigationType)navi gationType

Der von der JavaScript-Funkt ion ma keCa l l erstellte URL, der die Vibration des Geräts auslöst, nämlich ca ll ?cmd=pl aySound&msg=-1, ist im Objekt request entha lten und

lässt sich problemlos als String abfragen, indem Sie ihm die Meldung URL übergeben. Die­

se gibt ein Obj ekt vom Typ NSU R L zurück, das dann die Meldung abso l uteStri ng erhält.

Auf diese Weise gewinnen Sie einen Zeigervom Typ NSSt ring auf den URL, der im folgen­

den Code als ur l auftaucht. Er lässt sich mithilfe von ? als Tei lungstrennzeichen in ein

Array unterteilen, das Zeiger vom Typ NSSt ring ent hält .

NSString *u r l = [[ reques t URLJ abso l uteString]; NSArray *ur l Array = [ur l componen tsSeparatedßyStr ing :@" ?" J :

Das Array url Array enthält zwei Elemente. Das erste ist der ca l l -Teil des URL, das zwei­

te der Betehisstring cmd=p l aySound&msg=-1. Um zu ermitteln, mit welchem Befehl ge­

arbeitet werden soll und welche Parameter erforderlich sind, in diesem Fal l mi tl, muss

der Betehisstring weiter zerlegt werden. Dazu w ird er beim Zeichen & geteilt, wodurch ein

weiteres Array mit dem Namen url Pa ramsAr ray entsteht.

NSString *commandSt r i ng = [ url Array objectAt l ndex:l]; NSArray *ur l ParamsArray = [ commandStr i ng componentsSeparatedByString :@"&" J: //der Befehl ist der ers t e Parameter i m URL NSString *cmd = [[ [ ur l ParamsArray objectAtlndex :OJ componentsSeparatedByString :@"= " J objectAtlndex :l]:

ln diesem Fal l, der Anforderung der Vibration des Geräts, ist cmd=p l aySound das erste

Element des Arrays ur l Pa rams Ar ray, msg=l das zweite. Durch Untertei lung der Array­

elemente lassen sich also der auszuführende Befehl und seine Pa rameter gewinnen. Das Zeichen = stel lt dabei das Trennzeichen dar.

112

Page 114: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in Objective-c

ln Zeile 1 bis 3 des folgenden Beispiels w ird der Parameter abgefragt, der als der mit dem

Schlüssel msg verknüpfte Wert im URL als String pa rameterArrayStr i ng mit dem Typ

NSSt ring gesendet wurde. Da der JavaScript-Code, der den URL erstellt hat, alle Elemente

dieses Werts in JSON konvertiert, ist NSStri ng ein Objekt, das ins JSON-Format umge­

wandelt wurde. Dies sch ließt Zah len wie das aktuelle Beispiel und Strings, Arrays oder an­

dere Parameter ein, die aus dem JavaScript-Code stammen. Enthalten die Daten Leer- oder

andere Sonderzeichen, versieht UIWebView sie als Bestandteil des URL mit Escape-Codes.

Deshalb werden Zeile 6 bis 8 im folgenden Code benötigt, die die Maskierung der Sonder­

zeichen im JSON-String beseitigen.

1 NSStr i ng *parameterArraySt ring = [[[url ParamsArray 2 objectAtlndex:1 ] componentsSeparatedßyString:@"="J

3 objectAt l ndex:1 ] : 4 //Kodierung bese i tigen , mit denen UI We bVi ew die 5 //URL- Zeichen maskiert hat. 6 paramet erArraySt r i ng = [ parameterArrayString 7 stringByRepl acingPercen t EscapesUsi ngEncoding: 8 NSASCIISt r i ngEncoding]; 9 SBJ SON *genera t or = [ SBJSON al l oc ]; 10 NSError *error: 11 paramsToPass = [[ NSMuta bl eArray al loc ] 12 initWit hArray: [ generator 13 objectWi thSt r i ng: parameterArrayString 14 error :&error ] J : 15 if([paramsToPass count] == 0){ 16 //wenn kein Array mi t Da t en gesendet wurde, muss es ei n 17 //String gewesen sein , der al s einz i ger Parameter 18 //gesende t wurde . 19 [ paramsToPass addObject: paramet erArraySt r i ng ]; 20 21 [ genera t or re l ease ] ;

ln Zeile 9 bis 14 im vorstehenden Code erfolgt die Konvert ierung des JSON-St rings

pa rameterArrayS t ri ng in ein systemeigenes Obj ective-C-Array vom Typ NSArray. Zei­

le 9 weist ein SBJSON-Generatorobj ekt zu, dem anschließend die Meldung obj ectWi t h­

St r i ng gesendet w ird, die in derfolgenden Codezeile steht:

- Ci d)objectWi t hStr ing:CNSSt ring*)jsonrep error:CNSError**)error:

Dieser mehrteiligen Meldung werden ein JSON-String, hier paramet erArrayStr i ng, und

ein Zeiger vom Typ NSE rror, also er ror, übergeben. Der Zeiger er ro r wi rd für den Fall zu­

gewiesen, dass bei der Konvert ierung ein Feh ler auftritt. Geschieht nichts, ist er n i l .

113

Page 115: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

Der Rückgabewert dieser Meidung ist in diesem Fa ll die Zahl -1. Wird ein JavaScript-Array

in einen String umgewandelt, wird es zum Zeiger vom Typ NSAr ra y, ein JavaScript-String

zum Zeiger vom Typ NSStr i ng. Wenn ein benutzerdefiniertes JavaScript-Objekt über­

geben wird, ist das Rückgabeobjekt ein Zeiger vom Typ NSDi ct i ona r y .

Nach der Abf rage des Befehls und der Parameter, die für ihn benötigt werden, kann für die

eigentl iche Berechnung eine i f- oder case-Anweisung verwendet werden. Eine solche

Gruppe von Bedingungen ist jedoch nicht optimal, weil sie bei jedem Hinzufügen oder

Entfernen eines Befehls geändert werden müssen. ln Kapitel 2 wird dieses Problem im

JavaScri pt-Teil der Qu ickCon neeti Phone-Architektu r durch Implementiereneiner Frontcon­

troller-Funktion mit dem Namen hand l eRequest gelöst, die Aufrufe von Implementie­

rungen der Anwendungscontroller enthält. Da hier dasselbe Problem vorliegt, sollte eine

Objective-C-Version von hand l eRequest es beheben. Abschnitt 3 behandelt die Imple­

mentierung der Front- und Anwendungscontroller in Objeetive-C. Die folgende Codezei le

fragt eine Instanz des QuickConnect-Objekts ab und übergibt ihr die mehrtei lige Meldung ha nd l eReq ues tWi t h Paramete r s. lnnerhalb der Delegatmethode s hou l dSta r tload ­

Wi t h Reques t ist keine weitere Berechnung erforderlich.

[ [Quic kConnect getlnstance ] handl eRequest:cmd wi t hParameters:paramsToPass];

Da die Meldung hand l eRequest der QuickConnectiPhone-Objekte verwendet wird,

muss es eine Möglichkeit geben, den Befehl der erforderl ichen Funktionalität zuzuord­

nen, wie es in Kapitel 2 mit JavaScript gezeigt w urde. Das QCCommandMa ppi ngs-Objekt

aus den Dateien QCCommandMa ppi ngs. m und . h der Gruppe QCOb j C enthält sämtliche

Zuordnungen fü r Geschäfts- und Ansichtssteuerobjekte (Business Control Obj ects, BCO,

bzw. View Control Objects, VCO) für dieses Beispiel.

Derfolgende Code ist die Methode mapCommands des QCCommandMappi ngs-Obj ekts, das

beim Start der Anwendung aufgerufen w ird. Ihm wi rd die Implementierung eines Anwen­

dungscontrollers übergeben, die zum Erstellen der Zuordnungen von Befehlen zu Funk­

tionalität verwendet wird. Eine Erläuterung des Codes für die Meldung mapCommand ­

ToVCO und den Aufrufvon mapCommands fi nden Sie in Abschn itt 3.

1 + Cvo i d ) mapCommands:CQCAppControl l er* )aCont r oll er{ 2 [aControl l er mapCommandToVCO:@" l ogMessa ge"

withFunction:@" LoggingVCO" J : 3 [aControl l er mapCommandToVCO:@" pl ay Sound"

withFunction:@" Pl aySoundVCO"J: 4 [aControl l er mapCommandToBCO:@" l oc "

withFunction:@" Locat ionBCO" J :

114

Page 116: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in Objective-c

5 [aContro l l er mapCommandToVCO :@"send l oc"

with Function:@" LocationVCO " J: 6 [aContro l l er mapCommandToVCO :@"showDate"

withFunct ion :@"DatePickerVCO "J : 7 [aContro l l er mapCommandToVCO :@"sendPickResu l ts "

withFunct ion :@"PickResul tsVCO" J: 8 [aContro l l er mapCommandToVCO :@"pl ay "

withFunct ion :@"Pl ayAud i oVCO " J: 9 [aContro l l er mapCommandToVCO :@"rec" withFunction:

@"RecordAudioVCO " J : 10 }

Zeile 3 des vorstehenden Codes bezieht sich auf das aktuelle Beispiel der Vibration des

Geräts. Wie in diesem Abschnitt bereits gezeigt, lautet dervom JavaScript -Teil der Anwen­

dung erhaltene Befeh l p l aySound. lndem dieser Befeh l als erster Parameter der Meldung

ma pComma ndToVCO und Pl aySoundVCO als Parameter fü r den zweiten Teil, wit h Func ­

t i on, gesendet werden, entsteht eine Verknüpfung, die den Anwendungscontrol ler ver­

an lasst, eine doCommand-Meldung mit dem Parameter - 1 an die Klasse Pl aySoundVCO

zu senden. Wie Sie sehen, werden hier al le anderen Befeh le des Beispiels Dev i ceCa ta l og

zugeordnet, die vom Java Script -Code gesendet werden.

Der Code fü r die Funktion Pl aySoundVCO, der der Befeh l pl aySound zugeordnet ist,

steht in den Dateien Pl aySoundVCO . m und Pl aySoundVCO. h. Die Methode doCommand

enthä lt das gesamte Verhalten des Objekts.

Um einen Systemklang abzuspielen, muss ein vordefinierter Klang verwendet werden. Bis­

her gibt es nur einen, die Vibration. Alternativ kann ein Systemklang aus einer Klangdatei

erstellt werden. Beispiele für beide Verha ltensweisen bietet die Methode doComma nd der

Klasse Pl aySoundVCO.

1 + (i d ) doCommand : (NSArray*) parameters{ 2 SystemSoundiD aSound =

3 [((NSNumbe r* ) [ parameters objectAtlndex:1 ] ) i ntVa l ue]; 4 i f ( aSound == - 1){ 5 aSound = kSystemSoundiD_Vib rate;

6 7 el se{

8 NSString *soundFi l e = 9 [[NSBundl e mainßundl e] pa th For Resource :@" l aser "

10 ofTy pe :@"wav " J : 11 NSURL *ur l = [ NSURL fi l eURLWithPath :sound Fi l e];

115

Page 117: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4

12 13 14 15 16

Systemeigene Funktionen von QuickConnect

// ist die Audiodat ei zu lang zum Ab sp ielen //wird der Fehl er -1500 gemeldet OSStat us err or = AudioSer v icesCreat eSystemSound i DC

CCFURLRe f) url, &a Sound ) ;

17 Aud ioSer vicesPlaySystemSound( aSound ) ; 18 retu rn ni l : 19

Wie Sie in Zeile 4 des vorstehenden Beispiels sehen, wird die Variable aSound der Klasse

Sy stemSound iD auf den definierten Wert kSy stemSound iD_Vi bra t e gesetzt, wenn

der Parameter mit dem Index 1 den Wert -1 aufweist. Wenn nicht, wird ein Systemklang

aus der Datei l aser . wav erstellt, die in der Gruppe Re sou rces der Anwendung steht,

und die Variable aSound auf einen Bezeichner gesetzt, der für den neuen Systemklang

angelegt w ird.

in beiden Fä llen w ird die ( -Funktion Aud i oSe r v i ces Pl aySys temSound aufgerufen und

der Klang abgespielt bzw. das Gerät in Vibration versetzt. Handelt es sich um einen iPod

touch, werden Vibrationsanforderungen vom Gerät ignoriert. in einer echten Anwendung

mit mehreren Klängen lässt sich diese Funktion leicht erweitern, indem andere Zahlen als

Bezeichnerfür den abzuspielenden Klang übergeben werden.

Da die Variable vom Typ SystemSound I D tatsäch lich numerisch ist, sollten die System­

klänge beim Start der Anwendung erstellt und ihre Bezeichner dem JavaScript-Teil zur

späteren Verwendung übergeben werden. Damit wird die Rechen last f ür das Neuerstel­

len der Klänge bei j eder Anforderung vermieden und die Qualität des Benutzererlebnisses

gesteigert, wei l das Abspielen nicht verzögert wi rd.

Nachdem Sie die Übergabe von Befehlen von JavaScript an Objective-C gesehen und er­

fahren haben, w ie Sie die Vibration auslösen oder einen ku rzen Klang abspielen, ist es

leicht zu verstehen, wie Sie Objective-C einen Befehl übergeben und die Ergebnisse an

den JavaScript-Tei l der Anwendung zurückgeben lassen.

Da diese Arten der Kommunikation ähnlich ablaufen, wird als Beispiel die GPS-Orts­

ermittlung gezeigt, eine beliebte Funkt ion von iPhone-Anwendungen. Sie nutzt die Fäh ig­

keit des QuickConnectiPhone-Frameworks zur bid irektionalen Kommunikation zwischen

JavaScript und Objective-C.

Wie bei allen vom JavaScript-Framework gesendeten Befehlen ist eine Zuordnung des

Befehls l oc erforderlich, damit die Daten abgerufen werden können und eine Antwort

zurückgehen kann.

116

Page 118: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in Objective-c

[aControll er mapCommandToBCO:@" l oc" withFunction:@"LocationBCO"J:

[aControll er mapCommandToVCO:@"sendloc" withFunction:@" Locat i onVCO"J:

Hier gibt es zwei Zuordnungen, eine an ein Geschäfts- und eine an ein Ansichtssteuer­

objekt. Wie in Kapitel 2 erörtert, sind Geschäftssteuerobjekte für die Abfrage, Ansichts­

steuerobjekte dagegen für die Darstellung von Daten zuständig.

Da Geschäftssteuerobjekte fü r einen konkreten Befehl vom QuickConnectiPhone-Frame­

work vor sämtlichen Ansichtssteuerobjekten ausgeführt werden, wird zuerst eine do ­

Command-Meldung an die Klasse Locat i onBCO gesendet, die die GPS-Daten abfragt und

zurückgibt. Die folgende Methode doCommand gehört zur Klasse Loc at i onBCO; sie führt die Aufrufe durch, die erforderlich sind, um das Gerät zum Suchen seiner GPS-Daten zu

veran lassen.

+ Ci d) doCommand : CNSArray*) parameters { Quic kConnect ViewCont ro l l er *contro l l er

(Quic kConnect Vi ewContro l l er*)[ parameters object Atlndex:OJ: [[cont rol l er l ocationManager ] startUpdatinglocati on ] ;

return ni l ;

Die Methode startet die GPS-Hardware durch Abfragen des ersten Elements im Parameter­

array, das ihr übergeben wurde und sie anweist, die Hardware zu starten. Das Framework

setzt den ersten Parameter immer aufden Qui ckConnec t Vi ewControll er, damit dieser

bei Bedarf von den Geschäfts- oder Ansichtssteuerobjekten benutzt werden kann, die mit

einem Befehl verknüpft sind.ln allen Geschäfts- und Ansichtssteuerobjekten in Objective-C

beginnen sämtliche von JavaScript-Code gesendeten Parameter mit dem Index 1.

Das Qui ckConnectVi ewControl l er-Objekt besitzt ein integriertes Attribut der Klasse

CLLocat i onManager mit dem Namen l oca t i onManager, das von Ihrer Anwendung

nach Bedarf ein- und ausgeschaltet wi rd. Es ist w icht ig, diesen Manager nicht länger als

nötig laufen zu lassen, wei l er viel Batteriestrom verbraucht. Deshalb schaltet der vorste­

hende Code die Ortshardware ein, indem er ihm jedes Mal, wenn ein Ort benötigt wi rd,

eine st a r t Updat i ng Loca t i on -Meldung sendet. Sobald der Ort gefunden ist, wi rd die

GPS-Hardware ausgescha ltet.

Obj ekte der Klasse CL Locat i onManage r verhalten sich asynchron, d.h., bei der Abfrage von Ortsdaten w ird eine vordefinierte Rückruffunktion aufgerufen, soba ld der Ort erm it ­

telt ist. Mithilfe dieser Funktion können Sie auf den Ortsmanager und zwei Orte zugreifen:

einen zuvor festgelegten und den aktuellen.

117

Page 119: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

Der Ortsmanager verfeinert die Ortsangaben für das Gerät schrittweise, wobei er die

Funktion d i dUpdateTo Locat i on mehrmals aufruft. Das folgende Codebeispiel soll

herausfinden, wie lange es dauert, den neuen Ort zu bestimmen. Zeile 9 stellt fest, ob es

weniger als fünf Sekunden sind, und beendet die Suche, wenn es so ist.

1 (vo i d) locationMana ger : (C LLocationManager *)manager 2 didUpdateTo l ocation: ( CLLocation *)newlocation 3 from l ocation:(CLLocation *)oldlocation 4 5 II wenn rel ativ kurz vorher erfolgt, Aktuali sierungen zwecks 6 II Stromersparnis ausschalten 7 NSDate* eventDa t e = newlocation.timestamp; 8 NSTimelnterval howRecen t =

9 [ eventDate timelnterva l SinceNow]; 10 if (abs ( howRecent ) < 5.0){ 11 [manager stopUpdating l ocation ]; 12 NSMutabl eArray *paramsToPass =

13 [[NSMutabl eArray all oc] in i tWithCapacity :2]; 14 [paramsToPass addObject:se l f]; 15 [paramsToPass addObject:newlocation]; 16 [[QuickConnect getlnstance] 17 handl eRequest:@" sendloc " 18 withParameters:paramsToPass];

19 20 II sonst Ereignis überspringen und nächstes verarbeiten. 21

Nach Beendigung der Ortssuche sendet der Code eine Meldung an den QuickConnectiPho­

ne-Frontcontrol ler, die besagt, er solle eine send l Oe-Anforderung mit Qui ckConnect ­

Vi ewContro l l er, se l funddem neuen Ort als zusätzlichem Parameter behandeln.

Der Befehl send l oc ist dem Handler Locati onVCO zugewiesen, dessen Methode do ­

Command im folgenden Beispiel vorkommt. Sie fragt die UIWebView mit dem Namen

webVi ew aus dem Qui ckConnectVi ewContro l l er ab, von dem die ursprüngliche

Anforderung von GPS-Ortsdaten ausging. Anschließend legt sie die GPS-Daten im Array

pass i ngArray vom Typ NSArray ab.

Um die GPS-Daten an das webVi ew-Objekt zurückzusenden, muss das Array, in dem sie

stehen, in einen JSON-String konvertiert werden. Um aus dem Array vom Typ NSArray

einen String vom Typ NSStri ng zu machen, wird dieselbe Klasse SBJSON eingesetzt, mit

der zuvor aus einem JSON-String ein Array erstellt w urde. Es geschieht in Zeile 21 und 22:

118

Page 120: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Geräteaktivierung in Objective-c

1 + (id) doCommand: (NSArray*) pa ramet erst 2 QuickConnect ViewControll er *cont roll er 3 (QuickConnect ViewControll er*) [parame t ers 4 objectAt i ndex :O] ; 5 UIWe bVi ew *webVi ew = [cont rol l er webVi ew] ; 6 CLLocation *l ocat ion = (C LLocat ion*) [paramet er s 7 object At i ndex :1] ;

9 NSMu t ableArray *pass i ngArray = [ [ NSMutabl eArray all oc] 10 initWithCapac ity :3]; 11 [pass i ngAr ray addObject: [NSNumber numberWi thDoubl e : 12 l ocat i on .coord i nate . l atitude]] ; 13 [pass i ngAr ray addObject: [NSNumber numberWi thDoubl e : 14 l ocation.coordi nate .l ongitude ]] ; 15 [pa ss i ngAr ray addObject : [NSNumber numberWi th Fl oa t : 16 l ocat ion. al t itude ]]; 17 18 SBJSON *generator = [SBJSON al l oc] ; 19 20 NS Erro r *error ; 21 NSStr i ng *pa ramsToPass = [generato r 22 s t r i ngWithObject :passingArray error :&error ] ; 23 [generator rel ease] ; 24 NSStr i ng *jsStri ng = [[NSStr i ng all oc] 25 i ni tW i th Fo rmat :@" handl eJSONReques t ( I showl oc I I I %@ 1

) " .

26 paramsToPass] ; 27 [webVi ew 28 str ingByEva l uati ngJavaSc r i ptF romStr ing :jsStr i ng] ;

29 [pass i ngAr ray re l ease ] ; 30 re tu rn ni l ; 31

Nach dem Umwandeln der GPS-Ortsdaten in einen JSON-St ring, der für ein Array mit Zahlen steht, wird das JavaScript-Modul innerhalb des webVi ew-Objekts aufgerufen. Dazu wird zunächst ein St ring vom Typ NSSt ring angelegt, der den auszufüh renden JavaScript-Code enthält. in diesem Beispiel handelt es sich um ein handl eJSONReq uest­Objekt, dem der Befehl showl oc und die GPS-Daten im JSON-Format als String übergeben werden. Wie in Abschnitt 1 gezeigt, führt diese Anforderung dazu, dass die GPS-Daten in einem d i v-Eiement in der angezeigten HTML-Seite erscheinen.

119

Page 121: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

Im Ansch luss an dieses Beispiel können Sie sich das Date Pi ckerVCO- und das Pi ck­

Res u l ts V CO-Objekt im Beispiel Dev i ceCa ta l og ansehen und feststellen, dass derselbe

Ansatz verwendet wird, um die Standardselektoren für Datum und Uhrzeit auszugeben,

die sogenannten Picker, die Objective-C bereitstellt. Mit JavaScript innerhalb von UIWeb­

View stehen Ihnen zwar auch vordefin ierte Picker zur Verfügung, die aber aus Benutzer­

sicht nicht so gelungen sind wie die standardmäßigen von Objeetive-C. Mit diesen Stan­

dardpickern und denen, die Sie möglicherweise definieren, ergibt sich für Ihre Web-Apps

ein angenehmeres Benutzererlebnis.

4.3 DIE ÜBJECTIVE- (-IMPLEMENTIERUNG DER

QUIC K(ONNECTIPHONE-ÄRCHITEKTUR

Der in Abschnitt 1 und 2 gezeigte Code stützt sich weitgehend auf eine Obj ective-C-Imple­

mentierung derselben Arch itektu r, die in Kapitel 2 erläutert wurde. in diesem Abschnitt

geht es darum, wie die Umsetzung der Architektur in Objeetive-C erfolgt. Eine vollstän­

dige Erläuterung der einzelnen Komponenten finden Sie in Kapitel 2, das die JavaScript­

lmplementierung enthält.

Wie in der JavaScript-lmplementierung werden alle Verha ltensanforderungen über einen

Frontcontroller erledigt, der in Form der Klasse Qu i ckConnect implementiert ist, deren

Quel le die Dateien Qu i ckConnect. m und Qu i ckConnect . h sind. Da von vielen unter­

schiedlichen Stellen innerhalb einer Anwendung Meldungen an diese Klasse gesendet

werden müssen, handelt es sich um ein Singleton (Entwurfsmuster).

Singleton-Klassen sind so geschrieben, dass dieser Klasse innerhalb einer Anwendung nur

ein einziges instanzi iertes Objekt zugewiesen werden kann. Bei korrektem Vorgehen gibt

es immer eine Möglichkeit, von einer beliebigen Stelle innerhalb der Anwendung einen

Zeiger auf dieses Einzelobjekt zu erhalten. Für das Singleton-Objekt von Qu i c kConnect w ird dazu eine Klassenmethode get I nstance erstellt, die eine Instanz von Qui ckCon­

nect zurückgibt, die beim ersten Aufruf der Methode zugewiesen w ird.

Da es sich um eine Klassenmethode handelt, kann der Klasse eine get Ins ta n ce-Mel­

dung gesendet werden, ohne ein Qu i ckConnect-Obj ekt zu instanziieren. Die Methode

gibt einen Zeiger auf die zugrunde liegende Qu i ckConnect-lnstanz zurück. Wie Sie im

folgenden Code sehen, weist sie dazu einem statisch defin ierten Qu i ckconnect-Zeiger

eine Instanz der Klasse zu.

+ (QuickConnect* )getinstan ce{

120

//da di ese Ze i l e stat i sch dekl ariert ist, //wi rd si e nur ei nmal ausge f ührt. stat i c Quic kConnect *mySelfQC = ni l ;

Page 122: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung der QuickConnectiPhone-Architektur

@synchr oni zed([Qui ckConnect cla ss ] ) { if (mySel fQC == nil ) {

mySelfQC = [ Qu i ckConnect singl eton ] ; [ mySelfQC i nit ]:

r et ur n mySelfQC ;

Die vor der lnitial isierung gesendete Einzelmeldung nutzt das Verha lten, das in der den

Qu i ckConnec t -Objekt en übergeordneten Klasse FTSWAbs t ractSi ng l eton defin iert

ist . Diese Oberklasse weist das eingebettet e Singleton-Verhalten zu, beispielsweise

over r i di ng new, c l one und andere Methoden, die j emand inkorrekt zur Zuweisung einer weiteren Qui ckConnect -lnstanz benutzen könnte. Deshalb lässt sich ein Oui ck ­

Connect -Obj ekt nur mithilfe der Methode get In sta n ce erstellen und verwenden. Nach

der Zuweisung muss ein Qui ckconnect -Obj ekt wie alle korrekt gebildeten Object ive-C­

Obj ekte initialisiert werden.

Sowohl die Zuweisung als auch die lnitial isierung des Obj ekt s fi nden nur statt, wenn dem

Attribut mySe l fQC noch kein Qui ckConnect -Obj ekt zugewiesen wurde. Wegen des

Synchron isationsaufrufs, der die Prüfung auf ein instanziiertes Qui ckConnect -Obj ekt

umschließt, sind die Prüfung und die lnitial isierung th readsicher.

Eine weitere Methode der Klasse Qui ckConnect ist pa rameters. Wie die JavaScript ­Funktion ha ndl eRequest ( aCmd, pa ramete r s) in Kapitel2 stellt sie das Verfahren zur

Anforderung der Ausführung von Funkt ionalität in Ihrer Anwendung dar.

Der Methode werden ein Befehlsstring und ein Array mit Parametern übergeben. Im fol­

genden Beispiel wi rd in Zeile 3 bis 9 eine Reihe von Meldungen an den Anwendungscont­

roller gesendet . Zei le 3 und 4 f ühren zuvor Ansichtssteuerobjekte aus, die mit dem Befehl

verknüpft sind. Bestehen der Befeh l und die Parameter die Validierung, werden ggf mit ­

hilfe einer d i spa t ch ToBCO-Meldung die mit dem Befeh l verknüpften Geschäftssteuer­

objekte ausgef ührt . Diese Meldung gibt ein Array vom Typ NSMutab l eAr ray zurück, das

die ursprünglichen Arraydaten von pa r amet e rs und zusätzlich alle Daten enthält, die von

einem aufgerufenen Geschäftssteuerobjekt gesammelt w urden.

1 - (vo i d) handl eRequest: (NSSt r i ng*) aCmd 2 with Parameters : (NSArray*) parameter s t 3 if( [ self - >t heAppCont ro l l er dispatchToVal CO : aCmd 4 wi thPa rame t ers :paramet er s ] != ni l ) { 5 NSMutabl eArray *newPa rame t ers =

6 [se l f - >theAppControll er di spat chToBCO : aCmd

121

Page 123: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

7 withParameters:parameters]; 8 [self - >theAppContro l l er dispatchToVCO:aCmd 9 withParameters:newParameters]; 10 11

Nach Abschluss des Aufrufs von d i spatchToBCO:withParameters wi rd eine

di spatchToVCO :wi thParameters-Meldung gesendet, was dazu führt, dass alle eben­

fal ls mit dem betreffenden Befeh l verknüpften Ansichtssteuerobjekte ausgeführt werden.

Indem für alle Anforderungen von Funktionalität die Methode handl eRequest: wi th­

Pa rameters verwendet wird, durchläuftjede Anforderung ein dreistufiges Verfahren:

1. Valid ierung

2. Ausführung von Geschäftsregeln {BCO)

3. Ausführung von Ansichtsänderungen {VCO)

Wie in der JavaScript-lmplementierung stellt jede d i s patchTo-Methode eine Fassade dar.ln

diesem Fa ll heißt die zugrunde liegende Objective-C-Methode d i spa tchToCO: wi th Para­

meters.

Sie ruft zuerst al le mit dem Befehl defaul t verknüpften Befehlsobjekte und die in aMap

übergebenen Parameter ab. aMap enthä lt abhängig davon, welche Fassadenmethode

aufgerufen wurde, Geschäfts-, Ansichts- oder Validierungssteuerobjekte. Diese Standard­

befeh lsobjekte werden, wenn vorhanden, abgerufen und fü r alle Befehle benutzt. Wollen

Sie, dass bestimmte Befehlsobjekte fü r alle Befehle verwendet werden, brauchen Sie sie

nicht j edem einzelnen Befehl zuzuordnen, sondern nur einmal dem Befehl defau l t.

Damit die abgerufenen Befehlsobj ekte verwendet werden, benötigen sie eine Meldung,

näml ich doCommand. ln Zeile 19 bis 23 des folgenden Codes wird diese Meldung als Selek­

tor abgerufen und die Meldung performSel ector übergeben, was dazu führt , dass die

Meldung doCommand ausgeführt w ird, die Sie in Ihrem OCCommandübj ect-Obj ekt imple­

mentiert haben.

1 - Cid) dispatchToCO: CNSString*)command withParameters: 2 CNSArray*)parameters andMap:CNSDictionary*)aMap{ 3 //ein mutabl es Array an l egen , dass sämt l iche 4 //vorhandenen Parameter enthäl t. 5 NSMutabl eArray *resul tArray; 6 if(parameters = nil ){ 7 resultArray = [ [ NSMutabl eArray al l oc ] 8 initWithCapacity:O ];

122

Page 124: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung der QuickConnectiPhone-Architektur

9 10 else{ 11 12 13

resultArray [[NSMutableArray al l oc] initWithArray:parametersJ:

14 //das Ergebnis auf etwas setzen, damit 15 //d ie Ausführung fortgesetzt wird, 16 //wenn keine Zuordnungen stattfinden . 17 id result = @"Continue" : 18 if( [aMap objectForKey:@"default"J != ni l ){ 19 SEL aSelector = @sel ector(doCommand); 20 whi l e((resul t = [ ((QCCommandObject*) 21 [aMap objectForKey:@"defau l t "J) 22 performSel ector:aSel ector 23 withObject: parameters]) != nil){ 24 if (aMap == se l f ->businessMap){ 25 [resul tArray addObject:resul t ] ; 26

27 28 29 //wenn al l e Methodenaufrufe der Standardbefehl sobjekte 30 //etwas zu rückgeben, al l e benutzerdefinierten ausführen . 31 if(resul t != ni l && [aMap objectForKey:command ] != 32 nil ){ 33 NSArray *t heCommandObjects = 34 [a Ma p objectForKey :commandJ : 35 int numCommandObjec ts = [theCommandObjects count ] ; 36 for(int i = 0: i < numCommandObjects ; i ++){ 37 QCCommandObject *theCommand =

38 [ t heCommandObjects objectAt i ndex:iJ: 39 resu l t = [theCommand doCommand:parameters]; 40 if( result == nil ){ 41 resu l tArray = ni l : 4 2 brea k: 43 44 4 5

4 6

47 48

if (aMap == se l f ->businessMap){ [ resu l tArray addObject:resul t];

123

Page 125: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

49 NSMutabl eAr ray* r esultAr r ayCopy =

[ NSMutabl eArr ay arrayWi thArray :resul t Ar ray ] ; 50 [ r esul tArray release] ;

51 i f ( aMap == sel f- >businessMap ) { 52 ret urn r esul tArrayCopy ; 53 54 return r esul t; 55

Nachdem alle doCommand-Meldungen an alle Objekte von QCC ommandObj ec t gesendet

wurden, die Sie dem Objekt de f au l t zugeordnet haben, geschieht dasselbe für Obj ekte

von QCComma ndObj ect, die Sie dem der Methode als Parameter übergebenen Befehl zu­

geordnet haben. Die QCCommandOb ject -Obj ekte haben dieselbe Existenzberechtigung

w ie die Steuerfunktionen in der JavaScript-lmplementierung. Da Objekte von OCComma nd ­

Obj ect den gesamten Verha ltenscode für Ihre Anwendung enthalten, wird mithilfe eines

Beispiels leichter verständlich, w ie sie angelegt werden.

QCComma ndOb ject ist die übergeordnete Klasse von Loggi ngVCO. Daher muss

Loggi ngVCO die Methode doCommand umsetzen. Es folgt der gesamte Inhalt der Datei

Loggi ngVCO. m in der Beispielanwendung Devi ceCat a l og. Ihre Methode doComma nd

schreibt in die Protokolldatei der laufenden Anwendung. Dieses Ansichtssteuerobjekt

protokolliert Fehlersuchmeldungen aus dem JavaScript-Code Ihrer Anwendung. Abbi l­

dung 4.2 zeigt die dafür notwendigen Aufrufe.

Die Methode doCommand der Klasse Logg i ngVCO ist kurz. Das sollte für doCommand­

Methoden für die verschiedenen Befehlsobjekte grundsätzlich so sein. Sie sollten nur eine

Aufgabe erledigen, und das gut. Wenn Sie feststel len, dass eine solche Methode, mit der Sie

arbeiten, lang wird, sollten Sie möglicherweise daran denken, sie in logische Komponenten

zu untertei len und mehrere Klassen fü r Befeh lsobjekte anzu legen. Wenn diese Methoden

zu lang werden, befassen sie sich nämlich wahrscheinlich mit mehr als einer Aufgabe.

Im folgenden Beispiel besteht die »eine Aufgabe«, die das Loggi ngVCO-Objekt erledigt,

im Protokollieren von Meldungen in der Feh lersuchkonsole von Xcode. Diese wen ig um­

fangreiche Komponente lässt sich natürlich in vielen Befehlen in Verbindung mit anderen

Befehlsobjekten wiederverwenden.

124

Page 126: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung der QuickConnectiPhone-Architektur

1 aute~cconn•C!rtwcontr•"" 1 1 oulc~, •• ",!C, 1 1 Aopn .....

1eo .... " ... 1

: .-:-. '

Ohf:VldeReQUes11'100iteSSO!Oie' , flfSSO:Qf) •

' ' ' ' ' ' ' ' ' U dtspatchToSCO(toc'. messaoe> ~spaX;hToCO (bgMes..o;.aoe·. message, 'liewMap)

::, --~~~~~~~ doColmlar<l(message)

' ' '

- ---== ==""'---- 0 ' : ' ' ' '

~ Abbildung 4.2: Ein Sequenzdiagramm zeigt die in Objective-C aufgerufenen Methoden für die Behandlung einer Anforderung zum Protokollieren einer JavaScript-Fehlersuchmeldung.

Das Verhalten dieses Ansichtssteuerobjekts besteht aus einer einzigen Zei le, die die Funk­

tion NS Log ausführt. Dabei w ird das erste Obj ekt im Parameterarray an einen statischen

String angehängt und ausgegeben.

#import "LoggingVCO.h "

@impl ementation LoggingVCO

+ Cid) doCommand:CNSArray*) parameters{ NS Log(@"JavaScriptMessage: %@" ,

[parameters objectAt i ndex:l]); return ni l ;

@end

125

Page 127: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 4 Systemeigene Funktionen von QuickConnect

Damit diese Protokol lierung stattfindet, muss eine Zuordnung zwischen dem Befehl l og­

Message und der Klasse Loggi ngVCO erst ellt werden. Wie in der JavaScript-lmplementie­

rung werden dazu l ogMessageals Schlüssel und der Name der Klasse l oggi ngVCO als

Wert in eine Zuordnungstabelle geschrieben.

Die Zuordnung erfolgt in der Datei QCCommandMapp i ngs. m. Derfolgende Code stammt

aus dieser Datei in der Beispielanwendung Dev i ceCata log und ordnet l ogMessageder Klasse Loggi ngVCO zu.

[aCon t ro l l er mapCommandToVCO:@"logMessage " withFunct i on:@"LoggingVCO "J:

Dem Anwendungscontroller wird die Meldung mapCommandToVCO:wit hFunction

übergeben, in der der Befehl der erste und der Name des Ansichtssteuerobjekts der zweite

Parameter ist. Diese und andere ähnliche Methoden zum Zuordnen der übrigen Befehls­

objekta rten sind Fassaden, die die jeweilszugrunde liegende ma pComma ndT oCO-Methode

aufrufen.

Diese mapCommandToCO-Methode ermöglicht die Zuordnung mehrerer Befeh lsobjekte zu

einem einzigen Befeh l, indem sie den Befeh l einem Array vom Typ NSMutab l eArray zu­

ordnet. Anschließend wird dieses Array benutzt, um die Cl a s s-Obj ekte aufzunehmen, die

dem als zweitem Parameter übergebenen Klassennamen entsprechen. Derfolgende Code

implement iert die Methode mapCommandToCO.

- (vo i d) mapCommandToCO:CNSString*)aCommand wit hFunct ion:(NSString*)aCl assName t oMap:CNSMutab l eDictionary*)aMap {

NSMutabl eArray *contro l übjects =

126

[ [aMap object ForKey:aCommand ] re t ai nJ: if (control übjects == ni l ){

NSMutabl eArray * tmpCn t r l Objs = [[NSMutabl eArray al l oc] i nitWi thCapacity: l];

[ aMap setübject: tmpCntr l Objs forKey:aCommandJ: contro l übjects = tmpCntr l Objs; [tmpCntr l Objs re l ease];

//D i e Steuerobjekt kl asse für den gegebenen //Namen abfragen und ein Objekt des betreffenden //Typs i n das Array für den Befeh l einfügen. Cl ass aCl ass = NSCl ass FromString(aCl assName); if(aCl ass != ni l ){

[ contro l übjects addObject:aCl ass];

Page 128: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Zusammenfassung

else{ MESSAGE( "unable t o fi nd the %@ cl ass.

Make sure tha t it exists under this name and try again. " );

Das Einfügen der Klassenobjekte in ein Array vom Typ NSMutab l eArray bietet die Mög­

lichkeit, eine beliebige Anzah l von Befehlsobjekten gleichen Typs, etwa Ansichts- oder

Geschäftssteuerobjekte oder andere, demselben Befehl zuzuordnen und dann einzeln in

der Reihenfolge auszuführen, in der die mapCommandTo-Meldungen gesendet wurden.

Auf diese Weise lassen sich mehrere Ansichtssteuerobjekte nacheinander ausführen.

Siekönnen beispielsweiseein Ansichtssteuerobjekt verwenden, daseine U IView anzeigt, auf

das ein weiteres folgt, das die Undurchsicht igkeit einer anderen UIView ändert, und darauf

die Protokollierung einer Meldung folgen lassen. Dafür reicht es, drei ma pCommandToVCO­

Meldungen mit demselben Befehl, aber drei verschiedenen Namen von Befeh lsobjekten zu

senden.

ln der Beispielanwendung Devi ceCa ta l og gibt es noch mehr Beispiele fü r Geschäfts­

und Ansichtssteuerobj ekte. Sie werden durch Anforderungen vom JavaScript -Teil der An­

wendung aktiviert.

4.4 ZUSAMMENFASSUNG

ln diesem Kapitel haben Sie erfahren, w ie Sie einige wünschenswerte iPhone- und iPod

touch-Merkmale aus Ihrer JavaScript-Anwendung heraus aktivieren. Die Nutzung von

G PS-Ortsdaten, Besch Ieu n igu ngsmesswerten, der Vibrationsfunktion und der Audiofäh ig­

keiten erweitern das Ausstattungsspekt rum Ihrer Anwendung.

Wenn Sie sich die in Dev i ceCata l og enthaltenen Beispiele ansehen und mit Objective-C

arbeiten, sol lten Sie in der Lage sein, weitere Merkmale wie das Durchsuchen des Bonjour­

Netzwerks auf in der Nähe befindliche Geräte, das Hinzufügen, Löschen und Abfragen von

Kontaktdaten aus der Kontaktdatenanwendung oder das Hinzufügen, Löschen und Abfra­

gen anderer integrierter Verhaltensweisen einzufügen, die in Objective-C-Anwendungen

zur Verfügung stehen.

Ihre JavaScript -Anwendung kann mithilfe des in diesem Kapitel beschriebenen Ansatzes

fast alles verwirklichen, was eine reine Objective-C-Anwendung beherrscht. Ein Beispiel

daf ür finden Sie in Kapitel 7, in dem Sie lernen, wie Sie Google-Karten in eine beliebige

Anwendung einbetten, ohne das Aussehen und die Anmutung der Kartenanwendungvon

Apple zu beseitigen.

127

Page 129: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 130: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Google Maps einbetten

Häufig brauchen Sie in einer iPhone-Anwendung eine Möglichkeit, um Landkarten anzu­

zeigen. Dazu gibt es verschiedene Mögl ichkeiten. Sie können die Anwendung schließen

und die normale iPhone-Anwendung Karten starten, aber auch Google-Standardkarten

verwenden. Beide Ansätze weisen ihre Grenzen auf. in diesem Kapitel erfahren Sie, w ie Sie

eine Google-Landkarte erstellen und verwenden, die sich wie die iPhone-Standardanwen­

dung Karten verhält, ohne dass Sie dazu Ihre Anwendung schließen müssen.

5.1 ABSCHNITT 1: EINE KARTE IN EINER JAVASCRIPT­

ÄNWENDUNG MIT QUICK(ONNECT ANZEIGEN

Für Ingenieure und Programmierer gibt es verschiedene Möglichkeiten, um fürWeb-Apps

auf dem iPhone Landkarten zu verwenden. Am einfachsten ist es, in der Anzeige einen Link

hinzuzufügen, der mit http://maps.google.com beginnt und zu dem gewünschten Karten­

material führt. Wenn der Benutzer auf diesen Link tippt, wi rd die Anwendung beendet

und die Standardanwendung Ka rten geöffnet, die dann die gewählte Landkarte anzeigt.

Dieser Ansatz lässt sich einfach verwenden und schnel l umsetzen. Der Nachtei l besteht

aber daran, dass Ihre Anwendung geschlossen w ird, was al lgemein als schlechtes Saft­

waredesign gilt. Eine Anwendung mit einem solchen Verhalten wirkt wie Fl ickschusterei.

Benutzer bevorzugen eine besser in die Anwendung integrierte Lösung.

Page 131: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

Es gibt noch einen weiteren Nachteil. Google kann mehrere Stecknadelsymbole zwar als

Reaktion auf eine Suchanfrage wie »Pizza« anzeigen, aber nicht für bestimmte von Ihnen

definierte Orte. Nehmen wir z.B. eine Anwendung, in der Sie Stecknadeln an verschiede­

nen Orten in einer Stadt anzeigen lassen möchten, die aber nicht mit suchbaren Begriffen

w ie »Pizza« verknüpft sind.ln der URL-Anforderung, die Sie an Google senden, können Sie

zurzeit keine Positionen für mehrere Stecknadeln mit Beschreibung angeben. Diese Ein­

schränkung kann ärgerlich sein, wenn Sie z.B. die Länge und Breite eines Ortes verwenden

möchten, um dort eine Stecknadel anzuzeigen.

Ein anderer Ansatz besteht darin, in Ihrer Anwendung das durchzuführen, was Sie auf einer normalen Webseite machen würden. Das heißt, Sie verwenden die AJAX-API von

Google, um eine Landkarte in einen d i V-Bereich der angezeigten HTML-Seite einzubetten.

Dann können Sie die JavaScript-API von Google nutzen, um die einzelnen Stecknadeln zu

setzen.

Dabei bleibt zwar der Benutzer in Ihrer Anwendung, aber auch dieser Ansatz weist Nach­

tei le auf. Erstens ist es in der U I WebVi ew, in der Sie die Karte anzeigen, nicht möglich, inner­

halb der di V-Bereiche zu blättern. Die Berührungs- und Verschiebungsereignisse werden

auf einer sehr viel tieferen Ebene verarbeitet und werden nicht an den von Google bereit­

gestel lten Java Script-Code gesendet, der dieeingebettete Landkarte handhabt. Das bedeu­

tet, dass Sie die Karte zwar anzeigen, aber den dargestellten Ort nicht ändern können.

Ein weiteres Problem bi ldet die Größe der Sprechblasen mit Informationen zu den Orten,

die in Google angezeigt werden. Sie sind f ür die Darstel lung im Browser eines ausgewach­

senen Computers dimensioniert. Auf dem iPhone dagegen bedeckt eine solche Sprech­

blase einen Großteil der Karte. Außerdem liegt die Sprechblase größtenteils außerha lb

des Bildschirms und kann daher aufgrundder erwähnten Einschränkung fü r das Blättern

nicht gelesen werden. Es ist zwar möglich, die Größe des Inhalts dieser Sprechblasen zu

ändern, nicht aber die Größe der standardmäßigen Google-Sprechblasen selbst.

Es wäre offensichtlich am besten, die Ka rte wie im zweiten Ansatz in die Anwendung ein­

zubetten und dadurch mehrere Stecknadeln anzeigen zu können, aber gleichzeitig die

Möglichkeiten zum Blättern und zur Anzeige aus dem ersten Ansatz beizubehalten. Das

Framewerk QuickConnectiPhone enthält eine Komponente, die es Ihnen ermöglicht, mit­

hilfe eines JavaScript-Auf rufs so vorzugehen.

Das Xcode-Projekt MapExamp l e zeigt, wie Sie dabei vorgehen müssen. Sie können dieses

Projekt als Tei l der Datei QuickConnctiPhone.zip von http:llsourceforge.netlprojectslquick­connect/ herunterladen. Dieses Beispielprojekt finden Sie im Verzeichnis iPhone Examples.

130

Page 132: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Eine Karte in einer JavaSaipt-Anwendung mit QuickConnect anzeigen

Der Hauptbi ldschirm dieses Beispiels besteht aus einer einzigen HTML-Schaltfläche, wie Sie in Abbildung 5.1 sehen. Der Listener oncl i ck dieser Schaltfläche ist auf die Funktion s howTheMa p gesetzt, die Sie in der Datei mainjs des Projekts finden und die im folgenden Code wiedergegeben ist. Sie richtet vier Orte ein, nämlich Rexburg in ldaho, Wyoming, einen Sandwich-Laden und eine Position in der Wi ldnis.

function showTheMap (event) {

II Ein Ort besteht aus Breitengrad , Längengrad und Beschreibung var locationsArray = new Array(); rexburg = new Array(); rexburg . pus h(43 .82211) ; rexburg.push( -111.76860); rexburg.pus h( "County Court Hause "); l ocationsArray . push(rexburg) ;

var wyoming = new Array() ; wyoming.pus h(42 .86); wyoming.pus h( -109 . 45) ; wyoming.pus h( "Wyoming Pl ace ") ; l ocationsArray . push (wyomi ng ) ;

var wi l derness = new Array() ; wi lderness . push( 45 .35 ) ; wi l derness . push( -115 ) ; wi l derness . push( "River of No Return Wi l derness"); l ocationsArray . push (wi l derness);

var SandwichShop = new Array() ; sandwichShop.pus h(42.86); sandwichShop.pus h( -112.45); sandwichShop.pus h( "Somewhere Sandwiches"); l ocationsArray . push (sandwichS hop) ;

showMap(event, locationsArray);

131

Page 133: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

~ Abbildung 5.1: Hauptbildschirm der Anwendung Ma p­Examp l e mit der HTML-Schaltjläche

Jeder Ort ist ein Array aus drei Elementen, dem Breitengrad, dem Längengrad und einer

ku rzen Beschreibung, die mit der Steckn adel angezeigt wird. Die einzelnen Orte werden

zu l ocat i onsArray hinzugefügt. Die Reihenfolge der Werte für die einzelnen Orte ist

festgelegt, die Reihenfolge der Orte in l ocat i onsAr r ay dagegen ist beliebig.

in der Praxis können die Werte für die einzelnen Orte in einer Datenbank gespeichert sein,

aus einem RSS-Feed oder einer anderen Quel le abgerufen werden. Sie können sie sogar

abrufen, während Ihre Anwendung läuft. Wenn Sie die Postanschrift kennen, kann die Geo­

code-JavaScript-API von Google daraus den Breiten- und Längengrad bestimmen (siehe

http:l/code.google.com/intl!de-DE!apis/mapsldocumentation/services.htmi#Geocoding_

Object). Wenn Sie diesen Vorgang zur Laufzeit erledigen, ist er jedoch langsam. Besser ist

es, Längen- und Breitengrad der gewünschten Orte beim Entwurf mit einem Stapelverar­

beitungsprozess zu ermitteln und vor der Auslieferung der Anwendung zu speichern.

Nachdem Sie das JavaScript-Array mit den erforderlichen Orten erstellt haben, w ird es an

die Funktion showMap des Frameworks übergeben. Ebenfal ls übergeben wi rd das Ereig­

nis, das den Aufruf dieser Funktion ausgelöst hat. Jetzt übernimmt das Framework die

Steuerung und verwendet die in Kapitel 4, »GPS, Beschleunigungsmessung und andere

systemeigene Funktionen von QuickConnect«, beschriebene Funktion ma keCa l l und

132

Page 134: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Eine Karte in einer JavaSaipt-Anwendung mit QuickConnect anzeigen

weist ihren Objective-C-Teil an, eine Landkarte mit Stecknadelsymbolen an den einzelnen

Orten anzuzeigen, wie Sie in Abbildung 5.2 sehen.

,.. Abbildung 5.2: Die Anwendung MapEx amp 1 e zeigt eine Stecknadel für jeden Ort an.

Das Framewerk zeigt die Ka rte in einem Objekt der Obj ect ive-C-Kiasse Ma pV i ew an. Diese

in Abschnitt 2 beschriebene Klasse ermöglicht dem Benutzer, die Anzeige der Karten wie

in der Apple-Anwendung Karten durch Antippen und Sch ieben zu steuern. Der Benut zer

kann auch auf eine St ecknadel doppelt ippen, um die Karte auf diesen Ort zu zent rieren

und zu vergrößern.

Wenn der Benutzer einmal auf eine Stecknadel tippt, wi rd ähnlich w ie in der Anwendung

Karten in einem kleinen schwarzen Feld eine Beschreibung eingeblendet (siehe Abbildung

5.3). Zieht der Benutzer eine Stecknadel, so w ird sie zu der neuen Posit ion auf der Ka rte

verschoben.

Wenn der Benutzer die Karte nicht mehr braucht, t ippt er auf die Schaltfläche DONE (FER­

TIG), worauf hin die MapVi ew verschwindet. Die Anwendung wird w ieder in dem Zust and

dargest ellt, in dem sie vor der Anzeige der Kart e wa r. Im Gegensatz zu dem Ansatz, die

Anwendung zu schließen, die Anwendung Kart en zu öffnen, diese Anwendung wiederum

zu schließen und dann die alte neu zu start en, best eht hier kein Problem der Usability und

der Wiederherstellung des alten Zustands.

133

Page 135: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

.,.. Abbildung 5-3: Die Anwendung MapExamp l e zeigt eine kurze Beschreibung an.

Durch den Aufruf der JavaScript-Funktion showMa p des Framewerks gewinnt Ihre Anwen­

dung eine integrierte Funktion zur Kartenanzeige.ln Abschnitt 2 erfahren Sie mehr darü­

ber, wie Ma pV i ew und andere Objective-C-Kiassen gestaltet sind und verwendet werden.

5.2 ABSCHNITT 2: DIE ÜBJECTIVE-(-IMPLEMENTIERUNG DES

KARTENMODULS VON QUICK(ONNECT

Das Ka rtenmodul von QuickConnect besteht aus drei Klassen:

> MapVi ew - Das Hauptelement zur Anzeige von Landkartenbi ldern

> Pi n - Eine benutzerdefinierte Stecknadel, die an einem Ort angezeigt werden kann

> I nf oW i ndow - Eine Klasse zur Anzeige einer kurzen Beschreibung bei einer Steck-

nadel

Abbildung 5-4 zeigt die Beziehungen zwischen diesen Klassen. Jede Ma pV i ew kann über

mehrere Pi ns verfügen, und j eder Pi n muss mindestens eine Ma pV i ew haben. Außerdem

besteht eine 1:1 -Beziehung zwischen Pi ns und I nfoWi ndows, d.h., es muss für j eden Pi n

ein I nfoWi ndow und fü r jedes I nfoWi ndow einen Pi n geben.

MapView t-11-----*-11 Pin t-11-----1-tl lnfoView

.,.. Abbildung 5.4: Die Klassen im Kartenmodul und ihre Beziehungen

134

Page 136: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung des Kartenmoduls von QuickConnect

Da eine Objective-C-Anwendung von Natur aus modular ist, muss sie direkt mit der Klasse

MapVi ew und deren API interagieren. Diese API besteht nur aus einer einzigen Methode,

näml ich i nitWith Frame: andLocat i ons. Beim Aufruf dieser Methode wird eine Karte

generiert, Stecknadeln werden darauf platziert, und eine kurze Beschreibung wird für Be­

nutzer bereitgestellt, die auf die Stecknadel tippen. Außerdem wird dafür gesorgt, dass die

Karte auf die Stecknadel oder den Ort zentriert und vergrößert wird, auf den der Benutzer

doppeltippt. Derfolgende Code zeigt, wie die MapView-API im Framework QuickConnect

verwendet wird.

Wie bei GPS-Ortung, Debugging und den anderen in Kapitel 2, »Die Modularität von

JavaScript für iPhone-Anwendungen«, beschriebenen Anforderungen verwendet der Auf­

ruf zur Anzeige einer Landkarte den Frontcontroller sowie Anwendungscontroller. Auch hier ist der Befehl showMap über die Datei QCCommandMappings.m mit dem VCO show ­

MapVCO verknüpft. Die Methode doCommand dieses VCO ist klein und besteht hauptsäch­

lich darin, die in der JavaScript-Anforderung übermittelten Längen- und Breitengrade

sowie die ku rze Beschreibung in ein Array zu packen. Dazu wird das erste Element des

Parameterarrays übersprungen, da es sich dabei um den Qui ckConnetVi ewContro l l er

für die Anwendung handelt. Die im folgenden Code gezeigte Methode doComma nd finden

Sie im Xcode-Proj ekt Map Examp l e, das Sie von http:l/sourceforge.netlprojectslquickcon­nect herunterladen können.

+ Cid) doCommand:CNSArray* ) parameters { NSRange aRange = NSMa keRange(l, [parameters count ] - 1); NSArray * l ocations = [ parameters subarrayWithRange:aRange ] ; I I Dimensioniert die MapView bi l dschirmfül l end MapView *aMapView = [[MapView all oc ] initWithFrame:[[ UIScreen

mainScreen] app l icationFrame] andLocations: l ocations]; QuickConnectViewControll er *theControll er =

[ parameters objectAt l ndex:O ] ; II Fügt die MapView zur Hauptansicht der Anwendung hinzu [ [ [ theContro l l er webView]

superview] addSubview:aMapView]; return ni l ;

Da der Qui ckConnectVi ewContro l l er einen Verweis auf die U I WebVi ew enthält, die

die Anzeige anzeigt und ausführt, kann er verwendet werden, um einen Zeiger auf die

Hauptansicht der Anwendung zu gewinnen. Dazu w ird die Nachricht supervi ew an die

U IWebVi ew gesendet. Die neue MapVi ew wird dann der Hauptansicht der Anwendung

135

Page 137: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

hinzugefügt, indem sie in der Nachricht addSubv i ew als Parameter übergeben w ird.

Nachdem diese Nachricht gesendet wurde, erscheint die MapVi ew und füllt den Bi ld­

schirm aus, sodass die UI WebV i ew verdeckt wird.

Da der Funktionsumfang von MapVi ew ein abgesch lossenes Modul bildet, kann er leicht

in vielen verschiedenen Anwendungen wiederverwendet werden (in Kapitel 2 erfahren

Sie mehr über Modularität). Er lässt sich sogar mit wenigen internen Änderungen zur

Anzeige von Karten in hybriden Macintosh-Anwendungen einsetzen.

Alle Google-Karten sind unabhängigvon ihrem lnhaltWebseiten. Daher hat das MapV i ew­

Objekt als Attribut eine eigene UIWebVi ew namens webMapVi ew. Dabei handelt es sich

nicht um die Instanz von U IWebVi ew, die die Anwendung anzeigt.

Wie Sie im folgenden Code sehen, zeigt webMapVi ew die Datei mapView.html an, die Sie

in der Gruppe RESOU RCES MAPVIEW finden. Als ihrDelegate ist die Klasse MapVi ew fest­

gelegt. Die Ma pV i ew-Gruppe enthält sowohl eine eingebettete U I Vi ew als auch einen

WebVi ewDe l ega t e, der sich um alle Ereignisse fü r die U I WebVi ew kümmert.

1 - Cid) i nitWithFrame:CCGRec t )frame 2 and l ocations:CNSArray*) al ocat ion l ist 3 if (se l f = [ super i nitWi t hFrame: frame]) { 4 OKToTouch = NO ; 5 se l f . l ocations = [a l ocationl i st objectAt i ndex:1]: 6 frame.or igin .y -= 20: 7 UIWebView * aWebView = [ [ UIWebView al l oc]

8 i nitWithFrame: frame] : 9 se l f .webMapView = aWebView:

10 [ aWebView re l ease ]; 11 12 aWebView. user i nt erac t ion Enabl ed = NO ; 13 // Leg t al s Del egate f ür die WebV iew 14 // die WebView se l bs t fes t 15 [ aWebView setDel egate:sel f ]; 16 17 // Best immt den Pfad zur Date i mapView . html 18 //im Verzeichni s Resources 19 NSStr i ng *fi l ePathString = [[ NSBundl e mainßundl e]

pathForResource:@"mapView "of Type:@"ht ml " J : 20 MESSAGE(@"%@", fi l ePathStr ing) ; 21 // Ers t el l t den URL und die Anforderung der 22 II Datei mapVi ew. html 23 NSURL *aURL = [NSURL fi l eURLWithPath:fi l ePa t hString];

24 NSURLReques t * aRequest =

136

Page 138: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung des Kartenmoduls von QuickConnect

25 26

[NSURLRequest requestWithURL:aURLJ :

27 II Lädt die Datei ma pV iew .html in die WebView 28 [aWebView l oadRequest:aRequest]: 29 30 II Fügt die WebView zur I nhaltsans i cht hinzu 31 [se l f addSubview:self.webMapViewJ: 32 33 return self: 34

Man könnte meinen, dass zur Vereinfachung auch auf die Klasse Ma pVi ew verzichtet

werden könnte. Dies ist jedoch nicht der Fall. Da die U I Web Vi ew alle Berührungsereignis­

se verarbeitet und nicht dafür sorgt, dass solche Ereignisse von den von ihr angezeigten HTML-Eiementen verarbeitet werden, würde sonst das in Abschnitt 1 beschriebene Prob­

lem auftreten, das der Benutzer in der Karte nicht verschieben kann.

Um dieses Problem zu lösen, schaltet Zei le 12 des vorstehenden Codes die Verarbeitung

der Ereignisse durch die entha ltene UI WebVi ew ab. Dadurch kann das umschließende

MapV i ew-Obj ekt alldiese Ereignisse als Delegate verarbeiten. Der Delegate muss dann

die U IWebVi ew anweisen, in der Seite, die in ihr enthalten ist, zu verschieben.

Um eine Karte zu verschieben, müssen Sie erkennen können, ob eine Berührung in einer

Verschiebebewegung fortgeführt wurde. Dazu implementieren Sie die Standardmethode

touchesMoved: wi thEvent von MapVi ew.

- (voi d)touchesMoved :(NSSet *)touches wit hEvent:(U I Event *)event{

if(OKToTouch ){ i f ([ touches count ] == 1 ){

UITouch *touch = [touches anyObject ]; CGPoint prevloc =

[ t ouch previous l oca t ion i nView:sel f ]; CGPoint curloc =

[ t ouch l ocationinView:sel f ]; double touchDe l taX cur l oc . x - prevloc . x; double touchDe l taY = cur l oc .y - prevloc .y ;

NSString *javaScriptCall = [ [NSString al l oc ]

ini tWithFormat:@"s crol l (%f , %f ) " ,touchDe l taX, touchDel ta YJ :

NSString *resul t = [ webMapView

137

Page 139: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

stringßy Eva1uatingJavaScriptFromString: javaScri pt Ca 11 ] ;

i f( [ res u1 t compare:@"true" J 0){ int numP ins = [ pi ns count ]: for(i nt i = 0: i < numPins: i++)(

Pin *aPi n =

[pins objectAtlndex:i J : [aP i n moveX:touchDe l taX

andY:touchDel taYJ: [aPin.info moveX:touchDel taX

andY:touchDe l taYJ:

el se if( [touches count] 2){ II Kneifbewegung

Diese Implementierung von touchesMoved :wi t hEvent bestimmt zunächst, wie weit

die Berührung fortgefüh rt w urde. Dazu w ird der Abstand (der Deltawert) zwischen der

Position des aktuellen und des vorhergehenden Ereignisses bestimmt und an die HTML­

Seite in webMapVi ew übergeben. Dazu w ird mit dem Aufruf der JavaScript-Funktion

scro 11 die Nachricht st ri ngßy Eva 1 uat i ngJavaScri ptFromStri ng gesendet.

Die JavaScript-Funktion sc ro 11, die Sie im folgenden Code sehen und in der Datei map.

js der Gruppe RESOURCES MAPVIEW finden, verwendet die JavaScript-API f ür Google-Land­

ka rten, um eine anzeigbare Karte neu zu zentrieren. Dazu w ird die angeforderte Änderung

zu den x-u nd y -Werten des aktuellen Kartenmittelpu nkts addiert und dann das Ka rten­

objekt angewiesen, sich auf diese neue Position zu zentrieren.

funct ion scro11 (de1ta X, del taY){

138

try{ var centerPoint = ma p.fromlat l ngToDi vPixel (map.getCenter ()) ; centerPoint.x -= del taX: centerPoint. y -= del taY: var center l at l ng =

map.fromDi vPixel Tola t l ng ( centerPoint) ; ma p. setCenter(center l at lng);

Page 140: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung des Kartenmoduls von QuickConnect

catch(error){ return fa l se;

return true;

Wird diese JavaScript-Funktion erfolgreich abgesch lossen, so gibt sie true zurück, sodass

der Rest der Methode touc hesMoved: wi thEvent al le angezeigten Stecknadeln anwei­

sen kann, ebenfa lls den Standort zu wechseln.

Da die Verarbeitung durch die zugrunde liegende U IWebV i ew ausgeschaltet ist, damit der

Benutzer die Karte verschieben kann, können die Stecknadeln normaler Google-Karten nicht

feststellen, dass sie berührt wurden. Daher können die standardmäßigen Sprechblasen für

die Beschreiung dieser Stecknadeln nicht angezeigt werden, weshalb es notwendig w ird,

eine eigene Pi n-Kiasse zu erstellen.

Diese Klasse, die Sie in der Gruppe (LASSES: MAPVIEW fi nden, verwendet das Bild pinlnser­ted.png aus der Gruppe RESOURCES: IMAGES zur optischen Darstel lung. Diese Datei können

Sie aber j ederzeit durch eine andere Bilddatei Ihrer Wahl ersetzen.

Fü r jeden Ort, den Ihre Anwendung von der JavaScript-Seite aus sendet, w ird ein Obj ekt der

Klasse Pi n init ialisiert. Dazu wird die im folgenden Code gezeigte Methode i nitWith­

Frame : a nd I mage: a nd Loca t i on : aufgerufen. Diese Methode erstellt eine U I ImageVi ew

fü r das Bi ld der Stecknadel, legt deren Posit ion fest und scha ltet die Verarbeitung der Ereig­

nisse ein, indem sie das Attributuser I nte ract i on Enab l ed desObj ektsauft rue setzt.

- ( id )i nitWithFrame: ( CGRect )frame and i mage:(NSString*)an i mage and l ocation: (MapViewl oca t ion)a l ocation{

if ( self = [super initWith Frame :frame]) UI ImageView * pinimage = [ [U I I mageView al l oc] ini tWithi mage: [ UI I mage imageNamed :an i mage] J : [self addSubview: pin i mage]; [ pin i mage re l ease]; l ocation = aloca t ion : self.user i nteractionEna bl ed = YES: self. backgroundCol or = [ UICol or cl earColo r ] :

return se l f:

Durch die Aktivierung der Benutzerinteraktion w ird das Pi n-Obj ekt fü r die pi nto-Ereig­

nisse verfügbar und kann diese vera rbeiten. Wird eine Stecknadel berührt, so w ird die

139

Page 141: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

Methode touchesßegan: wi thEvent des Pi n-Objekts aufgerufen und zur Änderung

der Anzeige herangezogen.

Die Implementierung dieser Funktion finden Sie in Pin.m und im folgenden Code. Sie prüft,

ob das aktuelle und das vorherige Ereignis dieselbe Position auf dem Bildschirm haben.

Dadurch wird sichergestellt, dass der Code in dieser Methode nicht ausgeführt wird, falls

der Benutzer den Finger über den Bildschirm gezogen hat.

HateinesolcheBewegungnichtstattgefunden,kümmertsich touches Bega n: wi t h Event

um zwei verschiedene Fä lle. Der erste liegt vor, wenn der Benutzer einmal auf die Steck­

nadel tippt. Dabei soll die einfache Nachricht angezeigt werden, die zusammen mit dem

Ort von der JavaScript-Seite der Anwendung übertragen wurde. Dazu werden die Refle­

xionsmöglichkeiten von Objective-C verwendet, um eine s i ngl e Touch-Nachricht an die

Stecknadel selbst zu senden.

AnstatteinendirektenAufrufdurchzuführen,wirddieNachrichtpe rfo rmSe 1 ecto r: wi t h ­

Object: afterDel ay an die Stecknadel gesendet. Dadurch kann zwischen einzelnem

und doppeltem Antippen unterschieden werden. Wie Zei le 13 zeigt, hat der Benutzer 0.4 sek Zeit, um einen Doppeltipp zu vollenden. Geschieht dies nicht, wird die erste Berührung

verarbeitet und die zweite als eigene Geste gewertet.

Tippt der Benutzer dagegen innerhalb des Grenzwerts von 0.4 sek zweimal auf die Steck­

nadel, wird die Nachricht cance l Prev i ous PerformRequestWi thTa rget: se l ect

or: object übergeben, die die Übergabe der s i ngl eTouch-Nachricht abbricht. Dieser

Ansatz mit verzögerter Ausführung und Abbruch ist die übliche Methode, um zu bestim­

men, ob ein einfaches oder doppeltes Antippen vorliegt.

Wird ein Einzeltipp erkannt, wird die Nachricht sing l eTouch übergeben und die kurze

Beschreibung der Stecknadel angezeigt. Bei einem Doppeltipp dagegen wird die Karte auf

die Position der Stecknadel zentriert und vergrößert.

1 - Cvoid)touchesßegan:CNSSet *)touches 2 withEvent:CU I Event *)event{ 3 UITouch * touch = [touches anyübject]; 4 CGPoint prevloc = [touch previous l ocationinView:sel f ] ; 5 CGPoint cur l oc = [touch l ocationinView:sel f ] ; 6 7 ifCCGPointEqua l ToPointCprev loc , curloc) ){ 8 NSU i nteger tapCount = [touch tapCount]; 9 switch (tapCount) {

10 case 1: 11 [se l f performSelector: 12 @se l ector(singl eTouch) 13 wi thObject:n i l afterDelay: .4]; 14 break;

140

Page 142: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

15 16 17 18 19 20 21 22 23

24

25

26

27 28 29 30 31

32

33 34

35 36 37 38 39 40 41 42

Die Objective-C-Implementierung des Kartenmoduls von QuickConnect

case 2: [NSObject cancelPrev ious PerformRequestsWithTarget:self

selector:@selector(s i ngleTouch) object:nil];

II Zentriert auf die Stecknadel und vergrößer MESSAG E(@"double tap pin %i, %i",

l ocation.x, locat i on.y);

double l atüffset = ( location.y+42 )1 ((Ma pVi ew*)self .superv iew) . pixelsPerDeglatitude ;

double l ngüffset = ( location.x+10)1 ((Ma pView*)sel f.superv iew).pixelsPerDeglongitude ;

double l atitude = [ [( (MapV iew*)sel f . superview). northWest objectAt i ndex:OJ doub l eVal ue] -l atOffset;

double longitude = [[ (( MapView*)self .superview). northWest objectAt i ndex:1] doub l eVal ue] + l ngüffset;

MESSAG E(@" l atitude: %f l ongitude: %f northWest: %@", l atitude, 1 ongitude, ((MapView*)self. superview).northWest);

NSString *javaScriptCa ll = [ [NSString alloc] i nitWithFormat:@"zoomTo (%f, %f) " ,

l atitude, 1 ongitude];

NSString *mapDescription [((MapView*)self .superv iew) .webMapView

stringßyEva l uatingJavaScriptFromString: javaScriptCall ];

[( (MapView*)self . superview) setMaplat l ngFrameWi thDescr i ption: mapDescription];

[( (MapView*)self . superview) updatePin locations];

brea k; default:

brea k;

141

Page 143: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

Dadurch, dass bei einem Doppeltipp auf eine St ecknadel oder die Karte die Ansicht zent­

riert und vergrößert wird, erhöht sich der Nutzwert der Anwendung. Die Standardanwen­

dung f ür Karten führt bei einem Doppelt ipp nur eine Vergrößerung durch, zentriert die

Karte aber nicht, wesha lb ein Benut zer danach gewöhnlich noch mit dem Finger über den

Bildschirm fahren muss, um die Gegend um den Ort anzuzeigen, der ihn int eressiert. Unse­

re Beispielanwendung hat diese Einschränkung nicht.

Sie können auch St ecknadeln auf der Kart e durch Ziehen verschieben lassen. Dazu dient

die im folgenden Code gezeigte Methode touc hesMoved : wi th Event. Dies f unktioniert

ähnlich wie das zuvor gezeigte Verschieben in der Karte. Ein Unt erschied best eht darin, dass erneut die Nachricht cancel Pr evi ousPerformReq ues t sWi thTa rget : se l ect­

or : object übergeben wird, damit nicht die kurze Beschreibung angezeigt wird, da die

Met hode t ouches ßegan vor t ouchesMoved aufgerufen wurde. Ohne diese Abbruch­

nachricht würde die Beschreibung angezeigt und dann die Stecknadel verschoben, was

aber unschön aussieht .

1 - Cvoid) touchesMoved: CNSSet *)touches 2 wi th Event: CU I Event *)even t { 3 if( [ touches count ] == 1) { 4 5 [ NSObject cancel PreviousPerf ormRequestsWithTarget: sel f

se l ector :@se l ec t or(si ngl eTouch) object :n i l ] ; 6 moved = YES; 7 UITouch *touch = [ touches anyübject]: 8 CGPoi nt prev l oc = [ t auch previouslocationinView: se l f ] ; 9 CGPoi nt curloc = [ tauch l ocationinView: se l f] ;

10 doubl e t ouchDel t aX = cur loc . x - pr evloc. x ; 11 doubl e t ouchDel t aY = cur loc .y - pr evloc. y ; 12 [ se l f moveX :touchDel t aX andY :touchDel t aY] ; 13 MapVi ew l ocat ion maploc = se l f . l ocat ion ; 14 map l oc . x += t ouchDel t aX ; 15 map l oc .y += t ouchDel t aY ; 16 se l f . l ocati on = maploc ; 17 if(self . info != ni l ){ 18 19 20 21 22

142

se l f . info.hi dden = TRUE; se l f . info. l abel . text = @"Unknown " ;

Page 144: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung des Kartenmoduls von QuickConnect

Wie beim Verschieben der Karte werden zum Verschieben der Stecknadeln die aktuelle

und die vorherige Position herangezogen, um die Platzierung zu ändern. Beim Verschieben

der Karte ist die Position der Mittelpunkt dieser, beim Verschieben der Stecknadeln der

obere linke Anzeigepunkt der Stecknadel in x- und y -Koordinaten.

Da die St ecknadel anschließend nicht mehr f ür den ursprünglich angegebenen Ort auf

der Karte steht, ist die mit ihr verknüpfte Beschreibung wahrschein lich ungültig und wird

daher auf Unknown gesetzt. Wird die Beschreibung angezeigt, wenn der Benut zer mit

dem Ziehen beginnt, so wird sie geschlossen, damit die CPU beim Ziehen nicht sowohl die

St ecknadel als auch die Nachricht zeichnen muss. Dies geschieht in Zeile 18.

Das Attribut i nf o der Klasse Pi n dient zur Anzeige der kurzen Beschreibung, die vom

JavaScript-Tei l der Anwendung zur Verfügung gestel lt wird. Es handelt sich dabei um ein

I n foWi ndow-Obj ekt, das selbst eine U I Vi ew ist und als einziges Attri but l abe l aufweist.

Die Methode in i tW i th Fr ame : a ndDes c ri pt i on von I nf oWi ndow, die Sie im folgenden

Code sehen und in der Datei lnfoWindow.m in (LASSES: MAPVIEW finden, legt die Posit ion

der Beschreibung im Fenster sowie deren Inhalt fest. Das Benutzerschnittst ellenelement

zur Anzeige der Beschreibung ist ein U I Labe l .

- ( i d)i nitWithFrame : ( CGRect ) frame andDescription : ( NSSt r i ng* )description{

i f ( se l f = [ super i ni tWithFrame :frame]) [ se l f setßac kgroundCol or : [U I Col or bl ac kCo l or ] ] ; CGRect l abel Fr ame = CGRec t Ma ke(O , 0 ,

frame . size.wi dt h , frame . size.height ) ;

l abel = [[UI Label all oc ] i ni t WithFr ame : l abel Frame ] ;

l abel . text = description; l abel . backgroundCol or = [ UICol or cl earCol or] ; l abel . t ext Col or = [ UI Co l or wh iteCol or ]; l abel . t ext Al ignment = UI Te xt Al ignment Cent er ; [ se l f addSubview: l abel ] ; [ l abel r el ease];

return se l f ;

Durch die Verwendung von U I Labe l zur Anzeige der Beschreibung öffnen sich Ihnen eine

Menge Möglichkeiten. Sie können jet zt die Schriftart, die Ausrichtung, Größe, Farbe und

viele andere Attribut e setzen, z.B. auch Schatten. Es ist zwar möglich, den Text direkt zu

143

Page 145: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5 Google Maps einbetten

zeichnen, ohne U I Labe 1 zu nutzen, aber dazu sind mehr Codezeilen erforderlich. Durch

die Verwendung der vorgefertigten Klasse U I Labe 1 gewinnen Sie eine deutlich wartungs­

freund lichere Anwendung.

Die drei Klassen MapVi ew, Pi n und I nfoWi ndow bilden das Ma pVi ew-Modul. Sie enthalten

den gesamten Quellcode, der zur Anzeige einer grundlegenden Google-Karte erforderlich

ist, lassen sich aber auf einfache Weise anpassen, um ein noch ausgefeilteres Verhalten zu

zeigen.

Beispielsweise können Sie die Klasse I nfoWi ndow so ändern, dass sie noch mehr Einzel­

heiten anzeigt, indem Sie entweder die Anzeigegröße anpassen oder eine ganz andere

UIV i ew anzeigen, z.B. die normale Kartenanwendung von Apple. Sie können auch dafür

sorgen, dass die Klasse MapV i ewebensowie die Standardanwendung Routen anzeigt.

Seide Änderungen erfordern zwar Kenntnisse in Objective-C, sind technisch aber nicht

aufwendig.

Ein weiterer bemerkenswerter Punkt, den wi r bisher noch nicht behandelt haben, ist die

Frage, wie die Positionen der Pi n-Objekte und ihrer I nf oW i ndows beim Verschieben und

Vergrößern der Karte angepasst werden. Jede dieser Klassen verfügt über die Methode

moveX: andY, deren Parameter die Anzahl der Pixel in x- und y-Richtung sind, um die die

Stecknadel oder das Informationsfenster verschoben werden soll. Diese Methode sehen

Sie im folgenden Code.

Unerfahrene Objective-C-Programmierer mögen versucht sein, die Position durch eine

Codezeile wie [se l f frame ] . o r i gi n . x += xChan ge zu ändern. Diese Codezei le löst

keine Ausnahme aus, führt nicht zu einem Kompilierungsfehler - und ändert die Position

der Stecknadel oder des Informationsfensters nicht.

In U I V i ew-Kiassen von Objective-C, z.B. Pi n und In f oW i ndow, wird der Rahmen, der die

obere linke Ecke und die Länge und Breite festlegt, nur in zwei Fällen verwendet. Erstens

geschieht dies bei der lnitialisierung mit der Nachricht i ni tW i th Frame. in diesem Fa ll

w ird die als Parameter ent haltene Rahmenstruktur dazu verwendet, die Größe der Ansicht

zu ändern. Der zweite Fall tritt auf, wenn das Attributframe gegen ein anderes ausge­

tauscht wird, w ie Sie in der Methode move X: andY sehen.

- ( voi d) moveX: (doub1e) xChange andY :( doub1 e)yChange { CGRect f rame = [ se1f frame ] ; frame.or i gin . x += xChange ; frame.or i gin .y += yChange ; se1f. frame = f rame;

Aufgrund dieser eingeschränkten Änderbarkeit hat die direkte Bearbeitung des Attributs

f r ameeiner Ansicht keinerlei Auswirkung.

144

Page 146: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Objective-C-Implementierung des Kartenmoduls von QuickConnect

Jedes Mal, wenn die Kartevergrößert oderverschoben wi rd,mussdie Methode mov eX: a ndY aufgerufen werden. ln der Methode touchesMoved :wi th Event der Klasse MapVi ew wird der Stecknadel diese Nachricht bei jedem erfassten Ereignis gesendet.

for(int i = 0; i < numPins; i++){ Pin *aPin = [pins objectAt l ndex:i]; [aPin moveX:touchDel taX andY:touchDeltaY]; [aPin . info moveX:touchDel taX andY:touchDeltaY];

Das Vergrößern der Karte erfolgt in der Methode touc hesEnded: wi thEvent der Klasse MapVi ew. Diese Nachricht wird vom Gerät an ein MapVi ew-Objekt gesendet, nachdem alle touchesßegan- und touchesMoved-Nachrichten verarbeitet wurden.

Im fo lgenden Code wird zunächst ermittelt, ob ein Doppeltipp vorliegt, und dann die Position bestimmt, an der auf die Karte getippt wurde. Anschließend folgt ein Aufruf der JavaScript-Funktion zoomTo, die wirzuvor im Beispiel zum Einzoomen auf eine Stecknadel gesehen haben.

1 - (voi d)touches Ended:(NSSet *)touches 2 withEvent:(U IEvent *)event{ 3 4 if(OKToTouch) { 5 UITouch *touch = [touches anyübject ]; 6 if ([touch tapCount ] == 2){ 7 II Zoomen und zentrieren 8 CGPoi nt cur l oc = [touch l ocation i nView:se l f]; 9

10 11 12 13

14

15

16

doub l e l atüffset curloc.ylsel f.pixel sPerDeglatitude; doub l e l ngüffset curloc.xlpixel sPerDeg l ongitude;

doub l e l atitude = [ [northWest objectAtindex:OJ doub l eVa l ue] - l atüffset;

doub l e l ongitude = [[northWest objectAt i ndex:1] doub l eVa l ue] + l ngüffset;

NSString *javaScriptCa ll =

[[NSString all oc] i nitWithFormat: @"zoomTo(%f, %f) " , l atitude, l ongitude];

NSString *ma pDescript ion = [webMapView stringßyEval uatingJavaScriptFromString: javaScri ptCa ll ];

17 18 [sel f setMa plat l ngFrameWithDescription:mapDescripti on ] ;

145

Page 147: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 5

19 20

Google Maps einbetten

[ sel f updatePinlocationsJ:

21 el se t 22 NSLog(@"touched"); 23 24 25

Nachdem die Vergrößerungaufgrund des Doppeltipps auf ein Pi n-oder MapV i ew-Objekt durchgeführt worden ist, wird die Nachricht updatePi nlocat i ons an das MapV i ew­Objekt gesendet, wie Sie in Zeile 19 des vorstehenden Codes sehen. Der folgende Code zeigt, wie durch diesen Aufruf die Positionen der einzelnen Stecknadeln anhand von deren Längen- und Breitenwert sowie des Vergrößerungsfaktors aktual isiert werden.

Als Maß für die Vergrößerung dienen die Attribute pi xe l sPerDeg l atitude und p i xe 1 s pe rDeg Long itude (Pixel pro Breiten- bzw. Längengrad) der Klasse Ma pVi ew, die im vorherigen Aufruf der Methode setMap Lat LngFrameWi t hDescri pt i on gesetzt wurden.

1 - (void) updatePin locationst 2 int numPins = [pins count ] ; 3 for(int i = 0: i < numPins; i++H 4 Pin *aPin = (Pin*) [pins objectAt l ndex:i J : 5 doub l e l atitudeDel ta = [ [northWest objectAtlndex:OJ

doub l eVa l ue] - aPin. l ocation. l atitude: 6 doub l e l ongitudeDel ta = aPin. l ocation. l ongitude -

[[northWest objectAtlndex: 1] doubl eVa l ue ] ; 7 8 doub l e yPixe l s = l atitudeDel ta * pixel sPerDeg latitude; 9 doub l e xPixel s = l ongitudeDel ta * pixel sPerDeglongitude;

10 MapViewl ocation aPin l ocation = aPin. l ocation: 11 aPinlocation.x = xPixel s - 10 - 4; 12 // Die sichtbare Stecknadel befindet sich zehn Pixel von 13 // l in ks im Bild 14 aPinlocation.y = yPixe l s - 42 + 10; 15 // Die sichtbare Stecknadel befindet sich zehn Pixel von 16 // unten im Bi l d 17 18 CGRect pinFrame = aPin.frame; 19 pinFrame.origin .x = aPin l ocation.x;

146

Page 148: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Zusammenfassung

20 pi nFrame . or i gi n. y = aPin l ocat ion .y ; 21 aPi n . f rame = pi nFrame; 22 aPin . l ocation = aP i n l ocati on : 23 24 CGRect i nfoFrame = aPi n . i nfo. frame: 25 i nfoFrame. or i gin. x = aP i nl ocat i on . x - 100: 26 i nfoFrame. or i gin. y = aP i nlocat i on .y - 30: 27 aPi n . i nfo. frame = i nf oFrame: 28 29

Wie in der Methode moveX : andY muss der Rahmen abgerufen, verändert und dann zu­

rückgesetzt werden. Dies geschieht in den Zeilen 18 bis 22 des vorstehenden Codes für die

Steckn adel und in den Zeilen 24 bis 27 für das zugehörige I nfoW i ndow des Pi n-Objekts.

Die Positionen der einzelnen Pi n- und I nfoWi ndow-Objekte werden bei jeder Vergröße­

rung angepasst. Dabei ist es möglich, dass einige nicht mehr innerhalb der Ma pV i ew sicht­

bar sind, was j edoch kein Problem darstellt. Sie werden einfach im nicht sichtbaren Bereich

außerhalb des Bi ldschirms dargestellt . im Code müssen sie nicht ausgeblendet werden.

5.3 ZUSAMMENFASSUNG

in diesem Kapitel haben Sie gesehen, wie Sie Google-Landkarten in Ihre Anwendung

aufnehmen und ein Modul zur Kartenanzeige erstellen. Außerdem haben Sie gesehen,

wie Sie die Posit ionen von benut zerdefin ierten und St andardansichten bearbeiten.

Durch den wohl überlegten Einsatz von JavaScript -Aufrufen für eine Google-Karte, die

in einer U I WebV i ew angezeigt w ird, können Sie die JavaScript-API von Google zum Ver­

größern und Zentrieren nutzen.

All dies ist im Fra mework QuickConnect enthalten, sodass Sie mit einem JavaScript-Auf­

ruf eine vollständig verwendbare Google-Karte anzeigen können. Das Kartenmodul ist

nicht nur auf der JavaScript -Seite des Frameworks einfach zu verwenden, sondern auch in

Obj ective-C-Anwendungen, die Sie für das iPhone schreiben. Mehr als wen ige Zei len Code

ist dafür nicht erforderlich.

Benutzerdefin ierte, eingebettete Google-Karten liegen nun für Ihre iPhone-Anwendun­

gen im Bereich des Möglichen. Version 3-0 von iPhone OS hat dies sogar noch einfacher

gemacht.

147

Page 149: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 150: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Datenbankzugriff

Die meisten auf JavaScript aufbauenden Anwendungen brauchen einen Webserver zum

Speichern von Daten. Mit iPhone OS 2 .0 oder höher und der Klasse U I WebVi ew können Sie

Daten ohne Netzwerkzugriff auf dem iPhone speichern. Das bedeutet, dass die Anwen­

dung, die Sie erstel len, ein Bürger erster Klasse auf dem iPhone ist.ln diesem Kapitel lernen

Sie, wie Sie Daten speichern und abrufen und w ie Sie Datenbanken und Tabellen erstel­

len. Sie erhalten hier einen einfach zu verwendenden JavaScript-Wrapper fü r die auf dem

iPhone verwendete SQLite-Datenbank. lm ersten Abschnitt geht es um die ersten Schritte

zur Verwendung der Datenbank, in den folgenden Abschnitten um den Wrappercode.

6.1 ABSCHNITT 1: DIE BEISPIELANWENDUNG

BRowsERDBAccEss

Das Beispiel BrowserDBAccess soll Ihnen zeigen, wie Sie Datenbanken in JavaScript­

Anwendungen einsetzen können. Sie fi nden es im Verzeichnis Examples des QuickConnectFa­mi(y-Ordners und können es von http:l/sourceforge.netlprojectslquickconnect/ herunterladen.

Diese Beispielanwendung erstellt die SQLite-Datenbank s amp l eDB mit derTabeile s co re.

Diese Datenbank befindet sich in der UIWebVi ew und erm öglicht dem Benutzer, Infor­

mationen abzuf ragen. Auf diese Weise erstel lte Datenbanken verbleiben zwischen dem

Page 151: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Seenden und dem Neust art der Anwendung auf dem Gerät, auch wenn sie nicht mit

der Anwendung inst alliert wurden. Daher sind Dat en, die Sie in der Dat enbank abgelegt

haben, immer noch da, w enn Sie die Anw endung neu starten. Abbi ldung 6.1 zeigt die Bei­

spielanwendung, bevor eine Abf rage an die Dat enbank gesendet wird.

DATENBANKEN , SO W EIT DAS Ä UGE REICHT

Für Datenbanken gibt es ein besonderes Vokabular. Zum Gruppieren ähnlicher Elemen­

te werden Tabellen verwendet, und diese Elemente werden jewei ls als Datensätze an­

gesprochen. Datensätze bestehen aus Werten, die in sogenannte Felder eingetragen

werden, und Felder wiederum sind durch ihren Namen und ihren Typ definiert. Wenn

Sie sich einen Datensatz als eine Zeile in einem Arbeitsblatt vorstellen und ein Feld als

eine Spalte, kommen Sie der Wahrheit schon recht nahe. Tabellen ähneln den Arbeits­

blättern einer Tabellenka lkulationsanwendung. Wenn Sie in einer Datenbank einen

neuen Datensatz zu einer Tabelle hinzufügen, ähnelt das dem Vorgang, eine neue Zei le

in ein Arbeitsblatt einzufügen. Es ist nicht dasselbe, aber die Ähnlichkeiten sind stark

genug, um dieses Beispiel zum leichteren Verständnis heranziehen zu dürfen.

Ein Primärschlüssel ist etwas, das einen bestimmten Datensatz in einer Tabelle eindeu­

tig bezeichnet. Es kann sich dabei um einen Integerwert oder um Text handeln, aber es

dürfen keine Duplikate auftreten. Der Primärschlüssel ähnelt der Kombination aus Be­

nutzername und Kennwort für die Apple Developer Connection. Es wäre offensichtlich

von Übel, wenn zwei Personen dieselben Anmeldeinformationen hätten.

Ein Fremdschlüssel dagegen ist etwas völlig anderes. Er wird verwendet, um Daten

aus zwei verschiedenen Tabellen zu verknüpfen. Stellen Sie sich zwei Tabellen vor,

owners und dogs . Die Tabelle owners hat einen Primärschlüssel für jeden Daten­

satz. Um deutlich zu machen, welcher Hund zu welchem Besitzer gehört, wird in die

Tabelle dogs ein Fremdschlüssel eingefügt, der den Primärschlüssel des Besitzers aus

der Tabelle owne r s enthä lt. Das ist so ähn lich wie die Registrierungsnummer auf der

Steuermarke des Hundes, mit der der Besitzer ausfindig gemacht werden kann, wenn l sein Hund im Tierheim landet.

150

Page 152: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

SQLite-Datenbanken der WebKit-Engine verwenden

Wtbl<it Darabast Name: s.an1pleDB

SQL: SELECT • FROM scorc

~ Abbildung 6.1: Die Anwendung BrowserDBAccess vor dem Ausführen einer Abfrage

Die Tabellescore in der Anwendung Browse r DBAcces s besteht aus zwei Feldern. Das

erste ist ein Text-Primärsch lüssel namens pl ay er _name, das zweite ein Integerfeld

namens score. Das Primärschlüsselfeld wird nicht automatisch inkrementiert, weshalb

der Benutzer jedes Mal, wenn er einen Datensatz einfügt, einen Wert dafür angeben muss.

Die Anwendung B rowse r DBAcces s nutzt verschiedene vorgefertigte JavaScript-Kiassen,

-Methoden und -Funktionen, um auf die Daten in der Datenbank s amp 1 eDB zuzugreifen.

6.2 ABSCHNITT 2: SQLITE-DATENBANKEN DER WEBKIT­

ENGINE VERWENDEN

Eine Datenbank verwenden zu müssen, mag manchmal einschüchternd wirken. Program­

mierer und Ingenieure müssen an unzählige mögliche Fal lstricke denken, wenn sie Informa­

tionen speichern oder abrufen. Nur zu oft ha lten diese möglichen Fal lstricke Programmierer

davon ab, Datenbanken für die einfache Datenspeicherung einzusetzen.

Auf dem iPhone werden Daten in und fü r Anwendungen standardmäßig in der eingebet­

teten SQLite-Datenbank statt in Text- oder Binärdateien festgehalten. Die schnelle und

einfache Verwendung dieser Datenbank-Engine kann über den Erfolg Ihrer Anwendung

entscheiden. Um die Entwicklung zu besch leunigen, ist im QuickConnectiPhone-Frame­

work eine entsprechende JavaScript-Kiasse ent halten, sodass Sie sich nicht um die Prob­

leme bei der Verwendung von Datenbanken zu kümmern brauchen.

151

Page 153: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Die Datei DataAccessObjectjs, die Sie in der Gruppe QC i Phone sowohl in der Dashcode- als

auch in der Xcode-Vorlage finden, enthä lt einen Wrapper für den Code, der für den Zugriff

auf die SQLite-Datenbank erforderlich ist. Diese JavaScript-Datei wird sowohl durch die Dashcode- als auch die Xcode-Vorlage automatisch in die index.htmi-Datei Ihrer Anwen­

dung aufgenommen. Dieser Wrapper, die Klasse Da taAccessObj ect, besteht aus einem

Konstruktor und mehreren Methoden. Die vier wichtigsten sehen Sie in Tabelle 6.1.

Attribut/Methode Rückgabewert Beschreibung Parameter

DataAccesOb- Da taAccess - Erstellt beim DbName- Ein String, der ject ( dbName, Object Aufruf mit dem die Datenbank eindeutig dbVersion, Sch lüsselwort bezeichnet dbDescript ion, new ein Da ta -

dbVers ion- Ein String, dbSi ze. AccessObject

der gewöhnlich die Form isNat iveDatabase)

einer Fließkommazahl

aufweist

dbDes cri pt ion-Ein

String, der den Zweck

der Datenbank angibt

dbS i ze- Der Mindest-

betrag an Festplatten-

platz in Byte, der der

Datenbank zugewiesen

wird . Wird NULLoder gar

nichts übergeben, be-

t rägt der Standardwert

5 MByte.

isNat iveDa tabase -

Ein Boole, der besagt, ob

es sich um eine native

(mit der Anwendung installierten) Datenbank

handelt

152

Page 154: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

SQLite-Datenbanken der WebKit-Engine verwenden

getData CSO L . Keiner Die Methode ruft SOL- ein gült iger SQL-parameterArray) m it dem überge- Befeh lsstring

benen SQL-Code pa ramete rA rray- Ein

Informationen Array aus Werten, das

aus einer in der

UIWebView verwendet w ird, wenn es

sich bei dem SQL-Befeh l erstellten Daten-

um eine vorbereitete bank ab

Anweisung handelt

setData CSO L . Keiner Die Methode SOL- ein gültiger SQL-parameterArray ) speichert mit Befeh lsstring

dem übergebe-pa rame t erArray-

nen SQL-Code Ein Array aus Werten,

Informationen das verwendet wi rd,

in einer in der wenn es sich bei dem

UIWebView SQL-Befeh l um eine

erstellten Daten-vorbereitete Anweisung

bank handelt

getNat i veData CSOL. Keiner Die Methode ruft SOL- ein gült iger SQL-parameterArray) m it dem überge- Befeh lsstring

benen SQL-Code pa rame t erArray-

Informationen Ein Array aus Werten,

aus einer mit das verwendet wi rd,

der Anwendung wenn es sich bei dem

install ierten SQL-Befeh l um eine

Datenbank ab vorbereitete Anweisung

handelt

setNat i veData CSOL. Keiner Die Methode SOL- ein gült iger SQL-parameterArray) speichert mit Befeh lsstring

dem übergebe-pa rame t erArray-

nen SQL-Code Ein Array aus Werten,

Informationen das verwendet wird,

in einer mit der wenn es sich bei dem

Anwendung SQL-Befeh l um eine

i nsta liierten vorbereitete Anweisung

Datenbank handelt

Tabelle 6.1: Die wichtigsten vier Methoden von Da t aAcc essObj ec t

153

Page 155: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel6

Diese JavaScript-Wrapperklasse wird in der Datei databaseDefinitionjs verwendet, die

durch die Vorlage in Ihre Anwendung eingefügt wird.ln dieser Datei geben Sie an, welche

Datenbanken Ihre Anwendung nutzt.

Der folgende Code stammt aus der Datei databaseDefinitionjs der Beispielanwendung

BrowserDBAccess und zeigt, wie der Konstruktor eingesetzt wird, um eine Datenbank

zu erstellen, die von der in iPhone-Web-Apps verwendeten WebKit-Engine verwaltet wird.

Die integrierte Datenbankunterstützung der Engine können Sie verwenden, wenn alle er­

forderlichen Daten von der Anwendung nach ihrer Installation generiert werden.

var sampl eDatabase = new DataAccessObject("sampl eDB" , "1.0", "a sampl e database", 2000);

Der vorstehende Code erstellt die Datenbank sampl eDB (oder öffnet sie, falls sie bereits

vorhanden ist). Da sich die WebKit-Engine um die Erstellung und Verwendung dieser

Datenbank kümmert, braucht sie einige Informat ionen. Die erste ist die Versionsnummer

der Datenbank, die Sie auf jeden beliebigen Wert setzen können. ln diesem Beispiellautet

er 1. 0. Die Datenbank wird außerdem mit einer Maximalgröße von 2000 Byte initial isiert.

Wäh len Sie hierbei die Größe aus, die Ihnen geeignet erscheint.

Der gezeigte Konst ruktor gibt ein Da taAccessObject zurück, das mit der zugrunde lie­

genden SQLite-Datenbank verbunden und einsatzbereit ist. Änderungen an der Daten­

bank sind jetzt möglich; ein Beispiel dazu finden Sie in dem folgenden Code, der zeigt, w ie

Sie die Methode set Da ta des DataAccessObj ect verwenden:

sampl eDatabase . setDataC " CREATE TABLE I F NOT EX I STS score C'p l ayer_name ' VARCHAR PRIMARY KEY, ' score' I NTEGER) ;");

Dieser SQL-Befehl dient dazu, die Tabelle zu erstel len, aber die Methode set Da ta können

Sie f ür alle SQL-Anforderungen verwenden, die Datenbanktabellen bearbeiten, Daten ein­

fügen oder entfernen oder die Datenbank auf irgendeine Weise verändern.

Wie in Kapitel2, »Die Modularität von JavaScript f ür iPhone-Anwendungen«, beschrieben,

besteht ein Verwendungszweck von BCFs (Business Control Functions) darin, Daten aus

der Datenbank abzurufen. Die BCF getScores BCF (d ie im folgenden Code gezeigt wird)

erfü llt diese Aufgabe. Sie finden sie jeweils in der Dateifunctionsjs der Beispiele.

Diese BCF verwendet die Methode getData des DataAccessObj ect, um die Datensätze

aus der Tabelle score abzurufen. ln Zei le 3 sehen Sie den Aufrufvon getData.

1 function getScoresBCFCparameters) { 2 var SOL= ' SELECT * FROM score ' ; 3 sampl eDatabase.getDataCSQ L) ; 4

154

Page 156: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

SQLite-Datenbanken der WebKit-Engine verwenden

Abbildung 6.2 zeigt die mit dieser BCF abgerufenen Daten. Beachten Sie, dass get ­

ScoresBC F nichts zurückgibt, da die Methode getData asynchron ist und daher die

Ergebnisse der SQL-Abfrage nicht zurückgibt. Das QuickConneetiPhone-Framework küm­

mert sich um den Empfangder Daten und übergibt sie an dieSteuerobjekte,die demselben

Befehl zugeordnet sind wie die BCF. Die VCF (View Contra I Function) d i s p l aySco res VC F

in der Dateifunctionsjs ist demselben Befehl zugeordnet wie getScoresBC F, weshalb

das Framework die Informationen, sobald sie verfügbar sind, dieser VCF übergibt.

Wcl>Kil Dntal>as• Namt: sampl<OB

SQL: SELECT • FROM S<Ore

c~ .. Q~O')' > pJ.a)"i'r_n~nte u en bob 100

1000 jo~ S()()

sooo mgo 5SOO

This should really do some actual work!

~ Abbildung 6.2: Die Beispielanwendung BrowserDBAccess nach dem Antippen der Schaftjläche Execure QUERY

Das Einfügen von Daten in eine Tabelle läuft sehr ähnlich ab. Wenn ein Datensatz für eine

Personnamens Jane eingefügt werden soll, wird setData aufgerufen, wie Sie im Folgen­

den sehen:

sampl eDatabase.setData( "I NSERT INTO score VALUES( 'bob', 100)");

Es ist nicht üblich, Werte in SQL-Anweisungen hart zu kodieren, denn gewöhnlich werden

die Werte durch den Benutzer eingegeben. Es ist zwar möglich, eine SQL-Anweisung wie die

vorstehende aus Benutzereingaben zu konst ruieren, aber das kann gefahrlieh werden. Der

folgende Code zeigt, wie Sie dieses Risiko mithilfe von vorbereiteten Anweisungen meiden:

func t ion setScoresBCF(parameters){ var name = document .get El ementßyld( ' nameFi eld').value; var score = document.get El ementßyld( ' scoreFiel d ' ) .va l ue; var StatementParamet ers = [ name , score]; var SO L = "I NSERT I NTO score VALU ESC? , ?) " ; samp l eDatabase . setData(SQ L , st atementParameters);

155

Page 157: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Dies sieht anders aus als der Auf ruf von setData zum Erst ellen der Tabelle scor e.ln dem

Tei l des SQL-Strings, in dem sich der Name und ein Punktestand befinden sollten, stehen

stattdessen Fragezeichen. Dabei handelt es sich um Platzhalter, die in vorbereitet en An­

weisungen die Stellen markieren, an denen Dat en aus dem Array st atement Pa r amete r s

eingef ügt werden sollen. Der Programmierer ist daf ür verantwortlich, dass die Werte im

Array in derselben Reihenfolge plat ziert sind wie im SQL-St ring. Aus diesem Grunde st eht

die Variable name im Array sta t emen t Parameters vor score.

WAS SIND VORB ERE ITETE ANWEI SU N GEN?

Vorbereitete Anweisungen erhöhen dramatisch die Sicherheit von SQL zur Speiche­

rung von Daten, die der Benutzer eingibt. Sie bi lden eine hervorragende Möglichkeit,

um SQL-Injektionsangriffe zu verhindern, und sollten viel häufiger eingesetzt werden,

als es der Fall ist.

Nehmen wir an, Sie möchten einen Datensatz in die Tabelleuser _preferences ein­

fügen, die über die Felder l ocati on, co l o r und song verfügt. Das könnten Sie wie

folgt tun:

" SELECT * FROM user _p r eferences WH ERE name = "+aN ame

SQL-Anweisungen auf diese Weise zusammenzubauen ist jedoch schlecht. Es kann

nicht oft genug betont werden, wie schlecht das ist, denn dadurch öffnen Sie die

gesamte Datenbank für sogenannte SQL-Injektionsangriffe. Stückeln Sie SQL-Anwei­

sungen nicht zusammen!

Die sichere Vorgehensweise besteht darin, einen SQL-String wie den folgenden zu er­

stellen:

" SELECT * FROM user_pr eferences WH ERE name = ? "

Dazu erstellen Sie ein Array mit den Werten, die anstelle der Fragezeichen verwendet werden sollen. Die Aufrufe von set Da ta und get Da ta kümmern sich um den Rest, da

sie eine vorbereitete Anweisung verwenden.

Bei der Verwendung einer vorbereiteten Anweisung wird der SQL-Code ana lysiert,

bevor die Fragezeichen durch die Werte ersetzt werden. Falls also in irgendeiner der

Variablen schädlicher SQL-Code entha lten ist, wird er also gar nicht erst ana lysiert. Für

die Datenbank sieht es so aus, als enthalte die SQL-Anweisung einen merkwürdigen

String. Ein Aufruf mit Fragezeichen wie der vorstehende gibt keine Ergebnisse zurück,

der zusammengestellte dagegen kann alles mögliche aus einer Tabelle zurückgeben, l was der Hacker sehen möchte.

156

Page 158: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Nat ive SQlite-Datenbanken verwenden

Vorbereitete Anweisungen schützen Datenbanken vor Eindringversuchen über SQL-Injek­

tionsangriffe. Es mag zwar unsinnig erscheinen, diese kleine Datenbank gegen Eindring­

linge zu schützen, aber das ist es nicht. Es gibt immer die Möglichkeit, dass j emand, der

keinen Zugriff auf ein Gerät oder den darauf ausgeführten Code haben soll, dort Schaden

anrichtet. Datenverarbeitung sollte stets auf sichere Weise erfolgen.

Auch das Entfernen von Daten aus der Datenbank läuft nach diesem Muster ab. Da hier­

bei die Datenbank geändert wird, muss die Methode setDa ta verwendet werden. Aus

Sicherheitsgründen wird auch hier eine vorbereitete Anweisung verwendet, da der Benut­

zer einen Namen angibt, der entfernt werden soll.

function del eteScoreBC F( pa r ameters ){ var name = document .getEl ementByld( ' nameFi el d').value; var StatementParameters = [ bl ogName ] ; database . setData( ' OELETE FROM score where name = ? ',

statementParameters);

6.3 ABSCHNITT 3: NATIVE SQLITE-DATENBANKEN VERWENDEN

Sie können Datenbanken nicht nur in derWebKit-Engine erstellen und verwenden, die sich in jeder i Phone-Web-App finden lässt, sondern auch native Datenbanken einsetzen. Da bei

kann der Entwickler bereits vorhandene Daten in die insta llierte Anwendung aufnehmen.

Nehmen w ir an, Sie schreiben eine Anwendung, die Benutzern helfen soll, Waren in einem Großmarkt zu finden, und möchten darin eine Reihe von GPS-St andardorten auf nehmen.

Anstatt die Daten beim Start der Anwendung herunterzuladen und zu speichern, können

Sie sie in einer SQLite-Datenbankdatei in die Insta llation der Anwendung auf nehmen.

Die Beispielanwendung nat i veDBAccess hat die gleiche Funktion wie BrowserDBAc ­

cess, verwendet aber die SQLite-Datenbank sample.sqlite. Abbi ldung 6.3 zeigt diese Datei

in der Gruppe RESOU RCES im Xcode-Proj ekt.

Der JavaScript-Code zum Erstellen eines Da taAces s Obj ect, das als Wrapperfür den Aufruf

einer nativen Datenbank f ungiert, unterscheidet sich von dem fü r die WebKit-Datenbank aus Abschn itt 2. Wie bei der WebKit-Datenbank erfolgt die Definition in der Datei datbase­Definitionjs. Bei nativen Datenbanken ist jedoch nur der Name der Datenbankdatei erfor­

derlich, während die Parameter fürVersion und Größe überflüssig sind, da die Größe nativer

Datenbanken unbeschränkt ist (innerhalb sinnvoller Grenzen) und die Versionssteuerung

bei der Erstel lung und Verteilung durch den Besitzer der Anwendung erfolgt.

var sampl eData base = new Da ta Ac cessObject ( "sampl e . sq l ite") ;

157

Page 159: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Beachten Sie, dass es keinen Aufruf zum Erstellen einer Tabelle gibt, da die Tabelle sco r e

bereits in der Datei sample.sqlite vorhanden ist. Es ist zwar möglich, in nativen Datenbanken

Tabellen zu erstellen, aber dies ist eher unüblich. Die Tabellen werden der Datenbankdatei

gewöhnlich hinzugefügt, bevor die Anwendung in den App Store von Apple eingestellt w ird.

Q()f) !::J nativeDBAccess C)

I (Project Setting) I Debug · I ~ ~. ~ (Q.. Strlng Matehing ) OvOIView Action Bulld Bulld and Go Tasks Info Surch

Groups & Flies 111'1 jflle Name • I o<;. jCode I 0 I A t G I ,. rl:J natlveDBAccus ~ [j sample.sqllte Ii!

,.CJo;mes . ,.. CJ Other Sources

• CJ Resources ijJ databoseDeftnltlonJ > .i!J functlon>.J> ~ lndex.html i!J mai n.js

~ mapplng>.J> sample.sqllte

,.CJ MapView ,.. CJ QCIPhone

,. CJ Pms ,.CJ images

lfiJ MainWindow.)(i b

~ lnfo.pllst Dashcode to Xcode.o

,.. D Framewerks ,.. CJ Products

[D d lst.pllst ,.@>Targets

1> 0 El<ecutables • l!t Errors and Warnings

"' Q, Flnd Results

~1 l> lJ!]Bookmarks

~> § SCM -,.. Abbildung 63: Die Ressourcen für die Beispielanwendung nativ eDBAcce s s

Der Abruf von Daten aus einer nativen Datenbank erfolgt fast genauso w ie bei einer

Datenbank, die von der WebKit-Engine verwa ltet wird. Den einzigen Unterschied sehen

Sie im folgenden Code: Anstelle der Methode getData verwenden Sie getNat i veDa ta.

Für den Ersteller der Anwendung verhalten sich die beiden Methoden identisch.

function getScoresBC F(parameters ){ debug( ' gett ing scores from database' ) ; var SOL= ' SELECT * FROM score '; sampl eDatabase.getNativeData(SQ L) ;

Ebenso w ie die in Abschnitt 2 behandelte Methode getData ist auch getNat i veData

asynchron. Wenn die erfassten Daten verfügbar sind, übergibt das Framewerk sie daher

an andere Steuerobjekte, die demselben Befehl zugeordnet sind wie die BCF. Wie beim

WebKit-Beispiel ist dies die VCF d i s p l aySco res VC F.

158

Page 160: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das DataAccessObject in Datenbanken der WebKit-Engine verwenden

ln Abbildung 6-4 sehen Sie die Anzeige, die diese VCF in der Beispielanwendung na t ive ­

DBAccess hervorruft.

Das Hinzufügen und Entfernen von Daten sowie Änderungen an der Datenbank erfolgen

genauso wie in Abschnitt 2, wobei nur die Methode setNati veData anstelle von set ­

Da ta verwendet wird. Wenn Sie eine Anwendung erstellen, sollten Sie keine Unterschiede

im Verha lten sehen.

Nadre Datab ase Name: sampl<.sqllt<

SQL: SELECT • FROM score

( fuCIIIe011(1'-, )

pla~·tr_namt scort bob 100

100()

jo:oc SOO

iqW' $50()

Tbis sltould really du some aclual work!

~ Abbildung 6.4: Die Beispielanwendung na t i veDBAccess

nach dem Antippen der Schaltj/äche OPEN DATABASE AND

EXECUTE QUERY

6.4 ABSCHNITT 4: DAS DATAÄCCESSÜBJECT IN DATENBANKEN

DER WEBKIT-ENGINE VERWENDEN

ln den bisherigen Abschnitten haben Sie gesehen, wie Sie das DataAccessObject ver­

wenden, um sich nicht mit allen Einzelheiten der SQLite-lmplementierungen in der Web­

Kit-Engine und in nativen Datenbanken beschäftigen zu müssen. ln diesem Abschnitt

erfahren Sie, was fü r Einzelheiten das sind und wie Sie sie nutzen. Wenn Sie einfach nur

Da t aAccessObject verwenden möchten, aber nicht das Bedürfnis haben zu erfahren,

wie es funktioniert, können Sie diesen Abschnitt überspringen.

Die Kl asse DataAcessObject in der Datei QCiPhone!DataAccessObjectjs ist dazu da,

dass der Programmierer oder Entwickler so wen ig von SQLite verstehen muss wie mög­

lich. Daher wurde diese Klasse so entworfen, dass ihre Methoden und Konstruktaren so

sehr dem AJAX-Wrapper Se rverAccessObj ect ähneln wie möglich, der in Kapitel7, »Da-

159

Page 161: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

tenzugriff über das Netzwerk«, behandelt wird. Durch die Vereinfachung der API können

Programmierer, die mit SQLite nicht vert raut sind, Daten speichern, ohne erst viel Neues

lernen zu müssen.

ANONYME FUN KTIONEN

Wenn eine Person anonym ist, heißt das, dass Sie ihren Namen nicht kennen. Ist eine

Funktion anonym, so hat sie keinen Namen. ln JavaScript wird der Name einer norma­

len Funktion in einer Zeile w ie der folgenden deklariert:

f unc t ion bark(){ }

Der Name der Funktion lautet hier bark. Muss einer Funktion eine andere übergeben

werden, so wird häufig eine Funktion ohne deklarierten Namen verwendet, also eine

anonyme Funktion.

Die Übergabe einer anonymen Funktion an bark sieht wie folgt aus:

bark (new funct ion() { II Hi er tu t di e Fun kt i on irgendet was

} ) ;

Beachten Sie, dass der Bereichsoperator für die anonyme Funktion, I } , in den Parame­teroperatoren der Funktion ba r k, ( ) , eingesch lossen ist. Die Funktion ba r k kann diese

Funktion jetzt nach Bedarf aufrufen und speichern.

Alle anonymen Funktionen haben Zugriff auf lokale Variablen, die der Funktion, in der

sie deklariert sind, übergeben werden können. Daher ist der folgende Code gültig:

St ring type= ' doberman ' : bark (new f unct ion() {

if(type == ' boxer ' ){

} ) ;

}

el se if(type == ' doberman ' ){ }

Diese Besonderheit ist praktisch, wenn Funktionen oder Methoden andere Funktionen als

Parameter verwenden, wie Sie weiter hinten in diesem Abschnitt noch sehen werden.

Wie jedes andere wertvolle Werkzeug sollten Sie auch anonyme Funktionen nicht

übermäßig einsetzen, also nicht dort, wo sie gar nicht nötig sind.

160

Page 162: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das DataAccessObject in Datenbanken der WebKit-Engine verwenden

Der Konstruktor von Da taAcces sübj ect ist die einfachste Methode dieser Klasse. er soll

die Methoden des Objekts festlegen und als anonyme Funktionen definieren. Es werden also

keine Attribute gebraucht, um die dem Konstruktor übergebenen Parameter zu speichern.

Wie Sie in Tabelle 6.1 und in den Abschnitten 2 und 3 gesehen haben, verfügt Da taAc ­

cessübject über zwei Gruppen von Methoden. Die eine handhabt Daten, die in einer

WebKit-Datenbank gespeichert oder von dort abgerufen werden, die andere kümmert

sich um die Datenübertragung zwischen der JavaScript-Anwendung und einer in der ver­

teilten Anwendung enthaltenen SQLite-Datenbankdatei. Die WebKit-Methoden weisen

den umfangsreichsten JavaScript-Code auf und werden als Erste aufgeführt.

Sowohl getData als auch setData sind nur Fassade. Diese Methoden führen nur sehr

wenig Berechnungsarbeit durch und greifen für die Hauptarbeit auf eine dritte Methode zurück. Die einzigen Berechnungen, die in diesen beiden Methoden stattfinden, betreffen

die Zusammenstellung der Werte, die in derVariablenpass Th rough Parameters gespei­

chert werden (siehe den folgenden Code).

t hi s .getData = funct i on(SQL, preparedStatementParameters) { var passThroughParameters =

generatePassThroug hParamet ers(); this.dbAccess(SQ L, preparedStatementParameters.

fa l se , passThroughParameters) ;

Da das für die HTML s-Spezifikation verantwortliche Standardisierungsgremium W3C

verlangt, dass alle Aufrufe der Datenbankfunktionen der WebKit-Engine asynchron sind,

müssen zusammen mit den Anforderungen auch Informationen über den aktuellen

Status der Anwendung für den späteren Gebrauch übergeben werden. Die Funktion ge ­

ne ratePass Th rough Parameters aus QCUtilitiesjs erfasst die benötigen Werte.

Wie der folgende Code zeigt, gehören dazu der Befehl, für den Befehlsobjekte aufgerufen

werden, die Anzah l der bereits aufgerufenen BCOs, die an alle Steuerfunktionen überge­benen Parameter, z.B. globa l Pa ramAr ray, und ein Array mit den durch Aufrufe an ande­

re BCFs hervorgerufenen Ergebnissen, z.B. global BCFResul ts.

function generatePassThroughParameters(){ var passThroughParameters = new Array(); passThroughParameters.pus h(window . curCmd ) ; passThroughParameters.pus h(window.numFuncsCalled ) ; passThroughParameters.pus h(gl obalParamArray); passThroughParameters.pus h(window.globalBCFResul ts ) ; return passThroughParamet ers;

161

Page 163: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Diese Werte werden später vom Framewerk verwendet, um sicherzustellen, dass übrig ge­

bliebene Steuerfunktionen auf der Grundlage der in mappingsjs für den curCmd-Befehl

defin ierten Zuordnungen so ausgeführt werden, als wären alle Aufrufe von Befehlsfunk­

tionen synchron erfolgt. Weitere Erläuterungen dazu erhalten Sie in Kapitel 2.

Das resu ltierende Array pas sTh roughParameters wird zusammen mit einem Flag an

die Methode d bAcces s übergeben, wobei das Flag anzeigt, ob der SQL-Code in der Varia­

blen SOL als Versuch zur Änderung der Daten in der Datenbank behandelt werden soll.ln

der Methode getData wird, wie wir bereits gesehen haben, fa l se übergeben.

Die Methode dbAccess ist das Herzstück der Klasse DataAccessObject für WebKit­

Datenbanken. Sie erledigt die gesamte Arbeit, wenn getDa t a oder setData aufgerufen

werden.

Um die Methode dbAcces s verstehen zu können, müssen wir zunächst mit der zugrunde

liegenden JavaScript -API f ür SQLite vertraut werden. Diese API ist im kommenden Stan­

dard HTML 5 enthalten und wird durch die Verwendung derWebKit-Engine in U IWebVi ew implementiert. Dies findet sich in allen iPhone-Web-Apps und in Mobile Safari wieder.

Die j üngste Version dieses Standards (zur Zeit der Drucklegung) fi nden Sie unter http:! I dev.w3.orglhtmlsfwebdatabase!. Dieses Dokument beschreibt verschiedene Obj ekte und

Objektmethoden, wie die folgenden Tabel len zeigen.

Das grundlegende Element der API ist das Database-Objekt. Tabelle 6.2 beschreibt eine

Funktion, die mit diesem Obj ekt in Zusammenhang steht, und eine seiner Methoden.

Bei openData ba se handelt es sich um eine Factory-Funktion, die ein Da tabase-Objekt

instanzi iert .

Attribut/Methode Rückgabewert Beschreibung Parameter

openData - Da ta ba se- Eine Factory- dbName- Ein String, der base(dbName, Obj ekt Funktion, die die Datenbank eindeutig dbVersion, ein Da tabase- bezeichnet dbDescr ipt ion, Objekt für die

dbVers ion- Ein String, dbSi ze) spätere Verwen-

der gewöhnlich die Form dungerstel lt

einer Fließkommazahl

aufweist

162

Page 164: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das DataAccessObject in Datenbanken der WebKit-Engine verwenden

{Fortsetzung) dbDes cr i pt i on- Ein

String, der den Zweck der

Datenbank angibt

dbSi ze - Der Mindest-

betrag an Festplattenplatz

in Byte, der der Datenbank

zugewiesen wird. Wird

NULLoder gar nichts

übergeben, beträgt der

St andardwert s MByte.

tran sact ion ( exe- SO LTransa c- Eine Methode, execut ionCal l bac k -cuti onCa l l ba ck , t i on-Objekt die ein SO L- Eine Funktion mit erforder-

er ro rCa l l back, Transa cti on- lichem Code zum Ausfüh-successCal l ba ck ) Obj ekt für Ak- rung des SQL-Befehls

tua I isieru ngen er r or Ca ll back- Eine op-

und Abf ragen t ionale Funktion, die beim

von Datenban-Fehlschlagen der Transakti-

ken erstellt on aufgerufen w ird. in die-

ser Methode werden keine

Rollbacks der Datenbank

durchgef ührt, da bei einem

Fehler automatisch ein

Rollback erfolgt.

successCa l l ba ck - Eine

optiona le Funktion, die

beim erfolgreichen Ab-

schlussder Transakt ion

aufgerufen wird.

Tabelle 6.2:AP/jür Da t a ba se-Objekte

Nach dem Dokument fü r den Standard sind alle Parameter von openData base optiona l,

doch ist es unklug, keinen Datenbanknamen zu deklarieren. Wenn Sie in versch iedenen

Anwendungen mehrere Datenbanken einsetzen, sollte jede davon einen eindeutigen

Namen tragen. Den Parameter dbName nicht anzugeben, kann dazu führen, dass alle Ihre

Anwendungen dieselbe Datenbank verwenden - die dann auch schädlichen Anwendun-

163

Page 165: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

genvon anderen Autoren zur Verfügung stehen kann. Um Ihre Datenbanken zu schützen,

wird etwas Ähnliches verwendet wie die Regel vom identischen Ursprung, die AJAX-Aufrufe

in Browsern einschränkt.

Die Schutzregel für Datenbanken ist eine Einschränkung, die verlangt, dasseine Datenbank

nur für Anwendungen mit demselben Ursprung zugänglich ist. Wenn eine Webanwen­

dung von www. i hre_seite. de bedient wird und eine andere von web. i hre_ seite.

de, so wären die Datenbanken in diesen Anwendungen jeweils von beiden Anwendungen

aus zugänglich. Mit anderen Worten, alles, was von i hre_ sei te. de bedient wird, kann

auf alle Datenbanken mit diesem Ursprung zugreifen, und zwar unabhängig davon, ob die

Datenbank von der laufenden Anwendung erstellt wurde oder von einer Anwendung, die

von einer anderen Unterdomäne von i h re_sei te. de angelegt wurde.

Bei Web-Apps verwenden Sie ein U I WebV i ew-Objekt statt eines Webbrowsers, weshalb es

keine Regel des identischen Ursprungs zur Einschränkung von AJAX gibt. Es ist zurzeit noch

nicht geklärt, aber kann angenommen werden, dass auch die Ursprungsbeschränkung für

Datenbanken unwirksam ist. Der einzige Schutz Ihrer Datenbanken vor dem Zugriff durch

andere Anwendungen besteht daher möglicherweise darin, dass die Autoren dieser ande­

ren Anwendungen den Namen und die Version Ihrer Datenbank nicht kennen. Achten Sie

daher darauf, Ihren Datenbanken einen Namen und eine Versionsnummer zu geben.

Die Methodetransaction wird von allen SQL-Aufrufen verwendet. Tatsächlich gibt es

keine Möglichkeit, SQL-Code in einerWebKit-Datenbank auszuführen, als die Verwendung

eines von transactionerstellten SO L Transact i on-Objekts. Daher sind alle JavaScript­

Datenbankaufrufe in iPhone-Web-Apps automatisch transaktionssicher.

Häufig beunruhigt Entwickler die Frage, wann ein Rollback in der Datenbank erfolgen soll.

Gewöhnlich ist dies der Fall, wenn der vom Programmierer geschriebene Code feststellt,

dass eine Transaktion auf irgendeine Weise feh lgeschlagen ist. Wenn Sie die JavaScript­

Datenbankfunktionen verwenden, müssen Sie sich um Rollbacks nicht kümmern, da

Transaktionen bei einem Feh lschlag automatisch einen Rollback durchführen.

Senden Sie nicht die SQL-Anweisu ng ROLL BACK, wenneine Transaktionfeh lsch lägt, dennfür

den Rollback ist bereits gesorgt, sodass durch eine solche Maßnahme nur Probleme verur­

sacht werden. Die an die Methodetransaction übergebene Fehlercallback-Funktion wird

nicht für diesen Zweck verwendet, sondern nur zur Benachrichtigung über Feh lsch läge.

DasSOLTrans a ct i on-Obj ekt hat nur eine Methode, nämlich exec uteSO L (siehe Tabe lle

6.3). Diese Methode nimmt jeden SQL-Befehl entgegen, den Sie ihr senden. Es ist jedoch

unklug, eine SQL-Anweisung zusammenzustellen und dann auszuführen. Stattdessen

sollten Sie vorbereitete Anweisungen nutzen. Wenn Sie nicht wissen, was das ist und wie

Sie sie einsetzen, schlagen Sie in Abschnitt 2 nach.

164

Page 166: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

6.4 I Das DataAccessObject in Datenbanken der WebKit-Englne verwenden

Attribut/Methode Rückgabewert Beschreibung Parameter

executeSQL(sqlState - Void Eine Metho- sql Statement - Ein ment . arguments , de, die jeden String, der eine gültige successCallback , beliebigen SQL-Anweisung ent-errorCallback) String einer hält. Er kann ?-Sym-

SQL-Anweisung boleals Platzhalter

ausführt enthalten, wenn er als

vorbereitete Anwei-

sung behandelt wi rd.

ar gument s -Ein

optiona les Array der

Werte, die die ? -Plat z-

halter in vorbereiteten

Anweisungen ersetzen.

successCal lback -Eine opt iona le Funk-

tion, die bei erfolg-

reicher Ausführung

der SQL-Anweisung

aufgerufen wird.

errorCallback -

Eineoptionale Funk-

tion, die aufgerufen

w ird, wenn die Aus-

führungder SQL-An-

weisung fehlsch lägt.

Tabelle 6-3: API eines SOL Tra ns a ct i on-Objekts

Neben der SQL-Anweisung w ird ein optionaler Parameter mit Argument en übergeben,

nämlich ein Array aus Strings, durch die j egl iche in der SQL-Anweisung vorhandenen

Fragezeichen ersetzt werden sollen. Dabei handelt es sich um die Va riablen in einer vor­

bereiteten Anweisung, die durch einen Aufrufvon executeSQ L erstellt w urde. Ein Aufruf

dieser Methode legt stets eine vorbereitete Anweisung an, selbst wenn es keine Platz­

halter gibt. Wenn Sie vorbereitete Anweisungen verwenden, gewinnen Sie Sicherheit. Wenn nicht, geht es auch nicht schneller.

165

Page 167: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Die letzten beiden Parameter sind Callback-Funktionen, die ausgeführt werden, wenn die

Anweisung- nicht die Transaktion!- feh lschlägt oder erfolgreich ausgeführt wird. Der

Erfolgsfunktion übergibt die Methode executeSOL ein SO LResu l tSet-Objekt. Die API

dieses Objekts sehen Sie in Tabelle 6-4. Der Fehlerfunktion dagegen wird ein SO LE rror­

Objekt übergeben (mit der API aus Tabelle 6.6). Um das Ergebnis der Ausführung der SQL­

Anweisung handhaben zu können, müssen Sie diese Funktionen implementieren und in

den Aufruf der Methode executeSO L einschließen.

Attribut / Methode Rückgabewert Beschreibung Parameter

insertiD Keiner Ein schreibgeschütztes Integer- Keine

attribut, das die ID eines eingefügten Datensatzes enthält, falls das ID-Feld

automatisch inkrementiert wird

rowsAffected Keiner Ein schreibgeschütztes Integer- Keiner

attributmit der Anzahl der Zei len, die

durch eine Aktual isierungsanweisung

hinzugefügt oder geändert werden

rows Keiner Ein SO LRes ul tSetRowL i st -Attribut Keiner

mit allen resultierenden Zei len einer

Abfrageanweisung

Tabelle 6.4: API eines SO LRes u 1 tSet-Objekts

Das SO LResul tSet -Obj ekt enthält die Informationen, die Sie mithilfe der SQL-Anwei­

sung abgefragt haben, sowie zwei zusätzliche prakt ische Elemente, nämlich die Attribute

i nsert i D und rowsAffected.

Wenn Sie einen Datensatz in eine Tabelle mit einem automatisch inkrement ierten Primär­

schlüssel einfügen, enthält dasAttributins e rt I 0 des SO LRes u l tSet-Objekts den auto­

matisch generierten Schlüsselwert. Das ist praktisch, wenn Sie den Sch lüssel brauchen,

um damit verknüpfte Daten in andere Tabellen einzufügen.

Nach einer erfolgreichen Einfüge- oder Aktualisierungsanweisung enthält das Attribut

rowsAffected die Anzahl der eingefügten oder geänderten Zeilen. Dies kann zur Über­

prüfung des Verhaltens komplexer SQL-Anweisungen verwendet werden.

Das dritte Attribut von SO LResu ltSet ist rows. Es enthält SO LResultSet RowL i st, einen

Wrapper fü r den Zugriff auf ein Array aus Datensätzen. Wie Sie in Tabelle 6.5 sehen, hat die­

ses Obj ekt das Attribut l ength, das die Anzahl der Datensätze im Ergebnis einer SELECT­

Anweisung enthält. Diese Zah l entspricht der Anzahl der Zeilen im eingebetteten Array.

166

Page 168: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das DataAccessObject in Datenbanken der WebKit-Engine verwenden

Attribut / Methode Rückgabewert Beschreibung Parameter

length Keiner Ein schreibgeschütztes Integer- Keine attributmit der Anzahl der Da-

tensätze, die durch eine Abfrage-

anweisungabgerufen wurden

item( i ndex) Array Eine Methode, die einen Daten- index-Die

satzals assoziatives JavaScript- Nummer des

Array oder als Map zurückgibt Datensatzes im

Resultset, der

zurückgegeben

werden soll

Tabelle 6.5: API eines SO LRes u 1 tSetRowL i s t-Objekts

Das Objekt hat auch die Methode i t em f ür den Zugriff auf einzelne Ergebniszeilen. Mit

dieser Methode und dem Attribut können Sie in eingebetteten tor-Schleifen sehr leicht

durch die Zeilen und Werte iterieren. Die Standardvergehensweise dafür sehen Sie in dem

folgenden Code:

1 for ( var i = 0: i < aResul t Set .l eng t h; i ++){ 2 var aRow = aResul tSet. i t em(i); 3 for( key i n aRow){ 4 var aVal ue = aRow[key ]; 5 //H ier wird etwas mi t dem Schl üssel und dem Wer t get an 6 7

Den Code dieser fo r -Schleife würden zwar viele als Standardvergehensweise betrachten,

doch wird er nicht optimal ausgeführt, da in Zeile 1 die Länge des Resultsets jedes Mal

abgerufen w ird, wenn der Code die äußere Schleife durchläuft. Verschwendung zeigt sich

auch in der w iederholten Verwendung der fo r - ea eh-Sch leife in Zeile 3-

for - eac h-Schleifen in JavaScript sind vor allem verschwenderisch, was CPU-Zyklen an­

geht, vor allem aber, wenn sie in anderen Sch leifen auftreten. Weiter hinten in diesem

Abschnitt erfahren Sie bei der Erläuterung der Methode dbAccess, wie Sie diesen Code

so ändern können, dass er besser ausgeführt wird.

Tritt bei der Ausführung der SQL-Anweisung irgendeine Art von Feh ler auf- z.B. aufgrund

eines Fehlers in der Anweisung-, w ird statt eines SQLResul tSet- ein SQ LE rror-Objekt

erstellt. So w ie das SQLResul tSet-Objekt der Erfolgsmethode übergeben wi rd, die als

Parameter der Methode executeSQ L für die Anweisung angegeben ist, so geht das

SQLError-Objekt an die Fehlerfunkt ion.

167

Page 169: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Der Erfolgsfunktion wi rd niemals ein SQLError-Objekt übergeben und der Fehlerfunk­

tion niemals ein SQLResul tSet. Beide Funktionen dienen jeweils nur einem einzigen

Zweck, sodass sie einfacher zu schreiben und zu warten sind.

Das SQ LError-Objekt enthält zwei Attribute fü r die Fehlercodenummer und die von

SQLite generierte Fehlermeldung (siehe Tabelle 6.6).

Attribut/ Methode Rückgabewert Beschreibung Parameter

code Keiner Ein schreibgeschütztes Attribut mit der Feh- Keine

lernummer. Folgende Werte sind möglich:

o- Die Transaktion sch lug aus unbekannten

Gründen fehl.

1-Die Anweisung schlug aus unbekannten

Gründen fehl.

2- Die Anweisung schlug fehl, da die erwar-

tete Version der Datenbank nicht mit der

tatsächlichen übereinstimmt.

3- Die Anweisung schlug fehl, da zu viele

Daten zurückgegeben wurden. Versuchen Sie

den SQL-Modifizierer LI MI T zu verwenden.

4 - Die Anweisung sch lug fehl, da das Spei-

cherlimit erreicht w urde und der Benutzer

der Erhöhung des Grenzwerts nicht zuge-

stimmt hat.

5- Die Anweisung schlug aufgrundeines

Sperrenfehlers in der Tra nsaktion feh l.

6- Eine I NSERT-, UPDATE- oder REP LA CE-An-

weisungschlug fehl, da sie eine Einschränkung

verletzt hat (z.B. durch Duplizierung eines ein-

deutigen Schlüssels).

message Keiner Ein schreibgeschütztes Attribut mit der ent- Keine

sprechenden Fehlermeldung

Tabelle 6.6: API eines SOLE r ro r -Objekts

168

Page 170: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Das DataAccessObject in Datenbanken der WebKit-Engine verwenden

Die beiden Elemente code undmessagesind f ür Programmierer und Entwickler zwar

hilfreich, sollten dem Benutzer aber nicht angezeigt werden, der damit ohnehin nichts

anfangen kann. Verwenden Sie diese Indikatoren, um den Feh ler aufzuzeichnen und dem

Benutzer eine hilf reiche Meldung anzuzeigen.

Beispiele dafür, wie diese Objekte verwendet werden, finden Sie in der Methode dbAccess

von DataAccessObj ect.Wie in diesem Abschnitt bereits erwähnt, hat diese Methode fünf

Parameter und erledigt die eigentliche Arbeit hinter der Fassade der beiden Methoden get ­

Data und setDa ta. Der vierte Parameter gibt an, ob der Zugriff angefordert wird, um die

Datenbank zu ändern oder sie abzufragen. Dieser Parameter wird von der Fassadenfunktion

festgelegt, die dbAccess aufruft.

Bei der Untersuchung der Methode dbAccess stoßen Sie auf mehrere anonyme Funktio­

nen. Die erste wird in Zeile 5 als erster und einziger Parameter an die Methode transac ­

t i on der Datenbank übergeben. Es mag einfacher erscheinen, diesi rgendwoanders im

Code als reguläre Funktion zu defin ieren und als ersten Pa ra meter zu übergeben, aber das

würde den restlichen Code problematisch, wenn nicht sogar unmöglich machen- Varia­blen, die sich im Gült igkeitsbereich befinden, wei l sie anonyme Funktionen verwenden,

wären dann nämlich nicht mehr im Gültigkeitsbereich. ln Zeile 2 des nachfolgend gezeig­

ten Codes wird das Oue ryRes u l t -Objekt instanzi iert, das als Rückgabewert der Methode

dbAccess dient.

Damit ein OueryRes ul t -Obj ekt wirklich nützlich sein kann, muss es innerhalb der Funk­

tion exec uteSql der Transaktion verfügbar sein. Außer der Verwendung anonymer Funk­

tionen besteht die einzige Möglichkeit hierf ür darin, es global zu machen.

Bei globalem Gültigkeitsbereich wäre j edoch immer nur ein Datenbankzugriff auf einmal

möglich. Da aber der gesamte Datenbankzugriff asynchron erfolgt, kann dies unmögl ich

garantiert werden. Der beste Ansatz besteht also darin, anonyme Funktionen zu verwen­

den. Diese Logik gilt auch fü r die Funktionen, die an die Methode executeSq l der Trans­

aktionselbst übergeben werden.

Der Methode executeSql des Transaction-Objekts können zwei Funkt ionen als

Parameter übergeben werden. Es ist eine bewährte Vorgehensweise, dies stets zu tun. Die

zweite Funktion, die Sie in Tabelle 6.3 als dritten Parameter sehen, ist die Funktion, die das

Ergebnis der Abfrage handhaben soll, wenn al les gut geht. Die Deklarat ion dieser Funk­

tion beginnt in Zei le 10 des folgenden Codes.

in der Erfolgsfunktion wird eine vom SQL-Code generierte ID für einen eingefügten

Datensatz in dem OueryResul t -Obj ekt gespeichert, das in Zeile 7 instanzi iert wird.

Wurden Zeilen in der Datenbank geändert, so wird auch die Anzahl der betroffenen Zeilen

bestimmt. Dies geschieht jedoch nur, wenn der Parameter t rea t AsCha ngeData der

Methode dbAccess auf t rue gesetzt it.

169

Page 171: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Wurden keine Daten geändert, so folgt daraus, dass eine Abfrage ausgeführt wurde. Die­ser Fall wird in den Zeilen 23 bis 51 behandelt. Hier wird ein zweidimensionales JavaScript­Array erstellt und an den QueryResul t -Rückgabewert angehängt. Es speichert al le Daten, die im SOLRes u l tSet gefunden wurden. Durch die Übertragung der Daten an ein JavaScript-Standardarray kön nen Sie im restlichen Code auf die Daten zugreifen, ohne die Struktur des SQLResul tSet-Objekts oder die von der Abfrage zurückgegebenen Felder kennen zu müssen. Für den Fall, dass Sie die Namen der Felder doch brauchen, werden sie für den späteren Gebrauch im Que ryRes u l t-Objekt gespeichert. Die Feldnamen und die Feldwerte bleiben in derselben Reihenfolgewie im SQLResul tSet-Objekt.

1 this.dbAccess = function(SQ L, preparedStatementParameters. 2 treatAsChangeData, passThroughParameters){ 3 if ( !this.db) { 4 this.db = openDatabase (dbName. dbVersion. 5 dbDescription. dbSize); 6 7 var queryResul t = new QueryResul t ( ); 8 this .db.transaction ( function(tx ) { 9 tx .executeSql CSO L. preparedStatementParameters.

10 function (tx. resu l tSet) { 11 if(treatAsChangeData ){ 12 try{ 13 queryResul t . insertediD = resul tSet . insertld; 14 queryResul t . rowsAffected =

15 resu l tSet. rowsAffected; 16 17 18 19 20 21 22 23 24

25 26 27 28 29 30

170

catch(ex ){

el se{

II Es muss sich um eine Aktual isierung handel n queryResul t . rowsAffected =

resu l tSet.rowsAffected;

II Die Datenbank wurde nicht geändert . II Es muss sich um eine Abfrage handel n. queryResul t.numRows Fetched =

resul tSet . rows . l ength; var dataArray = new Array () ; queryResul t.numResul tFie l ds = 0; queryResul t.fiel dNames = new Array () ;

Page 172: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

Das DataAccessObject in Datenbanken der WebKit-Engine verwenden

i f (queryResul t.numRowsFetched > 0){ II Fel d-IDs aus dem Resu l tset abrufen var firstRecord = resu l tSet . rows . item(O); var numFi elds = 0; for(key in f irstRecord){

queryRes ult.fiel dNames.push(key); numFiel ds++;

queryResul t.numResultFie l ds = numFiel ds ; var numRecords =

queryRes ult .numRows Fetched; for(var i = 0; i < numRecords; i++ ){

var record = resu l tSet.rows.i tem(i); var row = new Array(); dataArray. push(row); for(var j = 0 ; j < numFie l ds; j ++){

row . push( record [queryResul t.fieldNames [ j] ] ) ;

queryResul t.data = dataArray;

if(window.cal 1Func){ var theResul ts = new Array() ; theResul ts.pus h(queryResul t ) ; theResul ts.pus h(passThroughParameters); requestHand l er(passThroughParameters[OJ.

54 55 56 57 58 59 60

passThroug hParameters[2 ], theResults);

61 }II Ende der Erfo l gs -Ca l l backfunkt ion zur SOL -Ausführung 62 . function(tx. error) { 63 queryResul t.errorMessage = error.message; 64 i f(window.ca l l Func){

var theResul ts = new Array() ; theResul ts.pus h(queryResul t ) ; theResul ts.pus h(passThroughParameters); requestHand l er(passThroughParameters [OJ .

65 66 67 68 69 passThroug hParameters[2 ], theResults ) ;

171

Page 173: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

70 } 71 II Ende der Haupt feh l erfunktion der SOL- Ausführung 72 ); II Ende des Haupt aufrufs von executeSq l 73 }); II Ende der Transakt ions-Ca l l backfunkt ion 74 II Ende der Methode dbAccess

Unabhängig davon, ob die ausgeführte SQL-Anweisung die Datenbank ändert oder ab­

fragt, wird das zu Beginn des Funktionsaufrufs erstellte Oue r yRes u l t -Objekt vom Frame­

werk an alle restlichen, noch nicht aufgerufenen Funktionen verteilt. Dies geschieht in

den Zeilen 58 und 59 mit der in Kapitel2 vorgestellten Funktion requestHand l er.

Zeile 62 zeigt den Anfang der Deklaration fü r die Fehlerbehandlungsfunktion der Metho­

de des Trans a ct i on-Objekts. Diese Funktion ist dafür zuständig, die von SQLite generier­

te Fehlermeldung in das OueryResul t -Objekt einzufügen und dieses dann an die rest­

lichen Steuerfunkt ionen zu übergeben. Weitere Informat ionen über solche Funkt ionen

erhalten Sie in Kapitel 2.

6.5 ABSCHNITT 5: DATAÄCCESSÜBJECT IN NATIVEN

DATENBANKEN VERWENDEN

Für den Zugriff auf nat ive Datenbanken ist weniger JavaScript -Code erforderlich als f ür

den aufWebKit-Datenbanken. Die meiste Arbeit wird im Objective-C-Teil des Framewerks

erledigt.

Wie die im vorhergehenden Abschnitt beschriebenen Methoden getData und setData

sind auch getNat i veDa ta und setNat i veDa ta nur Fassaden. Jedoch rufen Sie nicht die

Methode dbAcces s von Da taAcces sübj ect auf, sondern die Funkt ion getDev i ceDa ta

aus der Datei comjs.

this . getNativeData = funct ion(SQL , preparedStatementParameters){

getDeviceData(dbName , SO L, preparedStatementParameters);

this . setNativeData = funct ion(SQL , preparedStatementParameters){

setDeviceData(dbName, SO L, preparedStatementParameters);

Die Funktion getDev i ceDa ta besteht aus zwei Hauptfunktionseinheiten. Die erste, die

Sie im folgenden Code in den Zeilen 4 bis 16 sehen, stel lt ein Array aus Informationen

zusammen, die zum Ausführen der Abfrage in Objective-C erforderlich sind. ln diesem Array befinden sich auch die im vorhergehenden Abschnitt besprochenen, durchgereich-

172

Page 174: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

DataAccessObject in nativen Datenbanken verwenden

ten Parameter. Sie sind hier vonnöten, da diese Anforderung ebenso wie die an eine Web­

Kit-Datenbank asynchron erfolgt. Weitere Informationen über asynchrone Datenverarbei­

tung finden Sie in Kapitel 2.

Das Array enthält den Datenbanknamen, den auszuführenden SQL-Code, eventuell von

diesem Code benötigte Parameter für vorbereitete Anweisungen sowie durchgereichte

Paramet er. Informat ionen über vorbereitete Anweisungen finden Sie im vorhergehenden

Abschnitt dieses Kapitels.

1 f uncti on getDev iceData ( dbName. SOL. 2 pr epa r edStatementPa r ameters . call BackParams ){ 3 i f (dbName && SQL ){ 4 va r dataArray = new Array () ; 5 dat aArray .push( dbName ) ; 6 dataArray .push( SQL) ; 7 if ( preparedStatementParameters ){ 8 dataArray .push(preparedStatement Parameters ) ; 9

10 el se{ 11 // I n ei nen Pl atzhal ter ei nfügen 12 dataArray .push( new Array()) ; 13 14 va r ca l l ßa ckParameters = 15 gener atePassThr oughParameter s () ; 16 dataArray .push(cal l ßac kPa r ameters ) ; 17 18 var dataString = JSON.stringify(dataArray) ; 19 makeCal l ( " getData " . dataSt ri ng ) ; 20 21 return nul l : 22

Nachdem die Daten vorbereitet sind, werden sie in einen JSON-String umgewandelt und

an die Funktion ma keCa l l übergeben. Diese Funktion löst den Obj ective-C-Teil des Frame­

werks aus, w ie Sie in Kapitel4, »GPS, Beschleunigungsmessung und andere systemeigene

Funktionen von QuickConnect«, gesehen haben. Dies ist die zweite größere Funkt ionsein­

heit . Ohne sie wäre kein Zugriff auf native Datenbanken mögl ich. Weitere Informationen über JSON finden Sie in Anhang A, »Einf ührung in JSON«.

Wie die Funktionen in Kapitel4 zum Zugriff auf systemeigene Daten werden zum Abrufen

der Daten aus der Datenbank Objective-C-Steuerobjekte gebraucht. Je nachdem, ob die Da­

tenbank verändert oder abgefragt wird, w ird das Objekt SetData BCO bzw. GetDa taBCO ein­

gesetzt. Dies entspricht der Verwendung der JavaScript-Funktionen getData und setData.

173

Page 175: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

+ (id) doCommand:CNSArray*) parameters {

OuickConnectViewController *control l er = COuickConnectViewControll er*) [parameters objectAtlndex:O J :

if( [ parameters count] >= 3){ NSString *dbName = [parameters objectAtlndex:l]: NSString *SOL= [parameters objectAtlndex:2 ] : NSArray *perparedStatementVa l ues = ni l : if( [parameters count ] >= 4){

perparedStatementVa l ues = [parameters objectAt l ndex:3]:

SO LiteDataAccess *aDBAccess = CSOLi teDataAccess*)[controll er.databases

objectForKey:dbNameJ:

if(a DBAccess = ni l ){

aDBAccess = [[SOLiteDataAccess al l oc] in i tWit hDatabase:dbName isWriteabl e: YESJ:

[controll er .databases setObject: aDBAccess forKey:dbNameJ:

return [aDBAccess getData:SQ L with Parameters:perparedStatementVa l ues];

return ni l :

@end

Wie die JavaScript-Funktionen get Data und setData führen auch diese BCOs wenig Be­rechnungsarbeit durch. Im vorstehenden Code ruft die Methode doComma nd den Daten­banknamen, den SQL-Code und eventuelle Parameter für vorbereitete Anweisungen ab, die in der JavaScript-Anforderung übergeben wurden.

Wenn diese Informationen zur Verfügung stehen, wird die Methode getData des SO Li teDataAccess-Objekts aufgerufen. Dieses Objekt entspricht im Großen und Gan­zen einem DataAccessObj ect inJavaScript. Es verfügtebenfalls über Methodennamens s etDa ta und getDa ta, doch die Objective-C-Version ist im Gegensatz zur JavaScript-Ver­sion ein Singleton. Wenn Sie mehr über Singletons wissen wol len, lesen Sie Kapitel4.

174

Page 176: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

DataAccessObject in nativen Datenbanken verwenden

Die Methoden getData und setData von SOLi teDa taAcces s sind wie ihre JavaScript­

Entsprechungen Fassaden f ür die Methode dbAccess. Wie die JavaScript-Methode dbAc ­

cess ist auch die Objective-C-Version ziemlich kompl iziert, was am Umfang der SQLite­

API für die dynamische Bibliothek libsqlite3.o.dylib liegt, die mit jedem iPhone und iPod

tauch ausgeliefert wird. Diese API sehen Sie in Tabelle 6.7.

Objekt/Funktion Rückgabewert Beschreibung Parameter

sq l i te3 Keiner Eine Objektdarstellung Keine

der SQLite-Datenbank im

Arbeitsspeicher

sq l i te3_open SQLI TE_OK Öffnet die Datenbank im fi l ePath - Der ( filePath , bei erfolg- angegebenen Dateipfad vol lständige pfad &a Database ) reichem und speichert den Zeiger zur SQLite-Daten-

Öffnen in aDatabase dateiauf dem Gerät

aDatabase-Eine

Zeigerreferenz

auf einen SQLite3-

Zeiger, der für eine Datenbank im Ar-

beitsspeicher steht

sq l i te3_cl os e voi d Schließt die Verbindun- aDatabase-Ein ( aOatabas e ) gen zur SQLite-Daten- SQLite3-Zeiger, der

bankdatei in der Funktion

sq l i te3_open

gesetzt wird

sq l i te_ er rms g con st Ruft den letzten aDatabase-Ein ( aOatabase ) cha r * generierten Fehler ab SQLite3-Zeiger auf

die Datenbank, von der eine Fehler-

meldung abgeru-

fen werden sol l

sq l i te3_stmt Keiner Eine einzelne vorbe- Keine

reitete SQL-Anweisung

175

Page 177: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

sql i te3_ i nt Interpretiert den aDatabase- Ein

prepare_ v2 SOL ite_OK

SQL-Code SQLite3-Zeiger auf ( aDatabase.

bei Erfolg die Datenbank

SO LCha r. SO LCha r-Ein

- 1, &s t ate-cons t char

ment. NU LU * -Typ der UTF8-

Zeichen, die den

SQL-String bilden

sql i te3_ int Zählt die Felder im statement-Ein

co l umn_count Resultset einer Abfrage sq l ite3_ stmt-(s t atemen t ) Zeiger

sql i te3_ const Ruft den Namen eines statement- Ein co l umn_name char * Feldes ab sq l i t e3_stmt -(s t atemen t . i ) Zeiger

i-Ein Integerfü r

die Feldnummer

sq l i te3_ i nt Ruft die Anzah l der aDatabase- Ein

changes Datensätze ab, auf die SQLite3-Zeiger auf (a Database) sich die Änderung einer die Datenbank

Tabelle auswirkt

sq l i te3_ st eps i nt Verschiebt die Einfüge- statement-Ein (s t atemen t )

SOLITE_ROW marke im Resultset zum sq l i t e3_stmt -

bei verfüg-nächsten Datensatz Zeiger

barer Zeile

sql i te3_ i nt Ruft den Typ eines Feldes statement-Ein

co l umn_type Mögliche

(Spalte) im Resu ltset sq l i t e3_stmt -(s t atemen t . i )

Werte: einer Anweisung ab Zeiger

SOLI TE_ i -Die Nummer

I NTEGER des Feldes, von dem

Daten abgerufen SO LI TE_ LOAT werden sollen

SOLITE_BLOB

SOLITE_NU LL

SOLI TE_ TEX T

176

Page 178: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

DataAccessObject in nativen Datenbanken verwenden

sql ite3_ i nt Ruft den Wert eines statement-Ein

co lumn_int Integerfeldes ab sq l i te3_stmt-(sta tement, i ) Zeiger

i -Die Nummer

des Feldes, von dem

Daten abgerufen

werden sollen

sql ite3_ double Ruft den Wert eines statement-Ein column_doub l e doubl e-Feldes ab sq l i te3_stmt-

(sta tement, i ) Zeiger

i -Die Nummer

des Feldes, von dem

Daten abgerufen

werden sollen

sqlite3_ const Ruft den Wert eines statement-Ein co lumn_text unsigned Stringfeldes ab sq l i te3_stmt-(sta tement, i ) char * Zeiger

i -Die Nummer

des Feldes, von dem

Daten abgerufen

werden sollen

sqlite3_ byte * Ruft die Bytes eines statement-Ein co lumn_bl ob BLOß-Feldes (Binary sq l i te3_stmt-(sta tement, i ) Large Obj ect) ab Zeiger

i -Die Nummer

des Feldes, von dem

Daten abgerufen

werden sollen

sql ite3_ int Ruft die Anzahl der statement-Ein co lumn_bytes Bytes im Wert eines sq l i te3_stmt-(sta tement, i ) BLOß-Feldes ab Zeiger

i -Die Nummer

des Feldes, von dem

Daten abgerufen

werden sollen

177

Page 179: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

sqlite3_ void Ruft die mit der Anwei- statement-Ein

finalize sung verknüpften sq l ite3_stmt-(statement) Ressourcen ab Zeiger

sqlite3_ i nt Bindet einen Zeiger auf statement-Ein

bind - bl ob ein Byte-Array an einen sq l ite3_ stmt-(statement, Platzhalter in einer vor- Zeiger parameter l ndex, bereiteten Anweisung

parameterlndex aVariable,

-Die Indexnummer bytelength,

des Platzhalters in transcienceKey )

der vorbereiteten

Anweisung

aVariab l e-Ein

Zeiger auf das Byte-

Array, das in der

Datenbank gespei-

chert werden soll

byte Length- Der

Anzah l der zu spei-

ehernden Bytes

transcienceKey

-Ein Indikator dafür,

ob die einzufügen-

den Daten vorher

kopiert werden so I-len, um zu verhin-

dern, dass sich die

Daten während der

Speicherung ändern

sq l ite3_ bind_ i nt Bindet einen doub l e-Typ statement-Ein doub l e(statement, an einen Platzhalter in sq l i te3_stmt-parameter l ndex, einer vorbereiteten Zeiger aVariab l e) Anweisung

178

Page 180: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

DataAccessObject in nativen Datenbanken verwenden

{Fortsetzung) paramet er l ndex - Die lndexnum-

mer des Platzhal-

ters in der vorberei-

teten Anweisung

aVa r i abl e - Ein

doub 1 e-Wert, der

in der Datenbank

gespeichert

werden soll

sq l i te3_bind_ i nt Bindet einen Integer sta temen t -Ein int ( statement, an einen Platzhalter sq l i te3_stmt-

pa r ameterlndex, in einer vorbereiteten Zeiger aVar i abl e) Anweisung

parameter l ndex -Die lndexnum-

mer des Platzhal-

ters in der vorberei-

teten Anweisung

aVariab l e-Ein

Integer, der in der

Datenbank gespei-

chert werden soll

Tabelle 6-7= Die SQLLite3-API

Diese ( -Bibliothek enthält alle Funktionen, die für den Zugriff auf SQLite-Datenbanken

erforderlich sind, sowie zusätzliche Merkmale wie Transaktionen und vorbereitete Anwei­

sungen. Der folgende Code, der aus der Methode dbAccess des SO Li teDataAccess­

Obj ekts stammt, zeigt, wie Sie die API einsetzen, um mit vorbereiteten Anweisungen zu arbeiten. Wie in der Tabelle zur API aufgefüh rt, müssen der Funktion sq l i te3_p repa ­

re_v2 ein Zeiger auf die Datenbank, die auszuführende SQL-Anweisung sowie ein Zeiger

auf die Va riable sq l i te3_ stmt übergeben werden. Tritt während der Ausführung der

SQL-Anweisung ein Feh ler auf, gibt sq l ite3_ prepa r e_v2 einen numerischen Fehler­

code zurück.

179

Page 181: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

int numResultColumns = 0; sqlite3_stmt *statement = nil; const char* SQLChar = [SOL UTFBString]; if Csqli te3_prepare_v2C database, SO LChar, -1.

&statement, NU LL) == SQ LITE_O K) (

Die in dem vorstehenden Code übergebene Variable sql i te3_stmt wird bei der Ausfüh­

rung der Funktion sq l i te3_p repa re_v2 gesetzt und enthält die SQLite3-Anweisung, die

anschließend verwendet wird, um die einzelnen Datenelemente aus dem Resultset einer

ausgeführten SQL-Abfrage abzurufen. Durch die einzelnen Aufrufe der Funkt ion sq l i te3_

s tep wi rd eine Einfügemarke verschoben, die die Zeilenposition im Resultset markiert.

Wenn das Resultset leer ist, also keine Zei len enthä lt, gibt sql i te3_step also nicht

SQLI TE_ ROW zurück, sondern SOLI TE_DONE. Dadurch können Sie eine whi l e-Anweisung

verwenden, um die Daten aus der Zei le abzurufen, auf die die Einfügemarke zeigt.

whi l e Csq l i te3_s tep(statement) == SOL I TE_ROW) (

in dieser whi l e-Schleife w ird eine Folge von NSMutab l eArrays erstellt, wie Sie in Zei le

232 der Datei SQLiteDataAccess.m und in der folgenden Zeile sehen. Jedes dieser Arrays

steht für eine Zeile mit abgerufenen Ergebnissen und wird daher row genannt.

NSMutabl eArray *row = [[NSMuta bl eArray al loc ] in i tWithCapacity:numResu l tCo l umns];

Die Aufrufe, mit denen die einzelnen Felder aus den Datensätzen des Resultsets gewon­

nen werden, müssen jeweils so erfolgen, dass die Daten mit dem korrekten Typ abgerufen

werden. in Tabelle 6.7 finden Sie die verfügba ren Funktionen für die verschiedenen Typen.

Im folgenden Code werden alle diese Funktionen aufgerufen.

i nt type = [ [ [ theResu l t co l umnTypes ] objectAtlndex:i] i ntVa l ue];

i f(type == SOL I TE_I NTEGER) (

180

NSNumber *aNum = [ [ NSNumber al l oc] i nitWi thlnt: sq l i te3_column_int(statement, i)] ;

[ row addObject:aNum] ; [ aNum autorelease] ;

Page 182: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

DataAccessObject in nativen Datenbanken verwenden

else if(type == SQLITE_FLOAT){ NSNumber *aFl oat = [ [ NSNumber alloc ]

initWithFl oat :sqlite3_column_double(statement. i )J;

[row addObject:aFloat]; [aFl oat autorel ease];

else if(type == SQLITE_TEXT){ NSString *aText = [[NSString al loc]

initWithCString:sqli te3_col umn_text(statement. i) encoding:NSASC II String Encoding];

[row addObject:aText ]; [aText autorelease];

el se if( t ype == SQ LITE_B LOB){ NSData *aData = [ [NSData al l oc]

dataWithßytes:sql ite3_col umn_bl ob(statement. i) l ength: sql ite3_col umn_bytes(statement,i)];

[ row addObject:aData]; [aData autore l ease];

el se{// SQ LITE_NU LL [ row addObject:@"nul l "];

Um jeweils die richtige Funktion aufzurufen, muss der Typ des betreffenden Feldes be­stimmt werden. Dazu werden die Feldtypen vor diesen Aufrufen ermittelt und gespei­chert, wie Sie in den Zei len 213 bis 220 der Datei SQLiteDataAccess.m und im folgenden Code sehen:

NSMut ab l eArray *col umnTypes = [ [NSMutableArray al l oc ] initWithCapacity:OJ:

for(int i = 0: i < numResultCol umns; i ++){ NSNumber * col umnType = [NSNumber numberWithi nt:

sql ite3_col umn_t ype(statement,i)]; [col umnTypes addObject:col umnType];

[theResul t set Col umnTypes:col umnTypes];

[col umTypes re l ease ];

181

Page 183: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

Der Typ der einzelnen Spalten wird mit der Funktion sq l ite3_ col umn_ type vom

Resultset der Anweisung abgerufen. Der Funktion werden der Anweisungszeiger und die

Nummer des Feldes übergeben, dessen Typ bestimmt werden soll, woraufhin sie einen

numerischen Indikator für den Feldtyp zurückgibt. Möglich sind folgende Werte:

> SQL I TE_INTEGER

> SQLITE_FLOAT

> SQLITE_BLOB

> SQLITE_NUL L

> SQLITE_TEXT

DerRückgabetypderMethoden dbAccess,setData und get Data istein Da taAcce s s Res u l t ­

Zeiger. Dieses Objektenthält das Ergebnis der Ausführungeines beliebigen SQL-Strings in einer

SQLite-Datenbank. Derfolgende Code stammt aus der Datei DataAccessResult.h und zeigt die

Felder, die zum Speichern der Ergebnisse einer SQL-Abfrage verwendet werden.

@interface DataAccessResul t : NSObject { NSArray *fiel dNames; NSArray *co l umnTypes; NSMutabl eArray *resul ts; NSString *errorDescription: NS i nteger rowsAffected; NS i nteger inserted i D:

@property (nonatomic, retain) @property (nonatomic, retain) @property (nonatomic, retain)

NSArray *fiel dNames; NSArray *columnTypes; NSMutabl eArray *results;

@property (nonatomic, retain) NSString *errorDescr i ption: @property (nonatomic) NSinteger rowsAffected; @property (nonatomic) NSinteger inserted i D:

- CNSString*) JSONStringify;

@end

Da sich das Framework, wie schon in Kapitel4 besprochen, um die Datenübergabe küm­

mert, sind in den an die VCOs (View Control Objects) gesendeten Parametern auch al le

DataAccessResult-Obj ekte entha lten, die durch Aufrufe des SOL iteDataAccess­

Objekts erstellt wurden. Weil der Aufruf zum Festlegen oder Abrufen von Daten in der

nat iven Datenbank von JavaScript ausgeht, müssen die Endergebnisse der Abfragen

zurück an die JavaScript-Anwendung übergeben werden. Dies geschieht mithilfe des

SendDBResul tVCO-Objekts.

182

Page 184: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

DataAccessObject in nativen Datenbanken verwenden

Wie al le Befehlsobjekte hat auch SendDBResul tVCO eine doCommand-Methode. Da die

Daten zurück an JavaScript übertragen werden müssen, werden die Ergebnisse in einen

JSON-String konvertiert. ln den Zeilen 8 bis 12 des folgenden Codes sehen Sie, w ie dies

geschieht. Jedes Ergebnis wird zunächst in einen JSON-String umgewandelt und dann

dem NSMutabl eArray namens retVa l hinzugefügt. Dieses Array w ird dann in einen

JSON-String konvertiert. Aufgrund von Einschränkungen in der JSON-Bibl iothek von

Objective-C ist ein Aufruf zum Erstel len eines JSON-Strings aus einem Array von Objek­

ten nicht möglich. Die JSON-Bibliothek reicht nicht aus, um Objekte in Arrays korrekt zu

konvertieren. Daher ist für jedes DataAcces s Res ul t -Objekt ein zusätzlicher Aufruf von

JSONStri ngi fy erforderl ich.

1 + (id) doCommand:(NSArray*) parameterst

2 NSMut abl eArray *ret Va l = [[NSMutabl eArray all oc] ini t]; 3 NSArray *resul ts = [ parameters subarrayWithRange:aRange ] ; 4 int numResul t s = [ resu l t s count]; 5 for(int i = 0; i < numResults; i ++){ 6 DataAccessResul t * aResul t = 7 (Oa t aAccessResul t *)[resul ts objectAtlndex:i]; 8 NSString* resu l t String = [ aResul t JSONStringi fy ]; 9 [retVa l addObject:resul t String] ;

10 [aResu l t re l ease ] ; 11 12 [ re t Va l addObject:[ [ paramet ers object Atlndex: 4 ]

object Atlndex:O JJ : 13 14 SBJSON *generator = [ SBJSON al l oc ] ; 15 NSError *error ; 16 NSSt r i ng *da t aString = [ genera t or st r i ngWithObject:

retVa l error:&error ];

17 [ re t Va l re l ease ] ; 18 [ genera t or re l ease ]; 19 dataString = [ da t aString 20 st r i ngßyRepl acingOccurrencesOfString:@" ' "

wit hSt r i ng:@" \\ '" ] ; 21 dataString = [ da t aString

183

Page 185: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 6

22 stringByRepl ac i ngOccurrencesOfString :@"&" withString:@"\\&" J:

23 NSString *jsStr ing = [ [NSSt r i ng all oc] 24 i nitWithFormat : 25 @" handl eRequestCompl et i onFromNat i ve( ' %@ ' ) 26 • data String]; 27 QuickConnectViewControl l er *contro l ler 28 parameters objectAtlndex :OJ: 29 [controller.webView 30 stringßyEva l uatingJavaScriptFromString:jsString]);

31 [jsStr ing re l ease]; 32 return ni l : 33

Wie in Kapitel 4, wo die Ergebnisse in einen JSON-String konvertiert wurden, erfolgt auch hier

ein Aufruf, der sie zur weiteren Verarbeit ung zum JavaScript-Teil der Anwendung übergibt. Da­

bei handelt es sich um den zuvor gezeigten Aufrufvon s tri ngßy Eva l uat i ngJa v a Scr i pt ­

FromSt r i ng. Er f ührt die JavaScript-Funktion hand l eRequestComp l et i on FromNat i ve

aus, die sicherstellt, dass die restlichen BCOs und VCOs dem ursprünglichen Befehl zugeordnet

sind. Zusammenfassung

Das JavaSc:ript-Modul DataAcces sObj ect macht die Interaktion mit SQLite-Daten­banken in der WebKit -Engine bedeutend einfacher. Da das Modul nur JavaScript-Stan­

dardtypen wieStrings und Arrays akzeptiert, lässt es sich einfacher aufrufen als die SQLite­

JavaScript-Funktionen der WebKit-Engine selbst. Da taAcces sObj ect fungiert außerdem als Fassade f ür den Zugriff auf »native« Datenbankdateien, die Sie zusammen mit Ihrer

Anwendung ausliefern können. Der Zugriff auf die Daten in diesen Datenbanken ist mit

JavaScript-Aufrufen möglich. Dadurch wird eine JavaScript-Anwendung so ausgereift, als

hätten Sie sie in Objective-C geschrieben.

Wie DataAccessObject in JavaScript vereinfacht auch die Obj ective-C-Kiasse SO Li te ­

DataAccess den Abruf oder die Eingabe von Daten in SQLite-Datenbanken, die Sie mit

Ihrer Anwendung ausliefern. Diese Klasse folgt demselben Aufbau w ie DataAccess ­

Object in JavaScript, sodass Sie den Umgang damit leichter lernen können, auch wenn

Sie mit Obj ective-C nicht vert raut sind.

184

Page 186: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

DataAccessObject in nativen Datenbanken verwenden

Da alle Ergebnisse von Abfragen einer WebKit- oder einer nativen Datenbank Objekte mit

JavaScript-Standardtypen sind, müssen Sie die inneren Mechanismen von SQLite-, Web­

Kit- und nativen Datenbanken nicht kennen.

Sowohl DataAccessObject als auch die Klasse SO L iteDataAccess bieten die Trans­

aktionssicherheit, die nötig ist, damit asynchrone Aufrufe keine Anforderungen unterbre­

chen. Sie können gefahrlos eine Reihe von gleichzeitigen Datenbankaufrufen ausführen,

ohne befürchten zu müssen, dass Sie dadurch die Daten in der Datenbank beschädigen.

Im nächsten Kapitel sehen wir uns an, wie Sie einen Wrapper für AJAX-Aufrufe erstellen,

derwie DataAccessObject aussieht und sich auch so verhält.

185

Page 187: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 188: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Datenzugriff über das Netzwerk

Manchmal muss eine Anwendung auch auf Daten in einer nicht lokalen Datenbank oder

von einem Webdienst zugreifen. Es kann sogar sein, dass die Dat en auf dem iPhone mit

Dat en synchronisiert werden müssen, die irgendwo im Netzwerk gespeichert sind.

Web-Apps für das iPhone machen dies einfach. Aufgrund ihrer hybriden Nat ur haben Sie

Vollzugriff auf das XM LHt t pRequest-Objekt in JavaScript . ln diesem Kapit el lernen Sie,

wie Sie Dat en von einem RSS-Feed abrufen und in Ihrer Anwendung anzeigen.

Wie beim Datenbankzugriff in Kapitel 6 wi rd im erst en Abschnitt ein einfach zu verwen­

dender Wrapper fü r das XM LHt t pReque s t -Objekt vorgestel lt . ln den nachfolgenden Ab­

schnitten w ird erklärt, w ie Sie diesen Wrapper erstel len und wie er f unkt ioniert.

Page 189: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

7.1 ABSCHNITT 1: DIE BEISPIELANWENDUNG

ßROWSERAJAXACCESS

Die Beispielanwendung na t i veDBAccess in Kapitel 6 hat gezeigt, wie Sie Daten in einer

SQLite-Datenbank auf dem Gerät speichern und aus ihr abrufen. ln diesem Kapitel wird

eine ähnliche Anwendung verwendet, die Daten von Webdiensten und Servern abruft. Den

Ordnerfür die Anwendung browserAJAXAccess finden Sie im Verzeichnis iPhone Examples des Ordners QuickConnectiFamily, den Sie von sourceforge.netlprojects/quickconnect/ herun­

tergeladen haben.Abbildung7.1 zeigt die laufende Beispielanwendung.

Alle WordPress-Biogs haben einen RSS-Feed, der die letzten zehn Einträge jedes Blogs

bereitstellt, wie Sie in Abbildung 7-2 sehen. Es sieht zwar nicht so aus, als ob dieser Feed

die vollständigen Blageinträge anzeigt, dies ist aber tatsächlich der Fal l. Die Anwendung

browserAJAXAccess zeigt nur die Überschriften an, kann aber sehr leicht mit dem An­

satz und dem Code aus Kapitel6 erweitert werden, um die Überschriften und die Postings

zu speichern.

Zum Glück kümmert sich kein RSS-Feed darum, welcher Art der Client ist. Wenn ein Feed

eine Anforderung fü r Blogpostings erhält, sendet er diese im XML-Form, und zwar unab­

hängig davon, wer oder was den Feedangefordert hat. Da U I WebV i ew die WebKit-Engine

ent hält, kann es Anforderungen an Feeds senden und die zurückgegebenen XML-Daten

interpretieren. Als Werkzeug dazu verwenden Sie das XMLHttpRequest -Obj ekt, und als

Verfahrensweise AJAX.

188

~ Abbildung p: Die Anwendung br owser AJAXAcc ess mit 8/og/istings von TetonTech

Page 190: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Die Beispielanwendung BrowserAJAXAccess

I AJAX IST KEIN GRIECHE

Eines der größten literarischen Werke aller Zeiten ist die 1/ias. ln diesem epischen Ge­

dicht von Homer geht es um den Krieg zwischen den Griechen (oder Achäern) und den

Einwohnern von Troja.

Einer der größten Helden der Griechen ist Ajax. Wiederholt besiegte er seine Gegner,

und einmal bewahrte er ganz allein die griechische Flotte vor der Zerstörung.

Wie die griechische Flotte ist auch die traditionelle Entwicklung von Webseiten Angrif­fen ausgesetzt. Sie wird als zu langsam, zu schwierig zu verwenden und zu unflexibel

angesehen. Wieder einmal kommt ein AJAX zur Hilfe, aber diesmal ist es kein Grieche.

AJAX steht für Asynchronaus JavaScript and XML.

Das Prinzip von AJAX ist einfach: Der Benutzer erhält stimmigere lnteraktionsmöglich­

keiten, indem die Seiten nicht bei jeder Anforderung neu geladen werden. Stattdessen

werden Daten gesendet oder abgerufen und das Ergebnis dann durch dynamisches

HTML angezeigt. Durch die Verwendung von JavaScript kann dies alles auf einer einzi­

gen HTML-Seite geschehen.

AJAX sollte Ihnen daher nicht griechisch vorkommen. Und spanisch schon gar nicht.

Ou!ckConn•etiPhoru;a 1.1.1 now :W::Ji '.;lblo r-:b•u:uy I 3 J? PM Now Oui:k.Conn&et ~~loooo a•tWI~kt.

Ou!skCpt~ntetUnyx Dtl!l I lt New !Wl'lllni::!ID fsb IUHY 4. 3 .:,C PM

t took 1~ than OllpCd.ed, bUt 11 ls here. OuiekO:lfl~e!Linw 1.0 bela 1 u3eS tle 4.5 ve ...

O!.l!ckCOI)OtCIIPI!OO!J I 1 2 OON iWij!Jab!o :lf!ll.vy 17 r r PI.C

h te~n)e l tt " r~ rrcm ll dolrn!'b~r 11$if9 OCiPM~ \1!t9ion 1. 1 2 hA9 bf\o@l"l ( rtl'.fi@d .•

Pll'lm Pta lind Mntn Jllt~IJ •• Ii PI.(

l IOO'U 1111) P:tlill't; (lOW SOK ~I wt:rt l'o:ltld ·fn ·n3n0 'M11'1 Oclek.Cot!f'IOC'l A pon IC ::t !:U • ••

~ Abbildung 7-2: Der RSS-Feed von Teton Tech im Browser Safari

189

Page 191: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

Durch die Kombination des XM LHttpRequest-Objekts mit einfachem JavaScript zur

Bearbeitung einer Webseite kann Ihre iPhone-Web-App Daten aus dem Netzwerk so ver­

wenden wie lokale Daten. So können Sie die Vorteile beider Seiten genießen: Ihre Anwen­

dung kann sowohl eigenständig als auch im Netzwerkmodus laufen, und soba ld eine Ver­

bindung verfügbar ist, können Sie die Daten synchronisieren, um etwaige Abweichungen

auszugleichen. Im Framewerk Qu ickConnectiPhone finden Sie mit ServerAccessObj ect

einen einfach zu verwendenden AJAX-Wrapper.

7.2 ABSCHNITT 2: 5ERVERÄCCESSÜBJECT VERWENDEN

Mit dem AJAX-Wrapper ServerAcces sObj ect können Sie sehr leicht auf Daten im Netz­

werk zugreifen, ohne sich um die Feinheiten der API für das XM LHttpRequest-Objekt

kümmern zu müssen. Die API von ServerAccessObj ec t sieht fast genauso aus wie die

von Da taAcces sObj ect (siehe dazu Kapitel 6).

Auch die API von ServerAccessObj ec t hat einen Konst ruktor und zwei Methoden. Der

Konst ruktor enthä lt den URL des entfernten Servers und richtet die Methoden des Objekts ein. Diese Methoden- getData und setData- rufen dann Daten von dem im Konst ruk­

tor definierten entfernten Server ab bzw. senden sie an ihn. Tabelle 7.1 zeigt die API von

ServerAccessObject.

Attribut/Methode Rückgabewert Beschreibung Parameter

ServerAcces - Server - Erstellt beim Aufruf URL-Der URLdes Objec t (URU Access - mit dem Schlüssel- Servers, zu dem eine

Objec t wort new ein Verbindung hergestellt ServerAccess - werden soll

Object

ge tData void Die Methode ruft dataType- Der Typ ( dataType, Informationen von der abzurufenden refresh, pa ra - einem Server im Daten. Dafür gibt me t erSeq uence, Netzwerk ab. Dies es die beiden HTTPHeaders) ist der GET-Typ Mögl ichkeiten

einer Anforderung. ServerAccess -

Diese Methode ist Obj ect . XML und

t hreadsicher. ServerAccess -

Obj ect . TE XT.

190

Page 192: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject verwenden

{Fortsetzung) refresh- Ein

boaleseher Wert,

der anzeigt, ob

eine erzwungene

Aktualisierung der

Daten vom Server

erfolgen soll.

parameter -

Sequence- Alle

Parameter, die zum

URL hinzugefügt

werden müssen. Das

Fragezeichen am

Anfang dürfen Sie

nicht in diese Folge

aufnehmen.

HTTPHeaders -Ein

assoziatives Array der

Namen und Werte des

Anforderungsheaders,

die zusammen mit der

Anforderung gesendet

werden sollen.

set Da ta Keiner Die Methode da taType- DerTyp ( da taTy pe, pa ra - ändert oder erstellt der zu ändernden

meterSequence, Informat ionen bzw. zu erstellenden data, HTTPHeaders) auf einem Server Daten. Dafür gibt

im Netzwerk oder es die beiden

übergibt sichere Möglichkeiten

Para metertypen. ServerAccess -

Dies ist der POST -Typ Obj ect. XML und

einer Anforderung. ServerAccess -

Diese Methode ist Obj ect. TEXT.

t hreadsicher.

191

Page 193: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

(Fortsetzung) parameter-

Sequence- Alle

Parameter, die zum

URL hinzugefügt

werden müssen. Das

Fragezeichen am

Anfang dürfen Sie

nicht in diese Folge

aufnehmen.

data -Alle Daten, die

Sie in die Übertragung

aufnehmen möchten.

Dies können umfang-

reiche Mengen von Zeichendaten, Datei-

Uploads usw. sein.

HTTPHeaders- Ein

assoziatives Array der

Namen und Werte des

Anforderu ngsheaders,

die zusammen mit

der Anforderung

gesendet werden

sollen.

Tabelle p: Die API von Se rve rAccessObj ec t

Die Datei ServerAccessObjectjs, die Sie sowohl in der Dashcode- als auch in der Xcode­

Vorlage in der Gruppe QCIPHONE finden, ent hält den Wrapper ServerAccessObject.

Diese JavaScript-Datei w ird von beiden Vorlagen automatisch zur Datei index.htmllhrer Anwendung hinzugefügt.

Die Funktion getSiteData BC F aus der Datei functionjs verwendet diese JavaScript ­

Kiasse. Diese Datei enthä lt al le Steuerfunktionen für die Beispielanwendung browse r ­

AJAXAccess. Weitere Informationen über diese Funktionen und darüber, w ie Sie sie erstel len können, finden Sie in Kapitel 2, »Die Modularität von JavaScript f ür iPhone­

Anwendungen«.

Der Zweck der Funktion getSi teDataBCF besteht darin, Einträge aus dem Blog des Autors

abzurufen. Solche Abrufvorgänge können leicht mit ServerAccessObject erled igt

werden, w ie die Zeilen 2 bis 5 des folgenden Codes zeigen.

192

Page 194: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject verwenden

1 function get SiteDataBCF(paramet ers)( 2 var site = new ServerAccessObject( 3 ' http : llteton tech. wordpress.comlfeedl'); 4 site .getData(ServerAccessObject.XML, 5 ServerAccessObject.REFRESH); 6 II Da di eser AJAX- Datenzugriff saufruf asynchron ist, 7 II soll te diese BCF nichts zurückgeben. 8 9

Die Zei len 2 und 3 zeigen die Konstruktion eines neuen ServerAccessObject. lhm wird

der URL des zu verarbeitenden RSS-Feeds übergeben, in diesem Fal l der URL zum Blog des

Autors unter http://Tetontech.wordpress.com!feed. Um auf einen anderen Blog zuzugrei­

fen, ersetzen Sie entsprechend den UR L.

ln Zeile 4 und 5 wird dann das neue Objektnamens s i te verwendet, um die Daten zu ge­winnen. Da es sich um einen RSS-Feed handelt und da bekannt ist, dass der Server Daten

im XML-Typ an die Anwendung zurücksendet, wi rd der Datentyp auf XML gesetzt. Der

zweite Parameter ist ein Flag, das eine Akt ualisierung der Daten statt der Verwendung ei­

ner zwischengespeicherten Version erzwingt. Dies ist erforderlich, wenn Sie sicherstel len

möchten, dass die empfangenen Daten sämtliche auf dem Server gespeicherten Ände­

rungen ent halten.

Es kann jedoch schlechte Folgen haben, in jedem Fal l blind eine Aktualisierung zu erzwin­

gen. Wenn Siedies t un, obwoh I gar keine Aktua I isieru ng erforderlich ist, kann dies bei weiter

Verbreitung Ihrer Anwendung zu einer Überlastung von Server und Netzwerk führen. Aus

diesem Grund sol lten Sie abwägen, ob wirklich die absolut neuesten Daten erforderlich sind

oder ob Sie mit leicht veralteten Daten leben können.

Wie bei DataAccessObject sind auch alle Aufrufe von ServerAccessObj ect asyn­

chron. Es können gleichzeitig mehrere Aufrufe ausgeführt werden, sofern für jeden ein

neues ServerAccessObject erstel lt w ird. Wenn Sie das Framework QuickConnect­iPhone verwenden, müssen Sie nicht wie in AJAX eine Cal lback-Funktion defin ieren. Das

Framework sorgt dafür, dass alle verbleibenden BDFs (Business Control Functions) und

VCFs (View Cont rol Functions) ausgeführt werden, die demselben Befehl zugeordnet wer­

den wie die BDF, die das Se rve r Acces sübj ect aufgerufen hat.

Die Funktionen getSi teDataBCF und di sp l aySi teDataVC F sind beidein der Datei

mappingsjs dem Befehl samp l eQuery zugeordnet, wie Sie in Kapitel 2 erfahren haben.

Das bedeutet, das Framework sorgt dafür, dass die von getSi teDataBCF angeforderten

Daten garantiert an d i spl aySi teDataVCF übergeben werden.

193

Page 195: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

Den Code von d i s p l ayS i teDa ta VC F finden Sie im folgenden Listing. Der an diese Funk­

tion übergebene Parameter resu l ts ist ein Array aus JavaScript-Objekten für die ein­

zelnen BCFs, die dem Befehl sampl eQuery zugeordnet sind. Die Methode getData von

ServerAcces sObj ect erstellt ebensowie die gleichnamige Methodevon Da taAccess­

Object ein QueryResul t -Objekt (weitere Informationen über QueryResul t-Objekte

finden Sie in Kapitel 6).

Nachdem im folgenden Code die durch die Variable container dargestellten Elemente

gelöscht sind, wird in Zeile 9 das QueryResul t-Objekt mit den Ergebnissen des AJAX­

Aufrufs abgerufen. Da es sich bei getSiteDataBCF um die erste BCF handelt, die dem

Befehl samp l eQue ry zugeordnet ist, wird das durch diesen Aufruf hervorgerufene Ergeb­

nis zum ersten Objekt im Arrayparameter resul ts.

Wie in Kapitel 6 gezeigt, haben QueryResu l t-Objekte ein Attribut namens data. Bei

XML-Anforderungen wie der in getSiteDataBCF wird dieses Attribut mit dem resultie­

renden XML-Dokument gefü llt.

Da dieses Dokument sehr stark dem HTML-Dokument ähnelt, das gewöhnlich für dynami­

sches HTML zum Einsatz kommt, wird es auch sehr ähn lich behandelt. Dieselben Arten von

Methoden stehen zur Verfügung, z.B. getEl emetßyld und getEl ementsßyTagName. Das Dokument besteht auch aus Node-Objekten mit Eitern-, Kind- und Geschwisterbezie­

hungen. Zur Interpretation dieser Daten können Sie alle Standardmethoden und -ansätze

verwenden.

Den Aufruf der Helferfunktion pa rseWordPress Feed in der Datei RSSUtilitiesjs sehen

Sie ebenfal ls in Zeile 9· Er verwendet diese Standardmethoden, um ein zweidimensionales

Array aus Blageinträgen namens entri es abzurufen. Jeder Eintrag im Array besteht aus

dem Datum des Postings, dem Inhalt und dem Titel.

1 function displ aySiteDataVCF(results, parameters){ 2 var container = 3 document.getEl ementßyld( ' queryResul ts ' ) ; 4 II Löscht die Inhal te des Containers 5 whi l e(container. l astChi l d) { 6 container.removeChi l d(container.lastCh i l d); 7 } 8 II Estell t Eintragsobjekte mit einem WordPress-Parser 9 var entries = parseWord PressFeed (results[O ] .data);

10 var numEntries = entries. l ength;

194

Page 196: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject verwenden

11 // Fügt f ür jeden Eintrag Titel und Datum 12 // i n den div - Conta i ner ein 13 for ( var i = numEntries - 1; i >= 0; i - ){ 14 var entry = entries[i ] ; 15 var publishDate = entry .date; 16 var t i tle = entry.tit l e; 17 18 var t i tleElement = document . createElemen t ( 'h2' ) ; 19 t itl eE l ement.innerText = entry.title; 20 container.appendChild(titleEl ement); 21 22 var da teE l ement = document.createElement( 'h3 ' ); 23 dateEl ement . i nnerText = entry .date ; 24 contai ner.appendChi l d( dateEl ement); 25 26 var hardRu l e = document. createEl ement( ' hr' ) ; 27 container . appendChi l d( hardRul e); 28 29

Beim Zugriff auf die einzelnen von der Helferfunktion pa rseWordPress Feederstellten

Einträge werden in den Zei len 13 bis 18 Objekte für HTML-Eiemente erstellt und in den

Container eingefügt, sodass die Anzeige den Titel und das Datum der Blageinträge um­

fasst. Um die Einträge voneinander zu trennen, wird eine Lin ie eingefügt.

Dieses Beispiel zeigt, w ie Sie mit RSS-Feeds umgehen, aber die anderen Arten des Zugriffs

lassen sich mindestens ebenso einfach handhaben. Sie können auch eine Anforderung

vom Typ TE XT machen und HTML-Code abrufen, der in die Benutzerschnittstelle Ihrer An­

wendung eingefügt wird. Al lerdings w ird aus Sicherheitsgründen davon abgeraten. Statt­

dessen können Sie bei einem Aufrufvom Typ TEXT JSON-Code abrufen.

Welche Art von Daten Sie auch abrufen müssen, mit ServerAccessObject geht es

einfach. lnstanzi ieren Sie das Objekt, und rufen Sie getData für eine GET-Anforderung

bzw. set Data für eine POST-Anforderung auf ln beiden Fä llen übergibt das Framework

QuickConnectiPhone die Informationen an alle nachfolgenden Steuerobj ekte, die Sie dem

Befehl zugeordnet haben.

195

Page 197: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel 7 Datenzugriff über das Netzwerk

JSON IST AUCH KEIN GRIECHE

JSON wird wie der englische Name Jason ausgesprochen, der auf den griechischen

Helden Jason aus der Argonautensage zurückgeht. Bemerkenswert ist, dass Jason und

seine Gefährten vor allem wegen ihrer langen Reise zur Rückgewinnung des Goldenen

Vlieses bekannt sind.

Auch bei JSON geht es um eine lange Reise, nämlich darum, wie JavaScript-Objekte große

Entfernungen im Netzwerk überbrücken. Das Akronym steht fü r JavaScript Object Nota­

tion, aber das ist nur ein neumodischer Name für etwas, das es schon lange gibt.

Der folgende Code zeigt, wie Sie ein JavaScript-Objekt erstellen und darin einen Vor­

und einen Nachnamen speichern:

var anObj ect = new Obj ect ( ) ; anObj ect . fName = 'bob '; anObj ect . l Name = ' jones ';

Im folgenden Code sehen Sie dies in der Objektnotation:

var anObj ect = { fN ame : 'bob '. l Name : ' jones ' ) ;

Was ist nun richtig? Beide Ansätze führen zum gleichen Ziel. Die zweite Vorgehens­

weise ist höchstwahrscheinlich schneller, aber bei umfangreichen Objekten bietet die

erste Möglichkeit eine bessere Lesbarkeit und Wartungsfreundlichkeit.

Die Objektnotation hat den Vorteil, dass Sie wie folgt überall als Zeichenstring gesen­

det werden kann:

"{fName :'bob ', l Name:'jones ' J"

Dieser String kann dann der JavaScript-Standardfunktion ev a l übergeben werden,

um ihn in ein Objekt umzuwandeln, aber das ist gefährlich. Eine sicherere und einfach anzuwendende Vorgehensweise finden Sie in Anhang A, »Einführung in JSON«.

Ist es ein Zufall, dass mit AJAX und JSON zwei griechische Helden zur Rettung der

Webentwicklung herbeieilen? l Urteilen Sie selbst!

7.3 ABSCHNITT 3: 5ERVERÄCCESSÜBJECT

/

Im vorherigen Abschnitt haben Sie gesehen, w ie Sie ServerAccessObj ec t einset zen,

damit Sie sich nicht um AJAX und die API von XM LHt t pReques t kümmern müssen. in die­sem Abschn itt lernen Sie, worum es sich dabei handelt und wie Sie diese Technik und die­

ses Obj ekt einset zen. Wenn Sie einfach nur Se r ve r Acces sObj ect verwenden, aber nicht

genau wissen möchten, wie es f unktioniert, können Sie diesen Abschnitt überspringen.

196

Page 198: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject

Der Zweck von Serve r AccessObjec t in QciPhone/ServerAccessObjectjs besteht darin,

dem Programmierer oder Entwickler so wenige Kenntnisse über AJAX aufbürden zu müssen

wie möglich. Daher ist diese Klasse so aufgebaut, dass ihre Methoden und Konstruktaren

denen des JavaScript-Datenbankwrappers DataAcces sObj ect aus Kapitel 6 stark ähneln.

Dank der vereinfachten API können Programmierer, die mit AJAX nicht vertraut sind, Daten

aus dem Netzwerk abrufen, ohne erst viellernen zu müssen. Wenn Sie die API für eines die­

ser Zugriffsobjekte kennen, w issen Sie auch, wie Sie die anderen benutzen müssen.

Der Konstruktor von ServerAcces sObj ect ist die einfachste der darin enthaltenen Me­

thoden. Er speichert den URL des entfernten Servers und definiert dann die Methoden

des Objekts. Die einzige funktionale Zei le des Konstruktors, die Sie im Folgenden sehen,

speichert den URL für die spätere Verwendung im URL-Attribut des Objekts:

t his . URL = URL ;

Auf dieses URL-Attribut greift der Programmierer niemals direkt zu. Stattdessen wird die

private Methode ma keCa l l verwendet.

Diese Methode ist Herz und Seele eines Se rve rAcces Obj ect. Sie verrichtet die gesamte

Arbeit, wenn das Objekt aufgefordert ist, irgendeine Form von Serverzugriff durchzufüh­ren. Als Fassade dienen ihr die beiden Methoden getDa ta und set Da ta . Die API-Beschrei­

bung in Tabelle 7.2 erläutert deren grundlegende Verwendung.

Wie Sie im folgenden Abschnitt sehen, wird für diese Fassaden eine der vielen Standard­

vorgehensweisen zur Zuweisung von Methoden zu Objekten verwendet. Dabei wird durch

den Aufruf des Konstruktars funct ionein Funktionsobjekt erstellt und das Ergebnis einem

Attribut des zurzeit durch das Schlüsselwort key repräsentierten Objekts zugewiesen.

Die beiden Fassadenmethoden getData und setData sind fast identisch. Seide nehmen

vier Parameter entgegen und übergeben diese und drei weitere an die zugrunde liegende

Methode ma keCa ll . Die zusätzlichen Parameter entsprechen dem ersten, fünften und

siebenten im Aufruf von getData und dem ersten, dritten und siebenten in dem von

setData. Den fünften Parameter der Methode ma keCa l l bilden die Daten, die im Rah­

men der POST -Anforderung an den Server übertragen werden. Dies ist bei der Methode

getData natürlich nicht erforderlich, weshalb hier nul l übergeben wird.

t his .getData = function ( dataType, refresh, parameterSequence, HTTPHeaders){

var passThroughParameters =

generatePassThroughParameters ( ); this.ma keCa ll ( ' GET ' . dataType, refresh,

parameterSequence, nul l . HTTPHeaders. passThroughParameters);

197

Page 199: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

this.setData = function(dataType, parameterSequence, data, HTTPHeaders ){

var passThroughParameters =

generatePassThroughParameters(); this.makeCall('POST', dataType, true,

parameterSequence, data, HTTPHeaders, passThroughParameters);

Der Funktionsaufrufgenera tePassTh roughPa ramete rs sammelt alle Informationen, die

erforderlich sind, damit das Framewerk mit der Verarbeitung der BCFs und VCFs fortfahren

kann, die der BCF zugeordnet sind, von der das ServerAccessObject verwendet wird.

Attribut/

Methode

makeCal l (cal lType,

dataType,

re f res h ,

parameter -

Sequence,

data, HTTP -

Headers ,pass -

ThroughPara -

meters)

Rückgabe­

wert

void

Beschreibung

Eine Methode,

die als privat bet rachtet wer-

den sollte. Diese

Methode erledigt

die eigentlichen

AJAX-Aufrufe an

den Server und

kümmert sich

um die Ergeb-

nisse.

Tabelle 7-2: API der privaten Methode ma keCa 11

198

Parameter

callType-EntwederGET oder POST

dataType-EntwederTEXT oder XML

refresh- Ein boolesches Flag, das

anzeigt, ob eine Aktualisierung der

Daten erzwungen werden soll.

pa rameterSequence- EinString der URL-Parameter, die in der

Anforderung verwendet werden

da t a -Zeichen- oder Bi nä rdaten,

die zusammen mit POST-

Anforderungen gesendet werden

HTTPHeaders- Ein assoziatives

Array der Namen und Werte des

HTIP-Anforderungsheaders

passThroughParameters-

Ein Array von Werten, die das

Framewerk benötigt, um nach dem

Empfang der Daten vom Server mit

der Verarbeitung fortzufahren

Page 200: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject

Der dritte Parameter der Methode ma keCa l l ist ein boolesches Flag, das anzeigt, ob der

Cl ient, in diesem Fall die U I We bVi ew, Caching einsetzen soll oder nicht. Bei der Methode

setDa ta ist Caching offensichtl ich nicht sinnvoll, weshalb hier t r ue hart kodiert ist, um

die Zwischenspeicherung auszuschalten.

Wenn Sie diese Parameter in die Methodensignatur von ma keCa l l aufnehmen, kann die

Methode das Verha lten zum Abrufen von Daten von einem entfernten Server sowie zum

Senden effektiv kapseln. Dieses Entwurfsmuster der Fassaden-Helferfunktionen wird häu­

fig verwendet, wenn, wie in diesem Fall, ein Großteil, aber nicht der gesamte Code zwei er oder mehrerer Methoden bzw. Funktionen identisch ist und ohne die Fassaden eine erheb­

liche Verdopplung von Code auftreten würde.

Um die Methode ma keCa l l verstehen zu können, müssen Sie die API des zugrunde lie­

genden JavaScript-Objekts XM LHt t pReq ues t kennen. Diese API ist in U I We bVi ew imple­

mentiert und wird in Web-Apps und in Mobile Safari verwendet.

Das einzige Objekt in dieser API ist XMLHt t pReques t (siehe Tabelle 7-3).

Attribut/

Methode

XM LHttpRequest ()

abort( )

getAl l Res ponse -

Headers ()

get ResponseHeader

CaHeaderName )

Rückgabe­

wert

XMLHttp -

Request

vo id

String

String

Beschreibung Parameter I

Ein Konstruktor für das Keine

Objekt

Beendet die Anforderung, Keine

zu der diese Methode

gehört

Als Ergebnis dieses Aufrufs Keine

wird einString mit allen

Namen und Werten

des Antwortheaders

zurückgegeben.

Gibt einen String mit aHeaderName-

dem Wert des Headers Der Name des HTIP-

mit dem angegebenen Antwortheaders,

Namen zurück. Falls kein dessen Wert

solcher Header existiert, abgerufen

wird nu l l oder gar nichts werden soll

zurückgegeben.

199

Page 201: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

open(type, void Öffnet eine Verbindung type- EinString

UR L , asynch, zum gewünschten Server mit dem Wert GET userName, und bereitet sie vor. oderPOST passWord)

asynch- Ein

boolesches Flag,

das anzeigt, ob

die Anforderung

asynchron erfolgen

soll. An dieser Stelle

muss stets true

übergeben werden.

userName- Ein

opt ionaler Para-

meter. Dies ist der

Benutzername,

derfür den Zugriff

auf die im URL

angegebene Datei

oder das Verzeichnis

erforderlich ist.

passWord-Ein

optionaler Pa rameter.

Dies ist das Kennwort

f ürden angegebenen

Benutzernamen,

dasfür den Zugriff

auf die im URL

angegebene Datei

oder das Verzeichnis

erforderlich ist.

200

Page 202: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject

send(data) void Eine Methode zum data- Die an

Anhängen von Zeichen- die Anforderung

und Binärdaten an eine angehängten

Anforderung. Sie wird Informationen

bei POST-Anforderungen

wie dem Hochladen von

Dateien verwendet.

SetRequest - void Eine Methode, die name-Ein String, Header ( name, Standardheaderwerte der den Header value ) überschreiben oder bezeichnet

benutzerdefinierte v a l ue- Ein String,

Headernamen und der den mit dem

-werte zu einer Namen verknüpften

Anforderung hinzu-Wert angibt

fügen kann.

onreadystate - Ein Attribut, das auf change eine Funktion gesetzt

w ird. Die angegebene

Funktion wird aufgerufen,

wenn das Ereignis

on r eadystatechange

ausgelöst wird. Dies

geschieht bei jedem

Wechsel von readyState.

readyState Eine Folge von

lntegerwerten, die den

Status der Anforderung

angeben. Folgende Werte

sind möglich:

o- Die Sendemethode

w urde noch nicht

aufgerufen.

201

Page 203: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

(Fortsetzung) 1- Die Anforderung wird an

den Server gesendet.

2- Der Server hat die

Anforderung empfangen.

3- Ein Teil der Antwort vom

Server wurde empfangen.

4- Die gesamte Antwort

vom Server wurde

empfangen.

responseText Die in Textform vom

Server gesendeten Daten

a bzüglich der HTIP-

Antwortheader

response XML Die in XML-DOM-Form vom

Server gesendeten Daten.

Sind die XML-Daten nicht

gü ltig, ist der Wert nul l .

status Eine vom Server gesendete

Zahl, die den Erfolg

oder Feh lsch lag einer

Anforderung angibt. Am

häufigsten sind die beiden

folgenden Werte:

404- Nicht gef unden

200- Erfolg

Eine vollständige Liste

fi nden Sie unter http:! I www.w3.org/Protocols! rjc2676!rfc2676-seC1o.html.

statusText Ein vom Server erstellter

String mit einer den Status-

codebegleitenden Meldung.

Tabelle 7-3: API des XM LHttpReques t -Objekts

202

Page 204: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject

Die am häufigsten verwendeten Methoden dieser API sind der Konstruktor sowie open

und send. Im folgenden Code finden Sie ein einfaches Beispiel zur Verwendung dieser

Methoden und anderer häufig genutzter Attribute. Hier wi rd die Hauptseite des Open­

Source-Projekts WebKit in Textform abgerufen.

Beachten Sie vor allem zwei Punkte in diesem einfachen Beispiel. Erstens weist das reques t ­

Objekt einen globalen Gültigkeitsbereich auf. Es steht zur Verwendung in der Funktion

handleResponse zur Verfügung, die automatisch von der Browser-Engine aufgerufen wird,

wenn sich der Statuswert readyState ändert. Dadurch w ird der Code vereinfacht, aber es

besteht ein Problem, wenn zwei Anforderungen einander versehentlich überschneiden oder

zur gleichen Zeit gesendet werden müssen.

var request = new XMLH t t pRequest(); request.onreadystatechange = handl eRes ponse ; request.open( IGET I . l http: llwebkit.orgl l . true); request.sent( I I ) :

function handleRes ponse(){ if(request.readyState == 4 ){

i f ( request.status == 200){ var resul t = response.responseText; II Hier wird das Ergebni s auf irgendeine Weise verarbeitet.

Aufgrund des globalen Gültigkeitsbereichs derVariablen reques t ist dieses einfache Bei­

spiel nicht th readsicher. Da die Anforderungen asynchron erfolgen, ist es möglich und oft

auch wahrscheinlich, dass sie einander überschneiden. Um dieses Problem zu lösen, ist

diese globale Variable in Se rve rAcces sObj ect gekapselt.

Das zweite Problem besteht darin, dass die Anforderung an einen vollständigen URL

gesendet wird. ln Standardbrowsern kann ein XM LHttpRequest-Objekt nur Daten von

dem Server abrufen, dem es entsprang. Für eine U I WebVi ew in einer Web-App gi lt diese

Einschränkung j edoch nicht . Sie kann Daten von jedem Server abrufen, da sie kein Server

ist. Dies ist Segen und Fluch zugleich.

ln Browsern besteht diese Einschränkung, um Angriffe durch siteübergreifendes Scripting

(Cross-Site Scripting, XSS) zu unterbinden. Solche Angriffe t reten auf, wenn schädlicher

JavaScript -Code in ansonsten harmlosen HTML-Code eingefügt wi rd, den Ihre Anwen­

dung anfordert. Da eine U IWebVi ew kein Browser ist, sind Sie nicht dafür zuständig, die

Anwendung gegen solche Angriffe zu schützen. Zum Glück versorgt Sie das Framework

QuickConnectiPhone mit der Mögl ichkeit, Sicherheitssteuerf unktionen (Security Control

203

Page 205: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

Functions, SCF) zuzuordnen, die das ServerAcces sObj ec t aufruft, bevor es die Ergeb­

nisse der Anforderung an die VCFs übergibt.

Diese SCFs werden wie VCFs erstellt und mithilfe der Funktion mapCommandToSCF zuge­

ordnet. Beispiele dafür finden Sie in Abschnitt 4·

Die API des XMLHttpRequest-Objekts enthält keine Möglichkeit, um eine Aktualisierung

zu erzwingen. Darum kümmert sich das ServerAccessObj ect, indem es einen der stan­

dardmäßigen HTIP-Anforderungsheader einrichtet.

if(refresh) { /* * Wenn wir das Cachi ng deaktivieren und ei nen Aufru f beim * Server erzwingen *möchten , muss der Header ' I f -Modified - Si nce ' au f einen Wert * i n der * Vergangenheit einges t el l t werden .

*I http. setRequestHeader ( " I f - Modif i ed - Si nce ",

" Sat, 1 Jan 2000 00 : 00:00 GMT" ) ;

Der Header If -Mod if i ed - Si n ce weist den Server an, Daten zu senden, fal ls das a nge­

forderte Element ein Änderungsdatum aufweist, das hinter dem Datum im Headerwert

liegt. Wenn Sie den Wert auf ein Datum in der Vergangenheit setzen, stellen Sie sicher,

dass keine zwischengespeicherten Daten verwendet werden.

Die API von ServerAccessObject hat j edoch kein Flag, mit dem der Benutzer die An­

forderung als synchron oder asynchron defin ieren kann. Al lgemein wird anerkannt, dass

AJAX-Aufrufe asynchron erfolgen sollten, da die Web-Engine dadurch fü r weitere Einga­

ben des Benutzers verfügbar bleibt. Wären sie synchron, würde sich die U I WebVi ew beim

Drehen des iPhones in einen leeren, weißen Bi ldschirm verwandeln. Dies würde auch ge­

schehen, wenn der Benutzer durch die Ansicht blättert, während eine Anforderung an den

Server unterwegs ist. Beides ist fü r den Benutzer unschön. Da das XMLHttp Request also

besser nicht synchron verwendet werden soll, sind in ServerAccessObject alle Anfor­

derungen als asynchron hart kodiert.

Anders als in den früheren Beispielen verwendet das ServerAccessObject keine ei­

genständige Funktion, um on readys tatechange-Ereignisse zu verarbeiten, sondern

eine anonyme Funktion (weitere Informationen über anonyme Funktionen erhalten Sie in

Kapitel 3, »Benutzerschnittstellen für das iPhone erstellen«). Der Grund dafür liegt darin,

dass anonyme Funktionen den Gültigkeitsbereich der übergeordneten Funkt ion haben.

204

Page 206: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject

ln diesem Fall sind daher alle in der Methode ma keCa l l deklarierten lokalen Variablen auch in der anonymen onreadystatechange-Funktion verfügbar. Damit ist das zuvor beschriebene Problem der globalen Variablen gelöst. Die Variable http wird als das neu erstellte XMLHttpRequest-Objekt deklariert, das in makeCa l l verwendet werden soll. Dadurch verbleibt sie auch dann im Gültigkeitsbereich, wenn die anonyme Funktion für onreadys tatechange aufgerufen wird.

Wenn Ihnen das Prinzip anonymer Funktionen nicht vertraut ist, widerspricht dieses Vor­gehen der Intuition, und wenn Sie anonyme Funktionen schon kennen, mag es hier so scheinen, als ob Sie mit einerVorgehensweise durchkommen, von der normalerweise ab­geraten wird. Der folgende Code enthält die gesamte anonyme Funktion.

1 http.onreadystatechange = fun ction (){ 2 3 i f (http.readySta te == ServerAccessObject.COMP LET E

I I http.aborted ){ 4 II Der Standardplatzha l ter für al le Arten von Datenabfragen 5 var queryResult = new QueryResult(); 6 II Dies sind benutzerdefinierte Feh l erheader, 7 II die Sie bei Bedarf vom Servercode senden können.

8 if (! http.aborted ){ 9 queryResult.errorNumber

10 http.getResponseHeader( ' QC -Error -Number ' ); 11 queryResult.errorMessage = 12 http.getResponseHeader( ' QC -Error -Message ' ) ; 13 14 15 16 17

if Chttp.aborted ){ queryResult.errorNumber

queryResul t.errorMessage -100 "Request timed out. " ;

18 el se if(http.status != ServerAccessObject . HTTP_O K 19 && http.status != ServerAccessObject.HTTP_LOCAL 20 && http.status != 21 ServerAccessObject.OSX_HTTP_File_Access){ 22 23 24 25 26

queryResul t.errorNumber = http.status; queryResul t.errorMessage = "Bad access type.";

205

Page 207: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7

27 28

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 } ;

206

Datenzugriff über das Netzwerk

I* * Ruft di e Daten ab, falls der Server die Me l dung zurückgibt, * dass di e An f orderung erfol gre i ch verarbeitet wurde, * oder wenn di e An f orderung direk t an eine Datei auf de r * Serverf estpl atte ging . * Abruf erfol gt al s Text oder XM L *I

i f(queryResu l t . errorNumber ==null)( queryResul t .da t a = ht t p[ ' response ' +dataType]; if(!dispatchToSCF(passThroug hPa rameters[O J .

queryResul t .data)){ queryResult . er rorNumber =

ServerAccessObject .I NSECURE_DATA_R ECE IVED: queryResult . errorMessage =

"Insecure data rec i eved . " ;

I* * Ruft die näc hste St euerfunkt ion in der Liste *auf , um resu l t Data zu übergeben *I i f(wi ndow . ca l l Func)( I* * Kann von außerhal b einer * dispatchToBCF - Fun kt ion aufgerufen werden . *Wenn ja , dann muss kei ne cal l Func -* Funkt ion def i niert sei n. *I

var t heResul t s = new Array(); t heResul t s . pus h(queryResu l t) ; t heResul t s . pus h(passThroughParameters) ; requestHand l er(passThroug hParameters [OJ. passThroughParamet ers[2 ], theRes ul ts) ;

Page 208: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

ServerAccessObject

Die Zeilen 36 bis 42 im vorstehenden Codefragment enthalten die bereits erwähnten SCF­

und VCF-Aufrufe. Zeile 36 sieht wie der Code im Frontcontroller von Kapitel 2 aus. Tatsäch­lich ist sie fast identisch mit dem dort beschriebenen Aufruf der Funktion chec kVal i da ­

t i on und verhält sich auch so.

Benutzer können schädliche Daten eingeben, aber auch Server können solche Daten sen­

den. Die Funktion checkSecur i t y ist eine Funktion in der Art eines Anwendungscont­

rollers wie c hec kVa l i da t i on. Sie ruft die SCFs auf, die Sie in der Datei mappingsjs dem­

selben Befehl zugeordnet haben wie der BCF, die das ServerAccessObj ec t verwendet.

Damit können Sie beliebig viele Sicherheitsprüfungen auf die empfangenen Daten an­

wenden, um sich gegen Angriffe durch siteübergreifendes Scripting zu schützen.

Nach der Überprüfungwerden die Daten einem QueryResul ts-Obj ekt hinzufügt, damit

die Anwendung mit ihrerVerarbeitungfortfahren kann. Dies geschieht durch einen Aufruf

der Funktion r equestHandl er. Die passThroug hPa r amete r s werden hier verwendet,

da sie die als nächste aufzurufende Steuerfunktion sowie den Befehl entha lten, der den

Aufruf der BCF ausgelöst hat. Durch den Aufruf von r equestHand l er stellt die Metho­

de ma keCa l l von ServerAccessOb ject sicher, dass alle Ihre Steuerfunkt ionen in der

Reihenfolge aufgerufen werden, in der Sie sie in der Datei mappingsjs zugeordnet haben.

Da auch das Ergebnisobjekt the Resu l ts übergeben wird, steht es allen nachfolgenden

Steuerfunktionen zur Verfügung. Das bedeutet, dass Sie die Daten anschließend in j eder

passenden Weise verwenden können.

~ Abbildung 7-3: Sowohl Benutzer als auch Server können einer Anwendung schädliche Daten liefern. Das Prinzip der doppelten Frontcontroller schützt Ihren Anwendungscode vor fehlerhaften und möglicherweise schädlichen Daten.

207

Page 209: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Kapitel7 Datenzugriff über das Netzwerk

Da die anonyme onreadystatechange-Funktion diese beiden anwendungscontroller­

ähnlichen Funktionsaufrufe enthält und die einzige Funktion ist, an die der Server Daten

sendet, f ungiert sie als zusätzlicher Frontcontroller Ihrer Anwendung. Wenn Sie das Se r­

ver Acces sObj ect also für den gesamten Datenzugriff über das Netzwerk verwenden,

erhalten Sie dadurch die Vorteile, die in Kapitel 2 fü r Standardanwendungen aufgezeigt

wurden, für die gesamte Kommunikation über das Netzwerk.

Das Muster der doppelten Frontcontroller sorgt für die nötige Sicherheit der Anwendung

und gibt Ihnen gleichzeitig die erforderliche Flexibilität für den Datenabruf von beliebi­

gen Servern. Abbi ldung 7·3 zeigt, wie die beiden Frontcontroller Ihre Anwendung und Ihre

Daten schützen.

7.4 ABSCHNITT 4: SICHERHEITSFUNKTIONEN

Das ServerAccessObj ect ruft SCFs auf, um die Gültigkeit und Sicherheit der vom Ser­

ver abgerufenen Daten zu prüfen. Sie entsprechen damit den in Kapitel 2 behandelten

Validierungsfunktionen und folgen dem Muster aller übrigen Steuerfunktionen.

Damit eine SCF aufgerufen werden kann, muss sie einem Befehl zugeordnet sein. Wenn

Ihre Anwendung z.B. verlangt, dass sich ein Benutzer anmeldet, damit ihm JSON-Daten

gesendet werden können. Eine solche Zuordnung kann wie folgt aussehen:

mapCommandToSCF( ' l ogin ' . chec kForFunctions);

Das bedeutet, dass Sie auch die Funkt ion checkForFunct i ons benötigen, die von

checkSecur i ty aufgerufen werden kann.

Da die Bibliothek j son2 in der Datei QciPhoneljson2js zur Verf ügung steht, können Sie

diese Funktion sehr leicht schreiben.

Funct ion checkForFunctions(data){ i f( data == JSON . stringify(JSON.parse(data){

return true;

return fa l se;

Bei der Analyse der Daten fügt die Methode J SON. parse zusätzliche Zeichen in den String

ein, fa lls sie auf Funktionsdeklarationen oder Funkt ionsauf rufe stößt. Dadurch schlagen diese Versuche zur Defin it ion oder zum Aufruf von Funktionen feh l, was einen dringend

benötigten Schutz gegen XSS-Angriffe (siteübergreifendes Scripting) bietet.

208

Page 210: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Zusammenfassung

Dies können Sie f ür Ihre Überprüfungen nutzen, indem Sie das neu erstellte JavaScript­

Objekt wieder in einen String zurückverwandeln und ihn mit dem Origina l vergleichen.

Treten Abweichungen auf, weiß die Anwendung, dass die vom Server empfangenen Daten

schäd lichen Code enthalten.

Das bedeutet, dass der an Sie gesendete JSON-Text keine Funktionsdefinitionen und -auf­

rufe entha lten darf Das ist eine gute Sache, denn ansonsten könnten Sie niemals sicher

sein, ob die JavaScript-Funktionen im JSON-Text Ihr Code oder Schadcode sind, der im Rah­

men eines XSS-Angriffs eingeschmuggelt wurde.

7.5 ZUSAMMENFASSUNG

Mit ServerAccessObj ect haben Sie eine einfache, sichere Möglichkeit, um Daten aus

Quellen im Netzwerk in Ihren Web-Apps abzurufen. Sie können eine einfach zu nutzende

API verwenden, die ebenso wie die Da taAccess -API den Lernaufwand stark verringert.

Durch SCFs können Sie den abgerufenen Code so sorgfältig prüfen, wie Sie es für erforder­

lich halten.

Ein ServerAccessObject kann Daten aus dem Netzwerk abrufen und mithi lfe eines

Da taAcces sObj ec t für die weitere Verarbeitung speichern oder direkt verwenden, wie

es in der Beispielanwendung browse r AJAX Exampl e geschieht. Damit ist es auch mög­

lich, loka le Daten auf dem Gerät mit denen auf einem entfernten Rechner zu synchroni­

sieren.

Mit ServerAccessObject können Sie Code erstel len, der automatisch einen Webser­

ver benachrichtigt, wenn der Anwendungscode feh lsch lägt. Sie können auch Messwerte

der iPhone-Anwendung erfassen und an den Server senden, um die Anwendung schnel ler

und einfacher verwendbar zu machen.

Dank Se rverAcces sübj ect stehen alle diese Möglichkeiten jetzt auf einfache Weise für

iPhone-Web-Apps zur Verfügung.

209

Page 211: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript
Page 212: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Einführung in JSON

JSON (JavaScript Object Notat ion) ist ein bemerkenswertes Konzept. Damit können Sie Ja­

vaScript-Objekte und -Arrays in Strings umwandeln, die sich über ein Netzwerk übergeben

oder in einer Datenbank speichern lassen. Später können diese Strings dann auf einem

anderen Computer oder nach dem Abruf aus der Datenbank in ihrer ursprünglichen Form

wiederhergestellt werden. Die Fähigkeit, JavaScript-Objekte und -Arrays zu serialisieren

und wieder zu expandieren, eröffnet ganz neue Möglichkeiten. ln diesem Anhang lernen

Sie die API (Applicat ion Programmer Interface) einer weiträumig akzeptierten JSON-Bib­

liothek kennen und sehen in einfachen Beispielen, wie diese Bibliothek angewendet wird.

A.l ABSCHNITT 1: HINTERGRUND

Die Übergabe von Informationen von einem System zum anderen ist stets ein Problem.

Das gilt vor allem für die Entwicklung von Webanwendungen, denn hier kann der Server in

praktisch jeder möglichen Sprache geschrieben werden und auf den unterschiedlichsten

Arten von Computern laufen. XML war eines der ersten Formate, das sich nicht um Gerät,

Betriebssystem und Sprache kümmerte und damit dieses Problem lösen sol lte, und es er-

Page 213: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anhang A Einführung in JSON

fü llt in vielen Gebieten auch durchaus seinen Zweck. Für die Datenübertragung ist XML

j edoch des Guten zu viel, vor allemangesichtsder geringen Mengen an Informationen, die

gewöhnlich mit AJAX gesendet werden. Wenn Sie einfach nur ein Array aus Zahlen oder

eine Schlüssel-Wert-Zuordnung senden wollen, ist XML zu aufwendig. Das Problem wird

nicht durch die Erfindung einerneuen Technologie gelöst, sondern durch die Nutzung von

Fäh igkeiten, die bereits in Interpretersprachen schlummern.

Alle wichtigen Interpretersprachen mit loser Typisierung weisen eine Art ev a 1-Funktion

auf, die Strings so ausführt, als wären sie Quel lcode. Dies ist eine sehr leistungsfähige,

aber auch gefährliche Fähigkeit, denn wenn sie falsch eingesetzt wird, kann sie eine An­

wendung für Hacker und jede Form von Missbrauch öffnen. Daneben können in allen

wichtigen Interpretersprachen mit loser Typisierung Arrays und Objekte auch ohne den

Aufruf eines lnstanziierungs-Schlüsselworts wienewerstel lt werden.

Wenn Sie sich Java Script-Code ansehen, können Sie schnell erkennen, wie ein Array erstellt

wird. Das erste Beispiel zeigt einen obj ektorientierten Ansatz:

var array = new Array () ; array.push(5); array.push(13 ) ; array.push( 'hel l o ' ) ;

Das zweite Beispiel ist nicht obj ektorientiert:

var array = [5, 13, ' hel l o 'J:

Das Ergebnis ist in beiden Fäl len gleich. Es ist j edoch das zweite Beispiel, das uns für unse­

re Erörterung von JSON interessiert. Zusammen mit der Mögl ichkeit, Strings in JavaScript

wie Code auszuf ühren, wird durch diese Vergehensweise mit JSON möglich.

Der folgende Code erstellt einen Zeichenstring in der Form, die ein Programmierer ver­

wendet, um mit der Vergehensweise aus dem zweiten Beispiel ein Array anzulegen. Er­

stellt wird hier nicht das Array selbst, sondern eine Beschreibung des Arrays.

var someStr i ng = " [ 5, 13, 'hell o'J": II Wert et den St ring aus var array = eval( someStr i ng ) ;

ln der letzten Zeile wird der String als JavaScript-Quellcode ana lysiert, dieser JavaScript­

Code interpretiert und ausgeführt. Der String befindet sich in diesem einfachen Beispiel

in derselben Anwendung wie der Aufruf voneva l, weshalb dieser Vorgang eigentlich un-

212

Page 214: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Eine JSON-API für JavaScript

sinn ig ist. Wenn der String jedoch aus dem Objective-C-Teil einer QuickConnectiPhone­

Anwendung stammt oder, wie es in herkömmlichen Anwendungen der Fal l ist, von einem

Server, dann ist dieser Aufruf von ev a 1 sehr viel sinnvoller.

Obj ekte werden ähn lich erstellt. Bei dem folgenden objektorientierten Ansatz wird ein

Obj ekt angelegt und mit Attributen versehen:

var object = new Object(); object.width = 5: object.height = 13: object.message = ' he l lo ' :

Der entsprechende nicht objektorientierte Ansatz sieht wie folgt aus:

var object = { "wi dth":5," height " :l3, "message ":"hello"l:

Im Folgenden sehen Sie den JSON-Code:

var someStr i ng = '{"width" :5," height ": l 3, "message":" hello " } ': II Wertet den String aus var object = eva l (someStr i ng);

Dies ist zwar der Kern von JSON, doch dies selbst zu implementieren, birgt Gefahren. Wenn

der String beispielsweise vom JavaScript- zum Objective-C-Teil einer QuickConnectiPhone­

Anwendung übergeben wird und komplexe Anweisungen enthält, ist es möglich, damit

den gesamten Inhalt der Festplatte zu löschen.

Um dieses Sicherheitsproblem zu lösen, w urden bereits JSON-Bibliotheken entwickelt.

Diejenige f ür die JavaScript-Seite J son2 in der Dateijson2js. J s on2 ist der am häufigsten

eingesetzte JSON-Parser in JavaScript. Da Sie ständ ig Daten an den Objective-C-Teil von

QuickConnectiPhone-Anwendungen übergeben und von dort empfangen, müssen Sie

mit der API dieser Bibliot hek vertraut sein.

A.2 ABSCHNITT 2 : EINE JSON-API FÜR JAVASCRIPT

Die in Tabelle A.1 vorgestellte API J son2 ist sehr einfach und überschaubar. Sie besteht aus

nur zwei Funktionen. Die eine wandelt ein Objekt oder ein Array in einen String um, die

andere konvertiert Strings in Obj ekte. Die erste dieser Funktionen heißt s tri ng i fy.

213

Page 215: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anhang A Einführung in JSON

Funktion Parameter

JSON. st ri ngify (entity ,

rep l acer ,

space,

l inebrea k )

JSON.pa r se

Erforderliche Parameter:

ent i t y - Das JavaScript-Objekt, -Array oder -Basiselement, das

konvertiert werden soll

Optionale Parameter:

rep l acer-Eine Funktion oder ein Array, mit dem Sie die stan­

dardmäßige Stringerstellung für die mit den Schlüsseln der

JavaScript-Entitäten verknüpften Werte überschreiben können

spa ce-Eine Zahl oder ein Zeichen wie • \ t ' oder &nbsp zur

Einrückung von JavaScript-Entitäten, die als Werte mit Schlüsseln

in anderen Entitäten gespeichert sind

l i neb rea k - Zeichen, die das Standardzeichen • \ n' über­

schreiben, z.B .• \ r \ n 'oder <b r I>

Erforderliche Paramter:

( s tri ng . rev i ver ) s t ri ng - Der JSON-String, der in ein Java-Obj ekt oder -Array

umgewandelt werden soll

Tabelle A.1: Die J son2-API

rev i ve r - Eine Funktion mit dem umgekehrten Verhalten des

Replacers in der Methode st r i ng i fy

Die Funktion st r i ng i f y weist mehrere Parameter auf, aber für QuickConnectiPhone

brauchen Sie nur den ersten. Dabei handelt es sich um das Obj ekt oder Array, das in einen

String umgewandelt werden sol l. Im Folgenden sehen Sie dazu ein allgemeines Beispiel:

var JSONStr i ng = JSON.str i ngify( object ) ;

Die Umwandlung von Strings in Objekte ist genauso einfach:

var object = JSON. parse(someStr i ng) ;

Arrays werden auf genau die gleiche Weise behandelt .

Abbildung A.1 zeigt beispielhaft ein Ergebnis, nachdem ein Objekt in einen String umge­

wandelt, zurück in ein Objekt konvert iert und sein Attributs i ze ausgegeben wurde. Ein

vollständiges Beispiel zu r Verwendung von Json2 zur Stringumwandlung und Analyse

von Objekten fi nden Sie im Beispiel JSONData Examp l eim Verzeichnis iPhone Examples/ JSONDataExample des QuickConnectiPhone-Downloads. Dieses Beispiel zeigt sehr an­

schau lich das Zusammenspiel von JSON und AJAX. Es lädt in JSON verpackte Serverdaten

214

Page 216: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Eine JSON-API für JavaScript

und konvertiert diese dann schlussendl ich in JavaScript-Objekte und stellt diese dar. Mehr

Informationen zu diesem Beispiel finden Sie unter http:llquickconnect.pbworks.com/AJAX­and-JSON, -A-Qu ickConnect-exa mple.

()Q() obj ectj SON_example.htm l

~ ~ fi le:{{{Users{leebarney/Docu ments/bo -(~· Google ~ »

CD JavaDocs Sourceforoe ... ickConne:ct »

Serialized

{"sizc·•:4 .7,"couot'·:3}

inflatedObjects' size

4.7

h

~ Abbildung A.1: Das Ergebnis nach der String­

umwandlung und Rückkonvertierung eines Objekts

ln JSONData Examp l e finden Sie auch ein Beispiel zu Arrays, das zeigt, w ie Sie Arrays mit

J son2 in einen String umwandeln und zurückkonvertieren.

Für beide Anwendungsfä lle werden die üblichen Begriffe serialize (seria lisieren) und infla­te (wörtlich »aufblasen«, also erweitern) für die Ergebnisse der Funktion st r i ng i fy bzw.

parse verwendet.

M it der Bibliothek J son2 können Sie auch Basisele­

mente (Primitives) wie Zah len übergeben. Auch Strin­

gobjekte werden korrekt gehandhabt. Dies gi lt j edoch

nicht für al le JSON-Bibliotheken in al len Sprachen. Mit

der Bibl iothek J son2 können Sie beliebige Elemente

korrekt in Strings umwandeln und zurückkonvertieren.

Auch die JSON-Bibliothek für Objective-C handhabt

Primitives und Strings richtig.

~ Abbildung A.2: Eine Liste von Vorschaubildern erstellt mit

JSON und AJAX im JSONDataExample

215

Page 217: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anhang A Einführung in JSON

A.3 ZUSAMMENFASSUNG

JSON ist eine wunderbare Möglichkeit zur Übergabe von Informationen und völl ig unab­

hängig von Gerät, Betriebssystem und Sprache. Es gibt kostenlose Open-Source-Parser für

alle üblichen Sprachen. Bei manchen Sprachen (z.B. PHP) ist ein solcher Parser sogar im

Lieferumfang enthalten.

Die in QuickConnectiPhone entha ltene Bibliothek Js on2 ist einfach zu verwenden und

ermöglicht es Ihnen, Daten an den Objective-C-Teil einer hybriden Web-App zu senden

und von dort zu empfangen.

216

Page 218: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Evolution von QuickConnectFamily

Da sich Qu ickConnectiPhone noch in einem frühen Entwicklungsstadium befindet, un­

terliegt es häufigen Änderungen. Daher ist es sehr w ichtig, die Entwicklung zu beobach­

ten, um keine Aktualisierung zu verpassen. Tabelle 8.1 zeigt, was am 22. Februar 2010 zum

Download zur Verfügung stand. Mehr Informationen und die aktuellste Fassung der Road­

map finden Sie auch unter http:llquickconnect.pbworks.com!Porting-Roadmap.

Ja bedeutet, dass das betreffende Merkmal im Lieferumfang enthalten ist, ln der Entwick­

lung heißt, dass zurzeit an der betreffenden Funktion gearbeitet wird. Eine Funktion mit

dem Vermerk Entwicklung geplant ist möglich, aber noch nicht in der Entwicklung. Dagegen

bedeutet Nicht möglich, dass die betreffende Funkt ion auf dem Gerät nicht zur Verfügung

steht. Nur mit einem Strich versehene Tabellenzel len zeigen an, dass zum Zeitpunkt der

Drucklegung dieses Buches noch nicht an dem betreffenden Merkmal gearbeitet wird.

HINWEIS

Windows und Windows Mobile sind in Tabelle 8.1 nicht aufgeführt, da die Entwicklung

dafür zwar geplant ist, zurzeit aber noch nichtsdarangetan wird.

Page 219: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anhangs Evolution von QuickConnectFamily

iPhone Android Mac linux Symbian

Geoortung Ja Ja Nicht Nicht

möglich möglich

Besch Ieu nigungs- Ja Ja ln Ent-

messer wicklung

Vibration Ja Ja Nicht Nicht

möglich möglich

Ad-hoc-Netzwerke Ja Entwick- Ja Entwick- Entwick-

lung lung lung

geplant geplant geplant

JavaScript-Datenbank- Ja Ja Ja Ja ln Ent -

w rapper (SQLite) w icklung

Wrapperfü r Ja Ja Ja Ja ln Ent -

installierte native w icklung

Datenbank (SQLite)

AJAX-Wrapper Ja Ja Ja Ja ln Ent -

w icklung

Drag&Drop- Ja Entwick- Ja

Bibliothek lung

geplant

Netzwerk über Entwick- Entwick-

Synchron isierungs- lung lung

kabel geplant geplant

Kamerazugriff ln Ent - Ja

wicklung

Geoortung in ln Ent -

Bildern wicklung

Systemsounds Ja Ja Ja Entwick- Entwick-

(abspielen) lung lung

geplant geplant

Audiodateien Ja Ja Ja Entwick-

auf nehmen/ lung

abspielen geplant

218

Page 220: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Definitionen

Native Datums-/ Ja Nicht Nicht Nicht Nicht

Uhrzeitauswahl möglich möglich möglich möglich

Eingebettete Ja ln Ent- Ja Entwick- Entwick-

Google-Ka rten wiekJung Jung lung

geplant geplant

Diagramme und Ja ln Ent- Ja ln Ent- ln Ent-

Grafiken wiekJung wiekJung w iekJung

Tabelle 8.1: Stand der QuickConnectFamily-Entwicklung am 23. Februar 2009

8.1 Definitionen

Geoortung - Abruf der aktuellen GPS-Koord inatendaten

Beschleunigungsmesser - Abruf der Änderungen an der Geräteausrichtung in x-, y- und

z-Koord inaten

Vibration - Lässt das Gerät vibrieren

Ad-hoc-Netzwerke - Sucht nach anderen Geräten in der Nähe, die dieselbe Anwendung

ausführen, und kommuniziert mit ihnen

JavaScript-Datenbankwrapper (SQLite) - Verwendung der integrierten HTML s-Daten­

bank

Wrapperfür installierte native Datenbank (SQLite)-Verwendung der mit der Anwendung

ausgel ieferten SQLite-Daten ba n k

AJAX-Wrapper - Eine einfach zu verwendende AJAX-Bibl iothek für den Abruf von Daten

über das Netzwerk

Drag&Drop-Bibliothek - Eine einfach zu verwendende Bibliothek, über die der Benutzer

Bildschirmelemente versch ieben, drehen und in der Größe ändern kann

Netzwerk über Synchronisierungskabel - Greift über das Synchronisierungskabel auf den

Desktopcomputer zu und überträgt darüber Daten

Kamerazugriff -Aufnahmeund Speicherung von Bildern

Geoortung inBildern -Greift auf Geoortungsdaten zu, die in den mit dem Gerät aufge­

nommenen Bi ldern eingebettet sind

Systemsound (abspielen) - Gibt kurze Klänge wieder (weniger als fünf Sekunden)

Audiodateien aufnehmen/abspielen - Nimmt Aud iodateien mit dem Gerät auf und gibt

diese sowie mit der Anwendung ausgelieferte Audiodateien w ieder

219

Page 221: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Anhangs Evolution von QuickConnectFamily

Native Datums-/ Uhrzeitauswahl - Zeigt die Objectice-C-Eiemente zur Datums- und Uhr­

zeitauswah l statt der eingeschränkten JavaScript-Varianten an

Eingebettete Google-Karten - Zeigt in Ihrer Anwendung statt der Standardkarten benut­

zerdefinierte Google-Karten oder die Map-Anwendung an

Diagramme und Grafiken - Eine einfach zu verwendende Bibl iothek zur Anzeige von Lini­

en-, Balken-, Torten- und anderen Diagrammen

220

Page 222: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Stichwortverzeichnis

Stichwortverzeichnis

A abort 199 accel 107 ADC (Apple Developer

Connection) 26 add 46 Anonyme Funktionen 160 Ansichten 73 Ansichtsanwendungs-

controller 58 Anweisungen, vorbereitete 156 Anwendungen

BrowserAJAXAccess 188 BrowserDBAccess 149 Dialogfeld Alert 19 Immersionsanwendungen 8o m it nicht listengest ützter

Ansicht 75 Anwendungscontroller so Anzeige

Auswahlfelder 110 Karten in QuickConnect­

JavaScript-Anwendungen 129 API f ür Drag&Drop/Skalierung/

Drehung 91 application DidFin ish­

launching 31 Arrays

Erstellen 212 ln 5trings konvertieren 214 passThroughParameters 161 retVal 183

Asynchron 59 Aufnahmen

Beenden 10 8 Wiedergeben 108

Auswahlfe lder Anzeigen 110 Objective-C 120

8 BCFs (Business Control

Functions) 44 Benutzereingaben validieren 44 Berührbare Bilder 75 BrowserAJAXAccess 188 BrowserDBAccess 149 Business Control Functions

(BCF) 44

c calculateSolutionsBCF 47 caiiFunc 62 changeView 73 checkNumbersVaiCF so check5ecurity 207 code (Attribut) 168 (55-Transformationen 82 cube 78

D Dashcode

QuickConnectiPhone­Vorlage 17

Übergänge 76 Verzeichnisse 24

DataAccessObject 152 Beispielcode 170 Database-Objekt 162 dbAccess 161 generatePassThroughPara-

meters 161 getData 161 Met hoden 152 Native 5Qlite-Daten-

banken 157 passThroughParameters­

Array 162 setData 161 5QLError-Objekt 167

5QLResult5et-Objekt 166 5QLResult5etRowlist 166 5QLTransaction-Objekt 164 WebKit -Datenbanken 159

DataAccessObject.js 152 Database-Objekt 162 Dateien

DataAccessObj ectjs 152 Kopieren 23 5erverAccessObject.js 192

Datenabruf 44 Datenbankfelder 150 Datenbankzugriff

Beispielcode 170 BrowserDBAccess 149 Database-Objekt 162 Datenbankterminologie 150 dbAccess 161 generatePassThroughPara-

meters 161 getData 161 getDeviceData 172 getNativeData 172

makeCa ll 173 Native Datenbanken 172 Native 5Qlite-Daten-

banken 157 passThroughParameters-

Array 162 5endDBResultVCO-Objekt 182 setData 161 setNativeData 172 5QLError-Objekt 167 5Qlite3-APJ 175 5QLResult5et-Objekt 166 5QLResult5etRowlist 166 5QLTransaction-Objekt 164 Überblick 149 WebKit-Datenbanken 151, 159

Datensätze 150

Page 223: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Stichwortverzeichnis

Datenzugriff über das Netzwerk BrowserAJAXAccess 188 displaySiteDataVCF 193 getData 190, 197 getSiteDataBCF 192 makeCall 197 onreadystatechange 204 SCF (Security Control

Functions) 208 ServerAccessObject 190 setData 191, 197 Überblick 187 XMLHttpRequest-Objekt 202

dbAccess 161,169 Delegates 29 deleteScoreBCF 157 Dialogfeld Alert 19 dispatchToBCF 58 dispatchToECF 64 dispatchToVaiCF 54 dispatchToVCF 62 displayScoresVCF 155.158 displaySiteDataVCF 193 dissolve 77 doCommand 117,124, 135,183 DollarStash 81 done 87 dragAndGesture 91 Drag&Drop 69

Hüpfende Elemente 84 Module 90

Drehfunkt ionen 89 Drehu ng 94

E ECF (Error Control Functions) 47 Einbetten

Google Maps 129 Webinhalt (QuickConnect-

iPhone) 33 Elemente (Bibliot hek) 71 entryECF 47 Entwicklungsstand

QuickConnectiPhone 217 Entwicklungswerkzeuge

QuickConnectiPhone 217 eval 51,212 executeSQL 164,169

222

F fade 78 Feh leranwendungscontroller 63 flip 78 Fra meworks 42 Fremdschlüssel 150 FrontController-API 45 Funktionen

G

Anonyme Funktionen 160 SCF (Secu rity Control

Functions) 208

generatePassTh roughPa ra­meters 161

Geräteaktivierung JavaScript 103 Objective-C 110

Gesten 69, 87 Gestu reEvent 87 getAIIResponseHeaders 199 getData 153,154.161,190,197 getDeviceData 172 getGPSLocation 109 getlnstance 120 getNativeData 153.158.172 getResponseHeader 199 getSiteDataBCF 192 goForward 74 Google-Karten anzeigen 129 goSub 75 GPS

JavaScript 109 Objective-C 116

Gruppen (Xcode) 23

H hand leRequest 45,53 ha nd leReq uestCom pletion From­

Native 184 HIG (Human Interface

Guide) 68 HistoryExam ple 71 Hüpfende Elemente 84

Immersionsanwendungen 8o lnfoWlndow 134,147 initWithFrame 135 insertiD 166 lnstanziierung 27 isOraggable 93 item 167

J JavaScript

Geräteaktivierung 104 Modularität 41 scroll 138

JSON (JavaScript Object Notat ion) 108, 196 Json2-API 214 Überblick 211

Json2-API 214 JSONStringify 183

K Ka rten

ln QuickConnect-JavaScript­Anwendungen anzeigen 129

QuickConnect-Karten-modul 134

Vergrößern 142 Klassen

DataAccessObject-Methoden 152

Native SQLite-Daten-banken 157

QuickConnectView-Controller 33

Singleton-Klassen 120 SQLiteDataAccess 175 WebKit -Daten banken 159

Konvertierung zwischen Objekten und Strings 214

Kopieren von Dateien 23

L length 167 Listengestützte Schnittst ellen 71 loadView 34

Page 224: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

M makeCall 104,173,197 makeChangeable 90,93 makeDraggable 90 mapCommands 114 mapCommandToCo 126 MapView 134 math 46 Medizinische Bildgebungs­

anwendungen 8o message 168 Modularität

Beispiel für das JavaScript­Framework QuickConnect 43

Implementierung in Quick­ConnectiPhone 53

JavaScript 41 Steuerfunktionen 44

Module Definition 42 Drag&Drop 90 Drehung 94 Skalierung 94

moveX\ andY 144

N Native Datenbanken 172

getDeviceData 172 getNativeData 172 makeCall 173 SendDBResultVCO-Objekt 182 set NativeData 172 SQUte3-API 175 SQLite-Datenbanken 157

NSlog 125

0 Objective-C 26

Auswahlfelder 120 Geräteaktivierung 111

Objekte instanziieren 27 QuickConnectiPhone-

Anwendungsstruktur 29 QuickConnect iPhone­

Architektur 120 QuickConnect-Karten­

modul 134

Objekte Erstellen 213 lnstanziieren 27 in Strings konvertieren 214 Strings in Objekte

konvertieren 214 oldScale 93 ongesturechange 99 onreadystatecha nge 201, 204 ontouchchange 85 open 200 openDatabase 162

p parse 214 passThroughPara meters­

Array 162 pathForResource

ofType 36 Pin 134,139 play 105 playSound 105 prepareDrag 94 prepareGest ure 98 Primärschlüssel 150 Prinzipai-Delegate-Beziehung 29 Prinzipale 29 Protokolle 30 Provisioning 26 Proxys 29 push 77

Q QCCommandObject 124 QuickConnect

Karten anzeigen 129 Modularität 42

QuickConnectFamily-lnstaller 18 QuickConnectiPhone

Entwicklungsstand 217 Modu lares Design 53 Objective-C -Anwendungs-

struktur 29 Objective-C­

Implementierung 120 Webinhalt einbetten 33

QuickConnectiPhone-Vorlagen Dashcode 17 Xcode 21

QuickConnect-Kartenmodul 134 Qu ickConnectViewControl ler 33

Stichwortverzeichnis

R readyState 201 Rekursion 62 requestHandler 207 responseText 202 responseXML 202 retVal-Array 183 revolve 78 rows 166 rowsAffected 166

s SCF (Security Control

Functions) 208 Schalter 70 Schnittstel len

Ansichten 73 CSS-Tra nsformationen 82 listengestützte Schnitt-

stellen 71 scroll 138 Security Control Fundions

(SCF) 208 send 201 SendDBResultVCO-Objekt 182 sendloc 118 ServerAccessObject 190

displaySiteDataVCF 193 getData 190, 197 getSiteDataBCF 192 makeCall 197 Methoden 192 onreadystatechange 204 setData 191, 197 XM LHttpRequest-Objekt 202

ServerAccessObject.js 192 setData 153, 161,191, 197 setMapLatlngFrameWith-

Description 146 setNativeData 153, 172 SetReq uestHeader 201 setStartlocation 85 shouldStartl oadWithReq uest 111

showDateSelector 110 showMap 132 showPickResults 110 Singleton-Klassen 120 singleTouch 140 Skalierung 94 slide 77

223

Page 225: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript

Stichwortverze.:ic::.:h::n.::is ____________________ __

SQLError-Objekt 167 SQlite3-API 175 sqlite3_bind_blob 178 sqlite3_bind_double 178 sqlite3_bind_int 179 sqlite3_changes 176 sqlite3_close 175 sqlite3_column_blob 177 sqlite3_column_bytes 177 sqlite3_column_count 176 sqlite3_column_double 177 sqlite3_column_int 177 sqlite3_column_name 176 sqlite3_column_text 177 sqlite3_column_type 176 sq lite3_ errmsg 175 sqlite3_ finalize 178 sqlite3-0bjekt 175 sqlite3_open 175 sqlite3_prepare_v2 176 sqlite3_step 176 sqlite3_stmt 175 SQliteDataAccess 175 SQlite-Datenba nken

Beispielcode 170 Database-Objekt 162 dbAccess 161 generatePassThroughPara-

meters 161 getData 161 Native SQlite-Daten­

banken 157 passThrough Parameters-

Array 162 setData 161 SQLError-Objekt 167 SQLResultSet-Objekt 166 SQLResultSetRowlist 166 SQLTra nsaction-Objekt 164 WebKit-Datenbanken 151,159

SQLResultSet-Objekt 166 SQLResultSetRowlist 166 SQLTransaction-Objekt 164 Standardverhalten 69 status 202 statusText 202

224

Steuerfunktionen 44 stri ngByEva I uati ngJ ava Scri pt-

FromString 184 stringify 213 Strings konvertieren 214 Subviews 72 swap 78 Synchron 59 Systemsounds

T

ln Objective-C abspielen 115 JavaScript 104

Tabellen 150 terminatePiaying 108 touch 83 Touch 83 touchesBegan 142 touchesMoved\

withEvent 137.145 transaction 163,169 Transformationen 82 translate 86

u Übergänge 76 UIWebView

API 35 Klasse 33

Unteransichten 35 Unternehmensanwendungs­

controller s8

V VaiCF (Validation Control

Functions) 44 VCF (View Control Functions) 44 Verschiebung 99 Verzeichnisse 24 Vibrationen 105, 112 Vorbereitete Anweisungen 156 Vorlagen

Dashcode 17 QuickConnectiPhone 21

w WebKit-Datenbanken 159

Beispielcode 170 Database-Objekt 162 dbAccess 161 generatePassThroughPara-

meters 161 getData 161 passThroughPa rameters-

Array 162 setData 161 SQLError-Objekt 167 SQLResultSet-Objekt 166 SQLResultSetRowlist 166 SQLTransaction-Objekt 164

webKitTransform 83 webMapView 136 Wiedergabe

X

Aufnahmen 108 Systemsounds 115

Xcode Gruppen 24 QuickConnect-Vorlagen 21

XMLHttpRequest 199

z Zeiger 26 Zoom in Karten 142 Zukünftige Entwicklung

QuickConnectiPhone 217

Page 226: Dynamische iPhone-Anwendungen entwickeln. Anwendungsentwicklung mit HTML, CSS und JavaScript