iphone-app-entwicklung: Technologien, Webservice-Integration und App-Store-Anbindung

Größe: px
Ab Seite anzeigen:

Download "iphone-app-entwicklung: Technologien, Webservice-Integration und App-Store-Anbindung"

Transkript

1 Abschlussarbeit zur Erlangung des akademischen Grades Bachelor of Science (B.Sc.) iphone-app-entwicklung: Technologien, Webservice-Integration und App-Store-Anbindung Referent: Prof. Dr. Alois Schütte Korreferentin: Prof. Dr. Bettina Harriehausen-Mühlbauer Benjamin Glatzel Dominik Wilhelm Juli 2010

2

3 Erklärung Wir versichern hiermit, dass wir die vorliegende Arbeit selbständig verfasst und keine anderen als die im Literaturverzeichnis angegebenen Quellen benutzt haben. Alle Stellen, die wörtlich oder sinngemäß aus veröffentlichten oder noch nicht veröffentlichten Quellen entnommen sind, sind als solche kenntlich gemacht. Die Zeichnungen oder Abbildungen in dieser Arbeit sind von uns selbst erstellt worden oder mit einem entsprechenden Quellennachweis versehen. Diese Arbeit ist in gleicher oder ähnlicher Form noch bei keiner anderen Prüfungsbehörde eingereicht worden. Darmstadt, den 02. Juli 2010 Benjamin Glatzel Dominik Wilhelm III

4

5 Zusammenfassung Apples iphone hat sich zu einem der meist genutzten und begehrtesten Smartphones entwickelt und der App Store, die offizielle Vermarktungsplattform für iphone-applikationen, erfreut sich stetig wachsender Beliebtheit. Die Entwicklung von sogenannten Apps 1 ist somit nicht nur für Freizeitentwickler, sondern ebenso für Firmen von großer Bedeutung. Die vorliegende Arbeit betrachtet und analysiert zentrale Elemente der iphone-entwicklung. Die Themenschwerpunkte richten sich hierbei nach den Erfahrungen, die bei der Entwicklung der Buchungsapplikation wetravel gesammelt wurden. Zusätzlich werden Implementierungsschwerpunkte der zugehörigen Webapplikation wetravel online dargestellt und Möglichkeiten zur Bereitstellung einer leichtgewichtigen Webserviceschnittstelle für die iphone-applikation analysiert. Für die Webapplikation und die Webserviceschnittstelle wird das moderne Web-Application-Framework Ruby on Rails vorgestellt und hinsichtlich der Eignung für den Projekttyp evaluiert. Abschließend wird ein Konzept zur Integration einer Kauffunktionalität in die iphone- Applikation vorgestellt, das mithilfe des von Apple bereitgestellten Framework Store Kit einen möglichst sicheren Erwerb von Abonnements als Nutzungsberechtigung für die zugehörige Webapplikation ermöglichen soll. 1 Apples Synonym für iphone-applikationen. V

6

7 Inhaltsverzeichnis Tabellenverzeichnis Abbildungsverzeichnis XI XIII 1. Einleitung und Motivation 1 2. Technische Grundlagen Das iphone als Entwicklungsplattform Technische Ausstattung der aktuellen Gerätegeneration Das Betriebssystem iphone OS Die Architektur des iphone SDK Wertschätzung von Entwurfsmustern bei der Entwicklung Ruby on Rails als Framework zur Entwicklung von Webapplikationen Zentrale Prinzipien des Framework Ruby on Rails Zentrale Technologien des Framework Ruby on Rails Modernen Techniken im Umfeld des Web Strukturelle Grundlagen zu wetravel und wetravel online Struktur der iphone-applikation wetravel Struktur der Webapplikation wetravel online und des zugehörigen Webportals Betrachtung der Programmiersprache Objective-C Syntaktische Besonderheiten der Programmiersprache VII

8 Inhaltsverzeichnis 4.2. Objective-C als dynamische Programmiersprache Objektorientierte Konzepte in Objective-C Message-Forwarding als Alternative zu Mehrfachvererbung Abstrakte Klassen und Interfaces Funktionale Erweiterung von Klassen ohne Vererbung Stellenwert des Foundation-Framework Fazit Persistierung von Anwendungsdaten Gegenüberstellung verschiedener Techniken zur Persistierung von Daten Nutzung einer Dateistruktur Nutzung der Extensible Markup Language Nutzung von SQLite zur Persistierung von Datenstrukturen Das Framework Core Data Das Framework Core Data im Vergleich zur SQLite-API Initialisierung einer Datenbankverbindung Abruf von Datensätzen Hinzufügen von Datensätzen Änderungen von Datensätzen Löschen von Datensätzen Der Umgang mit Relationen Migration und Versionierung mithilfe des Core-Data-Framework Optimierung des Datenmodells und des Persistenzmanagers Faultingverhalten Auslagerung von Binärdaten Intelligente Relationen Weitere Optimierungen Fazit Entwicklung und Optimierung von iphone-applikationen Diskurs der Softwarearchitektur Entwicklung einer Designgrundlage für Tabellenansichten Generierung eigener Objekt-IDs mithilfe einer Basisklasse Erstellung einer Schnittstelle zur Datenbankkommunikation Entwicklung einer generalisierten Eingabemaske Bereitstellung einer Klasse für die Serverkommunikation Nutzung des Lokalisierungsmechanismus des Foundation-Framework Techniken zur Generierung von grafischen Effekten Generierung eines Spiegelungseffekts mithilfe von Core Graphics 71 VIII

9 Inhaltsverzeichnis Perspektivische Ausrichtung der Grafik mithilfe des Core-Animation-Framework Optimierung von iphone-applikationen Implementierung eines Cachingsystems Bereitstellung effizienter Tabellenzellen Entwicklung erweiterter Tabellenzellen Erstellung einer funktionsreduzierten Programmversion Anforderungen an die Software hinsichtlich des Apple-Review-Prozesses Fazit Leichtgewichtige Webentwicklung und Webservice-Integration Das Web 2.0 als Evolutionsstufe des Internets Prinzipien und Praktiken im Umfeld des Web Bereitstellung leichtgewichtiger Entwicklungsmodelle Ruby on Rails als Hilfsmittel bei der Entwicklung von Web-2.0-Applikationen Vertiefung des Konzepts der Webapplikation wetravel online Einsatz und Verwendung von Buchungsreporten Generierung von Statistiken mithilfe der Google Chart API Integration der PDF-Bibliothek Prawn Techniken zur Benutzerauthentifikation Bereitstellung des Authentifikationsmechanismus für die AJAX- Anmeldemaske Absicherung der Benutzerauthentifikation Entwicklung einer dynamischen Anmeldemaske mit jquery Techniken zur Bereitstellung multilingualer Webapplikationen Verbindung von iphone- und Webapplikation Bereitstellung einer Webserviceschnittstelle Sicherheitstechnische Analyse des Kommunikationsprozesses Betrachtung von REST als alternative Webservice-Architektur Fazit Integration von In-App-Purchases in iphone- und Webapplikation Einführung in das grundlegende Konzept zum Abschluss von Abonnements Nutzung und Integration des Store-Kit-Framework Abruf von In-App-Purchase-Produkten Integration der Kauffunktionalität für In-App-Purchases Bereitstellung der serverseitigen Abonnementfunktionalität Erfassung von Interessentenstatistiken Fazit IX

10 Inhaltsverzeichnis 9. Schlussbetrachtung 157 Appendices 163 A. Bildschirmfotos von wetravel und wetravel online 163 B. Listings 175 C. Literatur 179 X

11 Tabellenverzeichnis 7.1. Unterstützung des W3C-DOM-Standards im Vergleich XI

12

13 Abbildungsverzeichnis 2.1. Die einzelnen Bibliotheken des iphone SDK sind in Schichten organisiert Die bei der Entwicklung von iphone-anwendungen zum Einsatz kommende Form des MVC-Patterns Die gebräuchliche Form des MVC-Patterns sieht eine direkte Kommunikation zwischen View und Model vor Die Infrastruktur des Projekts wetravel Erzeugung eines globalen Designs durch die Einführung einer Superklasse für sämtliche View-Controller Vereinfachte Darstellung des wetravel-datenmodells Gruppierte Darstellung sämtlicher Controllerklassen der Rails-Applikation Das Datenmodell der Webapplikation Der sogenannte Core Data Stack Reduzierte Abbildung der Exkursions- und Buchungsklasse Reise- und Buchungsklasse nach Auslagerung des Bildes Verbindung einer Variablen mit einem GUI-Element Vererbung des Tabellendesigns und Verhaltens an alle Views Die individuellen Kopfzeilen und Zellen in Verbindung mit der Darstellung einer Hilfsnachricht im Vergleich zu einer normalen Tabelle Von WTBase erbende Entitäten Eingabemasken für Texte und Datumsangaben XIII

14 Abbildungsverzeichnis 6.6. Nutzung einer vereinfachten Form des Observer-Patterns für den Entwurf der Serverkommunikationsklasse Erzeugung eines Grafikeffekts, welcher der Darstellungsform Cover Flow ähnelt Cover-Flow-Ansicht innerhalb des Dateimanagers Finder der Firma Apple Eine Tabellenzelle, die ein generiertes Bild zu Darstellung eines angehängten Buchungsbildes nutzt Verdeutlichung des Transformationsprozesses zur Erzeugung des Spiegelbildes Maskierung des Spiegelbildes mit einem graustufigen Verlauf Core Animation nutzt intern eine orthogonale Projektion zur Abbildung Gegenüberstellung von perspektivischer und orthogonaler Projektion auf die Ebene z = Struktureller Aufbau einer UITableViewCell Entwurf einer Basisklasse zur effizienten Darstellung von angepassten Tabellenzellen Konzept zur Ausrichtung von Tabellenzellen in Abhängigkeit zum aktuellen Zellenstatus Zwei Ansätze zur Darstellung von kontextbezogenen Informationen und Optionen Genereller Aufbau und Interaktionsmöglichkeiten der Beispielzelle Fläche zur Eingrenzung der erlaubten Werte der Variablen x und y zur Bestimmung einer horizontale Fingerbewegung auf dem Display Buildkonfiguration für eine Lite-Version Das Analysewerkzeug Instruments Navigationsübersicht zum strukturellen Aufbau von wetravel online Screenshot des internen Bereichs von wetravel online Die Klasse Trip bündelt sämtliche zugehörigen Berechnungsmethoden Ein mit den Google Chart Tools generiertes Kuchendiagramm Die Klasse User kapselt sämtliche Funktionalität für die Authentifizierung Der zugrunde liegende Ablauf bei der AJAX-Authentifikation Screenshot der Anmeldemaske von wetravel online Die Klasse ApiController dient als Schnittstelle zur Kommunikation mit der iphone-applikation Ablauf zur Freischaltung eines innerhalb der iphone-applikation erworbenen Abonnements Ablauf zu Ermittlung von In-App-Purchase-Produkten Der Kauf eines In-App-Purchase-Produkts XIV

15 Abbildungsverzeichnis 8.4. Die für die Bereitstellung der Kauffunktionalität erweiterte Controllerklasse ApiController Die Entitätsklasse zur Speicherung der Transaktionsquittungen innerhalb der Datenbank Exemplarische Implementierung einer Interessentenstatistik mit geografischer Zuordnung der Herkunftsländer A.1. Bildschirmfotos der iphone-applikation wetravel A.2. Weitere Bildschirmfotos der iphone-applikation wetravel A.3. Weitere Bildschirmfotos der iphone-applikation wetravel A.4. Weitere Bildschirmfotos der iphone-applikation wetravel A.5. Die Anmeldemaske von wetravel online A.6. Die Report-Übersicht ist der Ausgangspunkt nach erfolgtem Login A.7. Ein Buchungsreport ist einer der verschiedenen Darstellungstypen A.8. Die Liste zur Auswahl von Teilnehmern zum Versand von Rechnungen und zur Darstellung von Rechnungsvorschauen A.9. Ein Kuchendiagramm als Beispiel für die Integration einer Statistik mithilfe der Google Chart Tools A.10.Die Einstellungen für Benutzer von wetravel online A.11.Die Kontenübersicht für Administratoren von wetravel online A.12.Statistische Übersicht samt geografischer Zuordnung für Administratoren von wetravel online XV

16

17 KAPITEL 1 Einleitung und Motivation Seit der Einführung im Jahre 2007 hat sich das iphone der Firma Apple schnell zu einem der meistbenutzten und begehrtesten Smartphones entwickelt. In nur drei Jahren konnte mit einem einzigen Endgerät weltweit ein Marktanteil von über 15 % erreicht werden (siehe [Can10]). In Amerika benutzen 21 % aller Smartphonebesitzer ein iphone und in direkter Konkurrenz steht nur Googles Betriebssystem Android, das seit neuesten Statistiken auf 28 % aller Smartphones eingesetzt wird (siehe [NPD10]). Über den App Store, Apples zentrale Vermarktungsplattform für iphone-applikationen, wurden bis heute über vier Milliarden 1 Apps bezogen und es stehen über Applikationen zur Verfügung (siehe [App10c]). Das iphone ist somit in kurzer Zeit zu einer rentablen Vermarktungsplattform für Applikationen geworden und viele Firmen legen großen Wert auf die Entwicklung von Apps. Den Erfolg verdankt das Gerät nicht nur einer ausgeklügelten Marketingstrategie, sondern auch der Einführung eines neuen Bedienkonzeptes. Bis zum Erscheinen des iphone mussten die sogenannten Smartphones stets mit einem Stift und höchster Präzision bedient werden. Das iphone hingegen Autoren: Benjamin Glatzel Dominik Wilhelm 1 Stand Anfang April

18 1. Einleitung und Motivation wird dank moderner Multi-Touch-Technologie 2 nur über die Fingerspitzen bedient. Die Aussage von Steve Jobs, dass das iphone... jedem anderen Mobiltelefon um buchstäblich fünf Jahre voraus ist... (siehe [App07]) hat sich bis heute bewahrheitet. Mit dem iphone wurde eine neue Generation von mobilen Endgeräten eingeleitet und die Entwicklung für diese ist mit vielen neuen Herausforderungen verbunden. In der vorliegenden Arbeit werden zum einen die Entwicklung einer modernen iphone- Applikation und die hiermit verbundenen Besonderheiten, Technologien und Probleme kritisch beleuchtet. Zum anderen sind die Entwicklung und Integration einer zugehörigen Webapplikation mit Ruby on Rails sowie die Evaluation des Framework hinsichtlich der Eignung für das Projekt zentraler Bestandteil der Arbeit. Abschließend wird die Integration einer Kauffunktionalität mithilfe des von Apple bereitgestellten Framework Store Kit diskutiert und die hierzu nötigen Schritte und Technologien hinsichtlich der Integration in die iphone- und Webapplikation analysiert. Die Arbeit basiert auf den Erfahrungen und Ergebnissen, die bei der Entwicklung der iphone-applikation wetravel gesammelt wurden. wetravel ist eine Buchungsapplikation, die sich besonders für Leiter von Gruppenreisen eignet und für die Aufteilung von Buchungsbeträgen unter einer Vielzahl von Personen konzipiert wurde. Neben der Basisfunktionalität wurde eine Webapplikation entwickelt, die die Applikation auf dem mobilen Endgerät um zusätzliche Funktionen erweitert. Diese ist unter dem Namen wetravel online bekannt und kann über die iphone-applikation kostenpflichtig für drei Monate freigeschaltet werden. wetravel und der zugehörige Onlinedienst sind seit Mai 2010 im App Store erhältlich. Eine markttechnische Analyse von Verkaufsstrategien und deren Auswirkungen auf den Verkaufserfolg der Applikation ist nicht Bestandteil dieser Arbeit. Die folgenden Kapitel behandeln zunächst die Grundlagen, die für das Verständnis der Arbeit von Nöten sind. So werden Details zu den eingesetzten Plattformen sowie den Architekturen und der Struktur der iphone- und Serverapplikation offengelegt. Im Kern dieser Arbeit wird in Kapitel 4 zu Beginn die Programmiersprache Objective- C, die zur Entwicklung von iphone-applikationen verwendet wird, im Vergleich zur weitverbreiteten Programmiersprache C++ analysiert. Hierbei werden besonders die dynamische Natur der Sprache sowie die integrierten objektorientierten Konzepte 2 Eine Eingabemethode, die Berührungen an mehreren Punkten gleichzeitig erkennen und auswerten kann. 2

19 gegenübergestellt. In Kapitel 5 wird die Technik zur persistenten Speicherung der Daten mithilfe des Framework Core Data erläutert, Möglichkeiten zur Optimierung des Objektgraphen sowie des Datenmodells beschrieben und die Eleganz des Framework anhand einiger Beispiele demonstriert. In Kapitel 6 steht die Entwicklung einer iphone-applikation im Mittelpunkt. Neben dem Entwurf eines Benutzerinterface, das den sogenannten Human-Interface-Guidelines (siehe [App10j]) von Apple entspricht, wird besonderer Wert auf die Optimierung der Anwendung gelegt, sodass diese auch bei der Darstellung von großen Datenmengen stets ohne Beeinträchtigung der Performanz funktioniert. Hierfür werden einige eigens ausgearbeitete Konzepte, unter anderem ein Caching-System als auch Methoden zur Erzeugung von effizient darstellbaren GUI-Elementen, vorgestellt und hinsichtlich der Integration in eine bestehende Applikation betrachtet. Kapitel 7 behandelt einige Themenschwerpunkte zur Entwicklung und Integration von Webapplikationen in Verbindung mit iphone-applikationen. Hierzu erfolgt zunächst eine Einführung in die Kerngedanken des sogenannten Web 2.0, die im weiteren Verlauf des Kapitels als Orientierungspunkt für die Entwicklung dienen werden. In Kapitel 8 wird die Integration der Kauffunktionalität in die iphone- und Webapplikation behandelt und besonders die Absicherung des Vorgangs vertieft. Zudem wird eine Möglichkeit zur Erfassung von Statistiken zu einer im Verkauf befindlichen iphone- Applikation erarbeitet. Im letzten Kapitel dieser Arbeit werden die Ergebnisse und Erfahrungen zusammengefasst und das Projekt auf Erfolg, Schwächen und Grenzen geprüft, gefolgt von einem Ausblick, der die zukünftige Bedeutung des Projektes und der verwendeten Technologien betrachtet. Die vorliegende Arbeit wurde von zwei Autoren verfasst. Die Zusammenfassung, die Einleitung, die Grundlagen-Kapitel (siehe Kapitel 2 und 3) und die Schlussbetrachtung wurden gemeinsam verfasst. Die Autoren sämtlicher Abschnitte des Hauptteils sind in Form von Randnotizen angegeben. Nach Nennung des Autors ist dieser bis zum erneuten Auftreten einer Randnotiz als Verfasser sämtlicher Textpassagen zu verstehen. 3

20

21 KAPITEL 2 Technische Grundlagen 2.1. Das iphone als Entwicklungsplattform Seit der Einführung des iphone wird eine stetige Steigerung der Verkaufszahlen registriert. Dieser Erfolg ist, neben dem Design des Gerätes, besonders der Kombination von Hardware und dem hierauf abgestimmten Betriebssystem zu verdanken. Dieses Kapitel bietet einen kurzen Überblick über die Hard- und Software des iphone und soll die Grundlagen vermitteln, die zum näheren Verständnis der Entwicklung von iphone-applikationen unverzichtbar sind. Autoren: Benjamin Glatzel Dominik Wilhelm Technische Ausstattung der aktuellen Gerätegeneration Die Firma Apple begann als einer der ersten Hersteller mit der Verwendung von 3,5 Zoll großen, kapazitiven Touchscreens, während die Konkurrenz hauptsächlich resistive Displays verwendete (vgl. zu diesem Abschnitt [App; Ana09]). Als Prozessor nutzt das iphone einen Samsung S5PC100 mit integriertem ARM Cortex A8, der auf 600 5

22 2. Technische Grundlagen MHz getaktet ist. Der zusätzliche PowerVR SGX Grafikprozessor dient zur Steigerung der Performanz bei grafisch intensiven Anwendungen, wie beispielsweise Spielen oder Software zum Abspielen von multimedialen Inhalten. Es stehen 256 MB Arbeitsspeicher und ein Flash-Laufwerk mit bis zu 32 GB Kapazität zur Verfügung. Neben der Nutzung des GSM/EDGE oder auch HSDPA/UMTS Netzes, bietet das iphone die Möglichkeit zur Herstellung von Verbindungen via WLAN oder Bluetooth. Zudem besitzt das Gerät eine integrierte Kamera mit einer maximalen Auflösung von 3 Megapixeln, ein Magnetometer sowie einen GPS-Empfänger Das Betriebssystem iphone OS Hauptmerkmal für den Erfolg ist jedoch das Betriebssystem, welches auf dem in Mac OS X 1 verwendeten UNIX-Betriebssystemkern Darwin aufbaut. Das sogenannte iphone OS, welches nicht nur auf dem iphone, sondern auch auf dem ipod touch und ipad zum Einsatz kommt, bietet dem Nutzer ein intuitives, auf Multi-Touch-Gesten ausgelegtes Bedienkonzept. Das Betriebssystem ist derzeit in Version verfügbar und dient als Grundlage für die in dieser Arbeit beschriebenen Entwicklungsmethodiken. Das Multi-Touch-Konzept erlaubt es beispielsweise mithilfe der Finger listenartige Darstellungsstrukturen in Bewegung zu versetzen sowie Bilder zu vergrößern oder zu verkleinern. Dank des kapazitiven Displays können multiple Kontaktstellen auf dem Display zeitgleich erkannt und verarbeitet werden. Die Verbindung zu der Desktop- Anwendung itunes und der Vertriebsplattform für Applikationen, der sogenannte App Store, sind in das System integriert. Hierüber können Software und Musik direkt auf dem Gerät gekauft und genutzt werden. Der größte Konkurrent des iphone OS ist das von Google entwickelte Betriebssystem Android. Für den Vertrieb von Applikationen wird ebenfalls eine zentrale Verkaufsplattform eingesetzt Android Market genannt. Im Gegensatz zu Apple beschränkt Google die Nutzung des Systems nicht auf die firmeneigenen Geräte. Dieser Vorteil kann jedoch zugleich ein Nachteil sein: Die Adaptierung des Systems durch unzählige Hersteller führt zu einer Steigerung der Anzahl von möglichen Hardware-Konfigurationen, welche die einfache Bereitstellung von Aktualisierungen merklich erschwert. 1 Das Desktopbetriebssystem der Firma Apple. 2 Stand Anfang Juni

23 2.1. Das iphone als Entwicklungsplattform Das von Apple vor Kurzem vorgestellte iphone OS 4 (vgl. zu diesem Abschnitt [App10a]) wird als größte Neuerung ein Multitasking-Konzept bereitstellen und somit viele neue Möglichkeiten für Entwickler und Anwender bieten. Unter den über 100 neuen Funktionen befindet sich auch iads, eine Art mobile Werbeplattform, die den Ertrag von zusätzlichen Werbeeinkünften ermöglicht. Die auf dem ipad vorgestellte Applikation ibooks wird mit dem Erscheinen der Systemaktualisierung für das iphone und den ipod touch verfügbar gemacht Die Architektur des iphone SDK Das von Apple bereitgestellte Software Development Kit (kurz SDK) enthält, neben der Entwicklungsumgebung Xcode und vieler weiterer Entwicklungswerkzeuge, alle für die iphone-entwicklung benötigten Frameworks, die anhand der Funktionalität in Schichten aufgeteilt wurden (vgl. zu diesem Abschnitt [App10k]). Diese Frameworks ermöglichen die Nutzung sämtlicher Hard- bzw. Softwarekomponenten. Cocoa Touch Media Core Services Core OS Abbildung 2.1.: Die einzelnen Bibliotheken des iphone SDK sind in Schichten organisiert. Wie in Abbildung 2.1 dargestellt, bilden diese eine hierarchische Struktur, in der die übergeordneten Schichten auf den Funktionalitäten der Vorangegangenen aufbauen. So beinhaltet der Core-Services-Layer das Foundation-Framework, das sämtliche Objective- C-Basisklassen für die folgenden Ebenen zur Verfügung stellt. Es folgt eine kurze Beschreibung der soeben erläuterten Schichten, während an dieser Stelle auf eine detaillierte Beschreibung verzichtet wird. 7

24 2. Technische Grundlagen Cocoa-Touch- und Media-Layer Der Cocoa-Touch-Layer enthält die Bibliotheken zur Erstellung ereignisgesteuerter Applikationen mit grafischer Benutzeroberfläche. Das hier angesiedelte UIKit-Framework stellt sämtliche zur Anzeige und Eingabe benötigten grafischen Elemente bereit. An dieser Stelle werden zudem High-Level-Frameworks zur Nutzung des Adressbuchs, der Kartenfunktionalität und der Entwicklung von grafisch intensiven Anwendungen gebündelt. Über die Nutzung des Address-Book-UI-Framework kann beispielsweise mittels vorgefertigter Darstellungselemente mit dem systemweiten Adressbuch interagiert werden. Der Media-Layer bündelt jene Frameworks, die zur Implementierung und Verwendung multimedialer Inhalte notwendig sind. Core Services und Core OS Layer Die Core Services bündeln die nötige Basisfunktionalität für die Entwicklung von Anwendungen. Wie bereits erwähnt, zählt das Foundation-Framework zu diesen Diensten. Diese Ebene enthält zudem sämtliche Klassen zur Datenspeicherung und Netzwerkkommunikation sowie das sogenannte Store-Kit-Framework, welches die Integration von sogenannten In-App-Purchase-Produkten innerhalb der Applikation ermöglicht. In der untersten Ebene, der Core-OS-Schicht, befindet sich das Speicher- und Threadmanagement sowie die Interprozesskommunikation Wertschätzung von Entwurfsmustern bei der Entwicklung Die für die iphone-entwicklung bereitgestellten Frameworks legen großen Wert auf eine kontinuierliche Anwendung objektorientierter Konzepte. Selbst systemnahe Frameworks, wie beispielsweise das Core-Foundation-Framework, simulieren Objektorientierung anhand spezieller C-Funktionen. Die Adaptierung vieler Patterns ist zum Großteil unumgänglich und ratsam. Es folgt ein kurzer Überblick über die wichtigsten Entwurfsmuster, die im weiteren Verlauf dieser Arbeit direkt oder indirekt durch die bei der iphone-programmierung verwendeten Frameworks zur Anwendung kommen. 8

25 2.1. Das iphone als Entwicklungsplattform Model-View-Controller-Pattern Das Model-View-Controller-Pattern, kurz MVC-Pattern, stellt eines der zentralen Entwurfsmuster dar und ist bei der Entwicklung mithilfe des Framework UIKit unverzichtbar (vgl. zu diesem Abschnitt [App10d], Seite 158 ff.). Die Anzeige, Verarbeitung und Speicherung von Daten wird in eine Ansicht (View), eine Steuerungseinheit (Controller) und ein Datenmodell (Model) aufgeteilt. Die View übernimmt hierbei die Anzeige der Daten als auch die Annahme von Benutzerinteraktionen. Der Controller stellt die Funktionalität bereit und delegiert zwischen dem Datenmodell und der zugehörigen View. Das MVC-Pattern zählt zu den sogenannten Compound-Patterns, da es mehrere Entwurfsmuster in sich vereint. Praktisch gesehen lässt sich dieses Pattern in Hinsicht auf die Entwicklung einer iphone-applikation wie folgt beschreiben: Mithilfe der Applikation Interface Builder, einem Werkzeug zur visuellen Komposition von Darstellungselementen, wird zunächst eine Ansicht entworfen, während ein Persistenzmanager die zugrunde liegenden Daten über die entsprechen Schnittstellen zur Verfügung stellt. Im Zentrum steht eine Controllerklasse, die zwischen den angebotenen Daten und der Interaktion über die Ansicht durch den Benutzer steht und delegiert. Die bei der iphone-entwicklung zur Anwendung kommende Form des Entwurfsmusters unterscheidet sich, im Vergleich zu der in Lehrbüchern dargestellten Form, hinsichtlich der Verteilung von Zuständigkeiten. Mediator Strategy Interaktion durch Benutzer Controller Aktualisierung Command Composite View Aktualisierung Benachrichtigung Model Observer Abbildung 2.2.: Die bei der Entwicklung von iphone-anwendungen zum Einsatz kommende Form des MVC-Patterns. Wie Abbildung 2.2 zeigt, entfällt bei der iphone-entwicklung, im Gegensatz zur gebräuchlichen Form in Abbildung 2.3, die direkte Kommunikation zwischen Model und View. Dies ermöglicht es, sowohl Model als auch View unabhängig voneinander zu 9

26 2. Technische Grundlagen Strategy Interaktion durch Benutzer Controller Aktualisierung Aktualisierung Composite View Benachrichtigung Model Observer Abrufung des neuen Stands Abbildung 2.3.: Die gebräuchliche Form des MVC-Patterns sieht eine direkte Kommunikation zwischen View und Model vor. nutzen und erhöht somit die Wiederverwendbarkeit beider Elemente. Der Controller tritt in diesem Fall in die Rolle eines sogenannten Mediators, der sämtliche Aufrufe zwischen Model und View koordiniert und ausführt. Ein weiterer Vorteil liegt darin, dass der Controller in dieser Form des Entwurfsmusters beispielsweise Platzhaltertexte und Platzhalterobjekte bereitstellen kann, da die direkte Kommunikation zwischen Model und View entfällt. Observer-Pattern Die Verwendung des sogenannten Observer-Patterns ermöglicht es einem Objekt oder mehreren Objekten, sich als Beobachter von anderen Objektinstanzen zu registrieren (vgl. zu diesem Abschnitt [App10d], Seite 154 f.). Bei der Umsetzung ist eine lose Kopplung von höchster Bedeutung, sodass das Subjekt, sprich die zu beobachtende Objektinstanz, keine detaillierten Informationen über die Beobachter und im umgekehrten Fall die Beobachter keine detaillierten Informationen über das Subjekt benötigen. Für die Umsetzung des Patterns können unter Verwendung des Foundation-Framework und der Programmiersprache Objective-C viele verschiedene Wege eingeschlagen werden. Diese werden im weiteren Verlauf der Arbeit in einem praxisbezogenen Kontext diskutiert. 10

27 2.1. Das iphone als Entwicklungsplattform Composite-Pattern Die Nutzung des Composite-Patterns (Kompositum) ermöglicht eine hierarchische, baumartige Staffelung von Objektinstanzen (vgl. [App10d], Seite 145 f.). Das Entwurfsmuster nimmt bei der Gestaltung von Oberflächen eine besondere Position ein, da hierbei Instanzen der Klasse UIView (diese dient zur Positionierung und Darstellung von Grafiken sowie GUI-Elementen auf dem Display) in sich weitere Referenzen auf UIView-Instanzen enthalten können (sogenannte Sub-Views). In diesem speziellen Fall wird eine hierarchische Staffelung auf struktureller und visueller Ebene erreicht. Singleton-Pattern Durch Anwendung des Singleton-Patterns kann sichergestellt werden, dass von einer Klasse nur eine einzige Instanz erzeugt werden kann und diese über einen zentralen Zugriffspunkt bereitgestellt wird (vgl. [App10d], Seite 157). Eine mögliche Adaption des Patterns wird beispielsweise in Kapitel 6 illustriert. Adaptionen des Decorator-Pattern Das sogenannte Decorator-Pattern stellt eine Möglichkeit zur Erweiterung von Klassenfunktionalitäten ohne Vererbung und ohne Modifikation des Programmcodes dar (vgl. zu diesem Abschnitt [App10d], Seite 147 ff.). Es genügt an dieser Stelle zu sagen, dass die erweiternde Klasse eine Referenz auf eine Objektinstanz der Klasse, deren Funktionalität es zu erweitern gilt, verwendet und die Schnittstellen dieser bereitstellt. Intern kann die sogenannte Wrapperklasse den Zugriff auf das Objekt beliebig anpassen und erweitern. Bei der iphone-programmierung spielen zwei Adaptionen dieses Patterns eine besondere Rolle. Die Erste, bekannt als Delegation-Pattern, nutzt ebenfalls eine Menge von Objektinstanzen, an die bestimmte Funktionalitäten delegiert werden. Es handelt sich hierbei jedoch um keine strikte Adaption des Entwurfsmusters, da die delegierende Klasse keine gemeinsame Schnittstelle mit den Delegaten teilt. Verschiedene Umsetzungsmöglichkeiten werden im Verlauf von Kapitel 6 praxisbezogen diskutiert. Die zweite Möglichkeit ist ebenfalls keine strikte Adaption des Patterns und bezieht sich 11

28 2. Technische Grundlagen auf ein Feature der Programmiersprache Objective-C. Die sogenannten Kategorien werden in Abschnitt genauer betrachtet und können ebenfalls zur Erweiterung von Klassen ohne Nutzung von Vererbung verwendet werden Ruby on Rails als Framework zur Entwicklung von Webapplikationen Ruby on Rails (kurz Rails oder RoR) ist ein modernes Framework zur Erstellung von Webapplikationen. Als Programmiersprache wird Ruby genutzt, eine stark objektorientierte Skriptsprache, die besonderen Wert auf eine natürliche Formulierung der Syntax legt. Ruby-Programme sollen leicht zu schreiben und auch nach längeren Zeiträumen noch ebenso leicht wieder zu verstehen sein. Rails führt die philosophischen Hintergedanken der Sprache weiter aus und versucht die nötige Arbeit bei der Programmierung zu minimieren. So werden die Standardbibliotheken von Ruby um Methoden erweitert, die die Lösung von altbekannten Programmieraufgaben meist auf besonders elegante und minimale Art und Weise erlauben. Ein neues Ruby-on-Rails-Projekt und die hiermit verbundene Verzeichnisstruktur können mit einem einzigen Aufruf innerhalb der Kommandozeile erstellt werden. Die Struktur des Projekts lässt den grundlegenden Aufbau von Rails-Applikationen erahnen: So existieren Ordner für Model- und Controllerklassen sowie Dateien zur Beschreibung der Ansichten. Rails-Applikationen haben, ähnlich zu iphone-applikationen, dem MVC-Pattern zu folgen. So werden in den Entitätsklassen über das Framework Active Record Klassenstrukturen auf die unterliegende Datenbank abgebildet und in den Controllerklassen die Verbindung zwischen Ansicht und Anwendungsdaten hergestellt. Die Beschreibung der Ansichten kann, unter anderem, in sogenannten eruby-files (Embedded Ruby), die neben der Beschreibung über die Auszeichnungssprache HTML oder XHTML das Einbinden von Ruby-Quelltext erlauben, erfolgen Zentrale Prinzipien des Framework Ruby on Rails Rails stellt zwei Konzepte in den Mittelpunkt, die die Wartbarkeit des Projektes und die Lesbarkeit des Quelltextes fördern können: 12

29 2.2. Ruby on Rails als Framework zur Entwicklung von Webapplikationen DRY Don t repeat yourself DRY, sprich Don t repeat yourself, bedeutet wörtlich übersetzt Wiederhole dich nicht und bezieht sich auf die Vermeidung von Redundanzen bei der Entwicklung. Sobald ein Wert oder eine Funktionalität an zwei verschiedenen Stellen in identischer Form vorhanden ist, besteht ein Verstoß gegen diesen Grundsatz. Die Bündelung von identischen Funktionen steigert die Wartbarkeit von Softwareprojekten ungemein. Dies gilt auch für die Vermeidung von Fehlern bei der textuellen Vervielfältigung von Werten. Wird beispielsweise ein Wert an verschiedenen Stellen wiederholt gesetzt, obwohl dieser in Abhängigkeit zu den vorherigen Definitionen steht, ist die Fehleranfälligkeit und der Aufwand im Falle einer Änderung groß. Conventions over Configuration Bei der Entwicklung von Ruby-on-Rails-Applikationen werden Konventionen über die Notwendigkeit der Konfiguration des Projektes gestellt. Dies bedeutet, dass das Framework für jeden Aspekt der Entwicklung eine Konvention bereitstellt, die es bei der Entwicklung einzuhalten gilt. Es wird sozusagen ein goldener Weg vorgegeben, dem bei der Entwicklung zu folgen ist. Dies erlaubt einen fast vollständigen Verzicht auf Konfigurationsdateien. Zum Vergleich sei die Entwicklung von Webapplikationen mit Java EE (Java Enterprise Edition) erwähnt, die ohne komplexe Konfigurationsdateien und mächtige integrierte Entwicklungsumgebungen (sogenannte IDEs) nicht praktikabel wäre. Für die Entwicklung mithilfe von Ruby on Rails genügt hingegen ein einfacherer Texteditor und die lokale Installation des Framework Zentrale Technologien des Framework Ruby on Rails Bei der Entwicklung mit Ruby on Rails spielen einige Subframeworks und Klassenbibliotheken eine zentrale Rolle. Da diese im Verlaufe der Arbeit mehrfach Erwähnung finden, seien an dieser Stelle die wichtigsten Vertreter genannt: 13

30 2. Technische Grundlagen Active Record Das Framework Active Record dient zum Abbilden von Klassen auf relationale Datenbankstrukturen (vgl. zu diesem Abschnitt [BK07], Seite 82). Hierbei folgt das Framework dem Konzept des objektrelationalen Mappings (kurz ORM). Nachdem eine Zuordnung zur unterliegenden Datenbankstruktur vorgenommen wurde, können die Active-Record-Objekte vollständig objektorientiert verwendet werden, während das Framework die Umwandlung der Methodenaufrufe in entsprechende SQL-Anfragen für das Datenbanksystem übernimmt. Action Controller Controller sind für die Vorbereitung des Datenbestands und die Vermittlung von Ansichten an die Clients zuständig (vgl. zu diesem Abschnitt [BK07], Seite 82). Innerhalb dieser können sogenannte Actions definiert werden, die bei bestimmten HTTP-Anfragen aufgerufen werden. Standardmäßig können diese Actions respektive Methoden über das folgende URL-Schema angesprochen werden: controller/action/id. Innerhalb der Controller können sogenannte Filter eingesetzt werden. Der Filter-Mechanismus ermöglicht die Auswahl einer oder mehrerer Methoden zur Ausführung zu bestimmten Zeitpunkten. Hierzu existieren sogenannte Before-Filter, die das Ausführen von Methoden vor dem eigentlichen Controlleraufruf erlauben, und After-Filter, für die Ausführung nach dem Controlleraufruf. Diese Filter können zudem auf bestimmte Actions begrenzt oder im Falle einer unerwünschten Ausführung, zum Beispiel durch Vererbung, übersprungen werden. Action Mailer Das Framework Action Mailer erlaubt das komfortable, programmatische Versenden von s. Hierzu müssen, ähnlich zu Active Record, Entitätsklassen angelegt werden. Nachrichten können durch das Deklarieren von Methoden innerhalb dieser vorbereitet und unter Zuhilfenahme von Makros und Methoden etwaige Versandinformationen, wie beispielsweise Betreff, Absender, Empfänger und Body, definiert werden. Die Formatierung des Bodys kann, wie bei Action-Controllern, über eine getrennte View 14

31 2.3. Modernen Techniken im Umfeld des Web 2.0 erfolgen. Der eigentliche Versand erfolgt durch den Aufruf einer Klassenmethode anhand eines durch Ruby on Rails vorgegebenen Namensschemas Modernen Techniken im Umfeld des Web 2.0 Web-Application-Frameworks, wie Ruby on Rails, werden heutzutage primär für die Entwicklung von sogenannten Web-2.0-Anwendungen verwendet. Dieser Begriff wurde Ende 2005 durch den Artikel What Is Web 2.0 von Tim O Reilly geprägt und verbreitet (siehe [O R05]). Zu den zentralen Elementen dieser neuen Generation des Internets zählen unter anderem leichtgewichtige Benutzerinterfaces und Entwicklungsmodelle. Ruby on Rails gehört, im Vergleich zu Java EE, zu den Vertretern dieser. Moderne Webapplikationen bieten den Benutzern ähnlichen Komfort wie Desktop-Applikationen, nur dass diese ohne lokale Installation mithilfe eines Webbrowsers verwendbar sind. Die im Folgenden erläuterten Techniken bieten hierfür die Grundlage: (X)HTML und CSS Die Beschreibungssprachen HTML oder XHTML dienen als Standard zur Beschreibung der Struktur und des Inhalts von Webseiten. Sowohl XHTML als auch HTML werden in Form einer baumartigen Struktur unter Zuhilfenahme von sogenannten Tags formuliert, bei der jeder Knoten eine beliebige Anzahl von Kindelementen besitzen kann. Für das Layout und die Erstellung eines Designs dient CSS (Cascading Stylesheets). Sowohl für HTML als auch für CSS sind derzeit neue Versionen bzw. Standardisierungen in der Entwicklung, bekannt unter HTML 5.0 und CSS 3.0. JavaScript JavaScript ist eine Skriptsprache, die von allen modernen Webbrowsern interpretiert und zur Erzeugung interaktiver Inhalte aufseiten des Benutzers verwendet werden kann. JavaScript-Frameworks, wie zum Beispiel jquery 3, dienen zur Vereinfachung der Ereignisbehandlung, des einheitlichen Zugriffs auf das Document Object Model (kurz 3 15

32 2. Technische Grundlagen DOM), der Ausführung von AJAX-Aufrufen sowie der Erstellung von Animationen und interaktiver Inhalte. Document Object Model Das Document Object Model (kurz DOM) stellt die interne Repräsentation einer HTML- oder XHTML-Webseite dar. Mithilfe dessen kann der Inhalt, meist unter Verwendung von JavaScript, dynamisch manipuliert werden. AJAX Unter dem Begriff AJAX (Asynchronous JavaScript and XML) sind sämtliche Techniken zur asynchronen Datenübertragung über den Webbrowser zu verstehen. Die entsprechenden Aufrufe des Webbrowsers können über die Skriptsprache JavaScript ausgeführt und zur Kapselung der zu übertragenden Daten die JavaScript Object Notation (kurz JSON) oder eine XML-Struktur verwendet werden. 16

33 KAPITEL 3 Strukturelle Grundlagen zu wetravel und wetravel online Die Applikation wetravel, die innerhalb dieser Arbeit zusammen mit der zugehörigen Webapplikation wetravel online als Grundlage für die Themen dient, ermöglicht eine komfortable Buchführung bei Gruppenreisen und Exkursionen. So können, unter anderem, Teilnehmer aus dem Adressbuch des Endgerätes importiert, mit wenig Aufwand neue Buchungen für eine Gruppe oder einzelne Teilnehmer erstellt oder Geldwechselvorgänge protokolliert werden, die die Applikation bei der Kalkulation der Gesamtbeträge berücksichtigt. Parallel hierzu wurde ein Webportal 1 sowie eine Webapplikation 2 entwickelt, die den Benutzern das Verwalten, Einsehen und Erstellen von Buchungsreports ermöglicht. Die Webapplikation (bezeichnet als wetravel online) steht nur nach Erwerb eines Abonnements zur Verfügung und kann über die iphone-applikation für drei Monate freigeschaltet werden. Hierbei kommen die Kaufmechanismen, die die Firma Apple seit der Version 3.0 des iphone SDKs bereitstellt, zum Einsatz. Zusätzlich hat der Benutzer die Möglichkeit Statistiken zu generieren oder Rechnungen an die Teilnehmer Autoren: Benjamin Glatzel Dominik Wilhelm

34 3. Strukturelle Grundlagen zu wetravel und wetravel online einer Reise zu versenden. Abbildung 3.1 zeigt die Infrastruktur des Projekts in einer vereinfachten Form. iphone XML Webserver Übertragung von Reporten über HTTP Core Data Active Record SQLite SQLite Abbildung 3.1.: Die Infrastruktur des Projekts wetravel Struktur der iphone-applikation wetravel Bei der Entwicklung der iphone-applikation wetravel stand eine möglichst hürdenfreie Wartung des Programmcodes sowie eine einheitliche Menüführung im Vordergrund. So wurde anfangs für jede Ansicht ein einheitliches Design entwickelt, das die vom SDK bereitgestellten Tabellenstrukturen für die Darstellung nutzt. Um Redundanzen zu vermeiden, wurde zunächst eine Klasse entwickelt, die die Initialisierung sämtlicher Ansichten ausführt und als Superklasse dieser dient (vgl. Abbildung 3.2). 18

35 3.1. Struktur der iphone-applikation wetravel UIViewController «interface» UITableViewDelegate «interface» UITableViewDataSource WTTableViewController {disjoint,incomplete} ParticipantListViewController ExcursionListViewController Abbildung 3.2.: Erzeugung eines globalen Designs durch die Einführung einer Superklasse für sämtliche View-Controller. Somit ist es besonders einfach, das Design der gesamten Anwendung anzupassen, da die hierzu nötige Funktionalität an einer zentralen Stelle verfügbar ist (siehe Abschnitt 6.1.1). Funktionen, die an vielen Stellen zur Anwendung kamen, wurden in Hilfsklassen ausgelagert. Dies hatte zum Beispiel die Erstellung einer Klasse zur Folge, die ausschließlich Methoden zur Kommunikation mit dem Server kapselt. Eine weitere Klasse bündelt beispielsweise Methoden zur Generierung von Grafiken oder zum Beschneiden von Zeichenketten. Insgesamt besteht das Projekt wetravel aus 75 Klassen und beinhaltet über Zeilen Quelltext 3. Abbildung 3.3 zeigt eine vereinfachte Darstellung des Datenmodells. Das Konzept der Attributgruppen ist nicht Bestandteil dieser Arbeit und ist aufgrund dessen innerhalb der Grafik nur in einer minimierten Form dargestellt. Für das grundlegende Verständnis ist zunächst wichtig, dass einige Datenbankobjekte wie bereits erwähnt über eine XML- Struktur an die Webapplikation übermittelt werden müssen. Diese vier Kandidaten sind in Abbildung 3.3 dem Paket mit der Bezeichnung Vollständige Übertragung zugeordnet. Hierunter ist zu verstehen, dass die vollständige Struktur der Klassen übertragen wird. Eine eindeutige, auch außerhalb des Kontextes der Applikation gültige Identifikation wird mithilfe der Basisklasse WTBase erzeugt. Diese stellt den zugehörigen Objekten 3 Ermittelt mit cloc. 19

36 3. Strukturelle Grundlagen zu wetravel und wetravel online einen über die Laufzeit der Applikation hinweg gültigen Schlüssel zur Verfügung (siehe Abschnitt 6.1.2). Die verbleibenden Entitäten werden entweder von der Webapplikation nicht verwendet oder in einer reduzierten Form übertragen, wie zum Beispiel als einfache Zeichenkette im Falle der Währungen. Hier wird der eindeutige, dreistellige ISO-Code (nach dem Standard ISO ) verwendet. Lokal User WTBase Stellt Objekt-ID zur Verfügung * Vollständige Übertragung 1 Excursion 0..* Heimwährung 0..* * Exchange 0..* 1 1 Currency 1 LogEntry Lokale Authentifikation und Logging. 0..* Group 0..* 0..* 0..* 1 0..* 0..* 0..* 1..* 0..* Participant Booking Amount 0..* * Dient der individuellen Verteilung von Buchungsbeträgen. {or} 1 Tag Attribute Groups 0..1 Picture 0..1 Abbildung 3.3.: Vereinfachte Darstellung des wetravel-datenmodells

37 3.2. Struktur der Webapplikation wetravel online und des zugehörigen Webportals 3.2. Struktur der Webapplikation wetravel online und des zugehörigen Webportals Für das Hosting der Webapplikation kommt, neben einem Mac mini Server der Firma Apple, die neueste Version des zugehörigen Serverbetriebssystems (Mac OS X Server 5, Version ), ein modernes UNIX-Betriebssystem, das besonders für die Konfiguration, Wartung, Überwachung und Einrichtung von Serversoftware eine Vielzahl von komfortablen Werkzeugen bereitstellt, zum Einsatz. Die Ruby-on-Rails-Webapplikation wurde mithilfe des Moduls Passenger 6 in einen Apache-Webserver (Version ) integriert. Die Webapplikation besteht, wie sämtliche Ruby-on-Rails-Applikationen, aus einer Menge von Controllerklassen, Hilfsklassen, Entitätsklassen und Ansichten. Die Controller, die die Funktionalität der Applikation zur Verfügung stellen, wurden anhand der Zugehörigkeiten in zwei Bereiche aufgeteilt. So sind jene Controller, die für die Portal-Anwendung von Nöten sind, getrennt von jenen, die die Hauptfunktionalität des wetravel-online-services bereitstellen. Alle Controller inklusive ihrer Unterteilung sind in Abbildung 3.4 zu sehen. Der Zugriff auf die unterliegende SQLite-Datenbank erfolgt mithilfe des Rails-Subframework Active Record, das unter anderem das zuvor erwähnte objektrelationale Mapping sowie die Migration und Initialisierung der unterliegenden Datenbank ermöglicht. In Abbildung 3.5 ist das zugrunde liegende Datenmodell zu sehen. Die Methoden, die beispielsweise für die Berechnungen des Wechselkurses oder des Gesamtkontostandes zuständig sind, wurden vor Ort in den Active-Record-Klassen implementiert. Abbildung 3.5 zeigt zudem die Zugehörigkeit der Klassen. So beinhaltet das Paket mit dem Titel Report jene Objekte, die von der iphone-applikation unter Zuhilfenahme einer XML-Struktur übertragen werden. In Kontrast hierzu stehen die Benutzer (User) und Quittungen (Receipt), die für die Authentifikation und Zuordnung von Abonnements im Kontext der Webapplikation verwendet werden. 5 Vermarktet unter der Bezeichnung Snow Leopard Server. 6 Bekannt als mod_rails oder mod_rack. 21

38 3. Strukturelle Grundlagen zu wetravel und wetravel online ActionController::Base ApplicationController OnlineController Webportal wetravel online WelcomeController FaqController AdminController MailsController StatisticsController PasswordRestoration- Controller DetailsController ApiController ReportsController SettingsController ImpressumController ContactController LoginController Participants- Controller Abbildung 3.4.: Gruppierte Darstellung sämtlicher Controllerklassen der Rails-Applikation. Informationen zu Benutzern und deren Abonnements. ActiveRecord::Base Ein Report spiegelt den aktuellen Stand einer Reise wider. Teilnehmer werden redundant abgelegt. wetravel online Report Receipt 0..* 1 User 1 0..* Trip * Exchange Visitor 0..* 1 Participant 0..* 0..* 0..* Booking 0..* 1 0..* Amount Dient der Protokollierung von Aufrufen für die Bereitstellung einer Statistikfunktionalität. Abbildung 3.5.: Das Datenmodell der Webapplikation. 22

39 KAPITEL 4 Betrachtung der Programmiersprache Objective-C Objective-C ist eine strikte Obermenge der Programmiersprache ANSI-C. Sie erweitert unter anderem den Sprachumfang dieser um objektorientierte Elemente und erlaubt die nahtlose Vermischung von C- und Objective-C-Syntax. Die Sprache fällt somit in die Kategorie der hybriden Programmiersprachen 1 und erlaubt die Verwendung von imperativen und objektorientierten Sprachmitteln (vgl. [GHK95], Seite 5). Demnach kann jedes ANSI-C-Programm mit einem Objective-C-Compiler übersetzt werden. Objective-C kommt heute hauptsächlich in Apples Betriebssystemen Mac OS X und iphone OS in Verbindung mit den Frameworks Foundation (Mac OS X und iphone), Application Kit (Mac OS X) und UIKit (iphone) zum Einsatz. Dank der GNU Compiler Collection (kurz GCC) können Objective-C-Programme auf vielen Plattformen übersetzt werden und mit GNUStep 2 steht zudem eine offene Implementierung der wichtigsten Frameworks zur Verfügung. Autor: Benjamin Glatzel Bei der Entwicklung von iphone-applikationen ist die Verinnerlichung der Programmiersprache Objective-C unumgänglich. Innerhalb dieses Kapitels werden die Be- 1 Erlauben die Kombination von Sprachelementen verschiedener Programmiersprachen

40 4. Betrachtung der Programmiersprache Objective-C sonderheiten dieser dynamisch orientierten Sprache und des zugehörige Foundation- Framework im Vergleich zur statisch ausgelegten Programmiersprache C++ betrachtet und hinsichtlich der Anforderungen an moderne, objektorientierte Programmiersprachen, untersucht. Dieses Kapitel stellt keine vollständige Einführung in Objective-C dar und geht nur exemplarisch auf Kernpunkte des Themengebiets ein. Für das Verständnis dieses Abschnitts werden Grundkenntnisse der Objektorientierung in höheren Programmiersprachen, wie beispielsweise C++ oder Java, vorausgesetzt. Als Grundlage für dieses Kapitel dienen die von Apple bereitgestellten Dokumentationen zur Programmiersprache Objective-C und der zugehörigen Laufzeitumgebung (siehe [App09h; App09f]) sowie das Buch Programming in Objective-C (siehe [Koc09]) Syntaktische Besonderheiten der Programmiersprache Die Erweiterungen der Sprache ANSI-C durch Objective-C orientieren sich stark an Smalltalk, eine der ersten objektorientierten Programmiersprachen (siehe [App09h], Seite 9). Auffällig ist hierbei zunächst die Infix-Notation, die sich durch die Verwendung von eckigen Klammern bemerkbar macht. Listings 4.1 und 4.2 stellen das Konzept des Message-Passings 3 den Methodenaufrufen der Sprache C++ gegenüber. 1 Fahrzeug * fahrzeug = [[[Fahrzeug alloc] init] autorelease]; 2 [fahrzeug miteinergeschwindigkeitzwischen:80 und :160]; Listing 4.1: Ein Nachrichtenaufruf in Objective-C. 1 Fahrzeug * fahrzeug = new Fahrzeug(); 2 fahrzeug->fahren("hollywood",80,160); 3 delete fahrzeug; Listing 4.2: Methodenaufruf in C++. Neben der unterschiedlichen Notation sind die optionalen Parameterbezeichnungen in Objective-C auffällig. Diese verbessern die Lesbarkeit und können bei Methoden mit vielen Parametern zum unmittelbaren Verständnis seitens des Lesers beitragen. Es ist zudem üblich, die Methoden als Satz zu formulieren. Betrachtet man im Vergleich 3 Wird in Abschnitt 4.2 genauer erläutert. 24

41 4.2. Objective-C als dynamische Programmiersprache hierzu eine Funktion in C++, ist die Hinzuziehung der Klassendokumentation bei einer Vielzahl von Parametern oft unumgänglich. Herkömmliche Sprachelemente, wie beispielsweise Ausdrucks- und Iterationsanweisungen sowie Verzweigungen, unterscheiden sich nicht von der zugrunde liegenden Sprache ANSI-C. Seit der Erweiterung von Objective-C im Jahr 2007 stehen zudem moderne Konzepte, wie zum Beispiel die schnelle respektive vereinfachte Iteration über Collection-Klassen mithilfe von For-Each-Schleifen oder die automatische Synthetisierung von Zugriffsmethoden für Instanzvariablen, zur Verfügung (vgl. [App09h], Seite 87 ff.) Objective-C als dynamische Programmiersprache The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it dynamically performs operations such as creating objects and determining what method to invoke. (siehe [App09f], Seite 13) Ein primäres Ziel der Sprache Objective-C ist es, möglichst viele Entscheidungen zur Laufzeit eines Programms zu treffen. So werden Objekte dynamisch bei der Ausführung alloziert, statt diese beim Kompilierungsvorgang statisch zu binden. Im Objective-C- Umfeld wird nicht von Methoden- oder Funktionsaufrufen gesprochen, sondern vom Senden von Nachrichten an Objekte, bekannt als Message-Passing. Diese Formulierung spiegelt die dynamische Natur der Sprache wider. So ist es möglich, ein Programm mit unbekannten Nachrichtenaufrufen zu übersetzen. Ob der Empfänger auf diese Nachricht antworten kann, wird erst zur Laufzeit festgestellt. Zur Vereinfachung wird innerhalb dieses Kapitels weiterhin sowohl bei C++ als auch bei Objective-C die Bezeichnung Methodenaufruf bzw. Funktionsaufruf verwendet. Objective-C unterstützt zudem statische und dynamische Typisierung. Der spezielle Datentyp id kann zur Referenzierung von Objekten beliebiger Klassenzugehörigkeit verwendet werden. Informationen zur Klasse und eventuellen Vererbungshierarchien werden intern durch die Verwendung der Instanzvariablen isa erreicht, die über die Basisklasse NSObject (siehe Abschnitt 4.4) bei der Initialisierung zur Verfügung gestellt wird. Alle dynamischen Elemente der Sprache werden durch die Verwendung einer 25

42 4. Betrachtung der Programmiersprache Objective-C Laufzeitbibliothek erreicht, die für sämtliche Objective-C-Aufrufe die entsprechenden C-Funktionen bereitstellt. Die Auflösung dieser erfolgt durch den Objective-C- Compiler. Das Vorgehen wird in Listing 4.3 und 4.4 anhand einer Gegenüberstellung eines Nachrichtenaufrufs und des entsprechenden Aufrufs der Laufzeitbibliothek verdeutlicht. 1 [empfaenger nachricht]; Listing 4.3: Objective-C-Nachrichtenaufruf. 1 objc_msgsend(empfaenger, nachricht); Listing 4.4: Der zugehörige Aufruf der Laufzeitbibliothek. Objective-C erlaubt die dynamische Auflösung von Funktionsimplementierungen im Betrieb. Auch das dynamische Linking von Klassen und Kategorien 4 ist zur Laufzeit möglich. Diese Funktionalität kommt zum Beispiel in der Systemeinstellungs-Applikation von Mac OS X zum Einsatz und erlaubt hierbei die Einbindung zusätzlicher Module zur Ausführungszeit (vgl. [App09f], Seite 17 f.). Objective-C erlaubt keine statische Erzeugung von Objekten, während C++ sowohl die dynamische, als auch die statische Allokation während des Kompilierungsvorgangs unterstützt. Polymorphismus ist bei Objective-C ein standardmäßiges Verhalten, da Klassenabhängigkeiten stets zur Laufzeit aufgelöst werden. C++ unterstützt dies ebenso, jedoch muss die dynamische Bindung durch das Schlüsselwort virtual an den entsprechenden Funktionsdeklarationen der Basisklasse erzwungen werden. Polymorphie ist in der Sprache Objective-C vergleichsweise schwach ausgeprägt, da sowohl die Überladung von Operatoren als auch die Überladung von Funktionen gänzlich entfällt (vgl. [GHK95], Seite 5). Letzteres kann jedoch durch die beschreibende Form der Methodennamen kompensiert werden. Durch das erwähnte Dynamic-Binding, werden in Objective-C Nachrichtenaufrufe dynamisch parallel zur Ausführung des Programms aufgelöst, während die Gültigkeit von Funktionsaufrufen in C++ bereits bei der Übersetzung des Programms sichergestellt wird. 1 id f1 = [[Fahrzeug alloc] init]; 2 id f2 = [[Auto alloc] init]; 3 id f3 = [[Motorrad alloc] init]; 4 Das Konzept der Kategorien wird in Abschnitt behandelt. 26

43 4.2. Objective-C als dynamische Programmiersprache 4 5 // Ausgabe: <Fahrzeug: 0x10010c650> <Auto: 0x10010c760> <Motorrad: 0 x10010c870> Listing 4.5: Dynamische Typisierung in Objective-C. Listing 4.5 zeigt die dynamische Typisierung in Objective-C anhand eines Minimalbeispiels. Auto und Motorrad sind Tochterklassen der Klasse Fahrzeug. Bei der Ausgabe über die Funktion NSLog wird auf die unterliegende Methode description der Basisklasse NSObject zugegriffen, von der die Klasse Fahrzeug erbt. Diese Funktion gibt standardmäßig die Klassenbezeichnung des Objekts und die zugehörige Speicheradresse als String zurück. Die dynamische Typisierung ist in Objective-C eine Möglichkeit, Referenzen zu speichern, jedoch kann der Typ eines Objekts auch statisch definiert werden, sodass bereits bei der Übersetzung des Programms Fehler im Programm aufgedeckt werden können. Die dynamische Erzeugung von Objekten zur Laufzeit wird hierdurch nicht beeinflusst, vielmehr wird der Gehalt der Informationen für den Compiler reguliert (vgl. [App09h], Seite 91 ff.). Objective-C ermöglicht das Abfragen zahlreicher Informationen eines Objekts zur Laufzeit (bekannt als Reflexion). So können unter anderem die Klasse und alle vorhandenen Methoden erfragt werden. C++ bietet hierzu nur sehr begrenzte Möglichkeiten. Über das Schlüsselwort typeid kann zwar der Typ eines Objekts und dessen Bezeichnung zur Laufzeit ermittelt werden, jedoch sind die gelieferten Informationen vom verwendeten Compiler und dessen Konfiguration abhängig. Objective-C erlaubt es zudem, Objekte über den Namen der Klasse zu instanziieren. Hierzu wird eine Methode verwendet, die den Klassennamen mit Hilfe der Laufzeitumgebung ermittelt und das entsprechende Klassenobjekt liefert. Dies ermöglicht die Instanziierung eines zugehörigen Objekts (siehe Listing 4.6). 1 Class motorradclass = 2 id motorrad = [[[motorradclass alloc] init] autorelease]; 3 4 // Ausgabe: <Motorrad: 0x10010cc60> Listing 4.6: Erstellung einer neuen Objektinstanz anhand eines Klassennamens. 27

44 4. Betrachtung der Programmiersprache Objective-C Dieses Prinzip lässt sich auch auf den Aufruf von Methoden, beziehungsweise auf das Senden von Nachrichten an Objekte übertragen. Hierzu bietet die Sprache das Konzept der sogenannten Selektoren, die der Beschreibung von Methodenaufrufen dienen. 1 Auto * automobil = [[[Auto alloc] init] autorelease]; 2 SEL fahrensel = 3 [automobil performselector:fahrensel]; 4 // Ausgabe: Brumm. Brumm. Listing 4.7: Ausführung einer Methode in Objective-C über einen Selektor. In Listing 4.7 wird ein solcher Selektor anhand einer Zeichenkette erstellt und zum Aufruf einer Methode des Objekts motorrad genutzt. In der Sprache C++ kommen die Funktionszeiger den Selektoren am nächsten. Diese ermöglichen die Übergabe von Funktionen als Argument anderer Funktionen, die innerhalb dieser aufgerufen werden können. Selektoren sind deutlich flexibler und dynamischer als das Konzept der Funktionszeiger, da sie beispielsweise, wie in Listing 4.7 gezeigt, allein über die Bezeichnung der Methode während der Programmausführung initialisierbar sind. Funktionszeiger hingegen müssen beim Kompilieren gebunden werden. Für die erwähnten Sprachelemente existieren in Objective-C zur Laufzeit entsprechende Datentypen zur Referenzierung (SEL für Selektoren und Class für Klassen) Objektorientierte Konzepte in Objective-C Das Definieren und Beschreiben von Klassen in Objective-C unterscheidet sich oberflächlich betrachtet nicht von bekannten objektorientierten Programmiersprachen. Dennoch spezialisiert sich die Sprache darauf, mit einer geringen Anzahl von Sprachelementen, die Paradigmen der Objektorientierung möglichst einfach zu repräsentieren (vgl. [App09h], Seite 9). Geltungsbereiche von Instanzvariablen können, ähnlich wie in C++, mit Compiler-Direktiven gesetzt werden. Methoden hingegen sind stets als public deklariert und somit vor äußeren Zugriffen nicht geschützt. Zum Schutz von Methoden kann alternativ Gebrauch von Kategorien (siehe Abschnitt 4.3.3) gemacht werden. 28

45 4.3. Objektorientierte Konzepte in Objective-C Message-Forwarding als Alternative zu Mehrfachvererbung Objective-C unterstützt, wie das Vorbild Smalltalk und im Gegensatz zu C++, keine Mehrfachvererbung. Die Einführung dieser Funktionalität widerspricht dem Gedanken, eine Sprache zu entwickeln, die leicht verständlich und nicht unnötig komplex ist. Neben dem Problem, dass Mehrfachvererbung oft falsch angewendet und der Overhead somit verstärkt wird, bringt diese Probleme mit sich, für die keine einfachen und eleganten Lösungen existieren. Ein bekanntes Beispiel ist das sogenannte Diamond- Problem 5 (vgl. [GM10], Seite 296 f.). Um diese Funktionalität dennoch in Objective- C zu replizieren, stellt die Sprache über das Runtime-Environment das Konzept des Message-Forwarding, sprich die Weiterleitung von Nachrichten, zur Verfügung. Hierbei ist der Kerngedanke nicht die Übernahme der Funktionalität der Basisklassen, sondern die dynamische Weiterleitung von Nachrichten an Objekte. Beim Senden einer Nachricht an ein Objekt kann dieses dynamisch entscheiden, ob es auf diese antwortet, oder die Nachricht an ein Objekt weiterleitet und dessen Antwort zurückliefert. Im Gegensatz zur Mehrfachvererbung werden hierbei keine vergrößerten Klassen erstellt, sondern Funktionalität aufgeteilt und an Objekte delegiert (vgl. [App09f], Seite 19 ff.) Abstrakte Klassen und Interfaces Ein Protokoll stellt eine implizite Definition einer Schnittstelle bzw. eines Interfaces aus der objektorientierten Programmierung dar. So werden eine Menge von optionalen oder nicht optionalen Funktionssignaturen gebündelt und eine adaptierende Klasse muss die Implementierung der vorgeschriebenen Signaturen bereitstellen. Im Gegensatz zur Vererbung können Klassen eine Vielzahl von Protokollen adaptieren. Interfaces können in der Sprache C++ durch den expliziten Einsatz von Klassen, die ausschließlich Pure-Virtual-Methoden beinhalten, erstellt werden. Das Konzept der Protokolle ist im Vergleich zur umständlichen Definition in C++, hinsichtlich des Konzeptes aus der Objektorientierung, eindeutig und leicht verständlich. Objective-C stellt jedoch keine implizite Möglichkeit zur Verfügung die Instanziierung von Objekten zu verhindern, wie dies von abstrakten Klassen bekannt ist. Hierzu wird als Konvention lediglich das 5 Beim Erben von zwei Klassen, die eine gemeinsame Basisklasse besitzen, können Funktionsaufrufe oft nicht eindeutig zugeordnet werden. 29

46 4. Betrachtung der Programmiersprache Objective-C Einfügen einer Anmerkung in der Dokumentation der Klasse und, bei Bedarf, das Versehen der Funktionen mit Stubs 6, empfohlen Funktionale Erweiterung von Klassen ohne Vererbung Mit dem Konzept der Kategorien besteht in Objective-C die Möglichkeit, Klassen ohne Vererbung und ohne Besitz des Quelltextes um Methoden zu erweitern. Als Beispiel könnte die Klasse NSString des Foundation-Framework um eine projektspezifische Funktion erweitert werden. Kategorien dienen nur der Erweiterung um Methoden, Instanzvariablen können nicht ohne die Verwendung von Vererbung hinzugefügt werden. Sie eignen sich zudem zur Aufteilung von Aufgabenbereichen oder zur Kapselung von privaten Methoden. Die Erweiterung einer Klasse kann in C++ nur durch explizite Vererbung erreicht werden, während in Objective-C die Definition einer Kategorie und die Einbindung jener in den Übersetzungsvorgang genügt. Die erweiterte Klasse kann vollständig transparent verwendet werden. Kategorien können jedoch nicht mit voll-dynamischen Konzepten, wie sie beispielsweise in der Programmiersprache Ruby zu finden sind, verglichen werden. Es handelt sich hierbei lediglich um einen Mechanismus, der bei der Übersetzung eines Programms die deklarierten Methoden berücksichtigt und den betroffenen Klassen zuordnet Stellenwert des Foundation-Framework The Foundation framework defines a base layer of Objective-C classes. In addition to providing a set of useful primitive object classes, it introduces several paradigms that define functionality not covered by the Objective-C language. (siehe [App10f], Seite 13) Das Foundation-Framework stellt einige Basisklassen für die Programmierung zur Verfügung. Zu diesen zählt zunächst die Klasse NSObject, die als Superklasse für alle weiteren Klassen dient. Sie sorgt für die reibungslose Initialisierung, füllt die zur Laufzeit benötigten Informationen und stellt die Verbindung des Objekts zur Laufzeitumgebung her. Das Foundation-Framework bietet zudem viele gebräuchliche Datentypen wie 6 Platzhaltermethoden, die beispielsweise nur einen einzigen Wert zurückgeben. 30

47 4.4. Stellenwert des Foundation-Framework zum Beispiel Collection-Klassen oder Klassen zur Bildung und Manipulation von Zeichenketten (sogenannte Strings). In Hinblick auf C++ ist das Framework mit der C++ Standard Library zu vergleichen. In Bezug auf Objective-C und besonders im Kontext des Foundation-Framework wurden viele Konventionen eingeführt. So gibt es keine impliziten Konstruktoren oder Destruktoren, die anhand der Bezeichnung der Klasse zu implementieren sind. Stattdessen wird das Wort init als Bezeichnung für die Initialisierungsmethode des Objekts verwendet. Erweiterte Konstruktoren, die über mehrere Parameter verfügen, nutzen stets init als Präfix. Umgekehrt wird vor der Auflösung eines Objekts die Methode dealloc der Basisklasse NSObject aufgerufen, die durch Überschreibung für die Freigabe von allozierten Objekten verwendet werden kann. Das Fehlen von Namespaces wird durch die Einführung von Präfixen in Klassenbezeichnungen kompensiert. Ein markantes Beispiel ist die Zeichenkette NS 7, die allen Klassenbezeichnungen des Foundation-Framework vorangestellt ist. Hinsichtlich des Speichermanagements werden ebenso Konventionen und Techniken eingeführt, die die Arbeit mit dynamisch allozierten Objekten erleichtern. Die grundlegende Idee ist hierbei die Zählung von Objektreferenzierungen. Nach der Allokation und Initialisierung eines Objekts ist der Referenzierungszähler dessen gleich eins und kann beispielsweise über die Aufrufe retain und release erhöht bzw. verringert werden. Erreicht der Zähler null, wird der reservierte Speicher des Objekts bei nächster Gelegenheit dealloziert. Der sogenannte Retain-Count kann jederzeit ermittelt werden. Die soeben erläuterte Zählung von Referenzierungen ist in Listing 4.8 anhand eines Beispiels demonstriert. 1 id harley = [[Motorrad alloc] init]; 2 retaincount]); 3 // Ausgabe: 1 4 [harley retain]; 5 retaincount]); 6 // Ausgabe: 2 7 [harley release]; 8 retaincount]); 9 // Ausgabe: 1 7 Steht für NeXTStep. Ein ehemaliges Betriebssystem, das die Grundlage für die heutigen Betriebssysteme der Firma Apple formte. 31

48 4. Betrachtung der Programmiersprache Objective-C 10 [harley release]; 11 // [...] 12 // Verursacht mit hoher Wahrscheinlichkeit einen Speicherzugriffsfehler 13 [harley fahren]; Listing 4.8: Beispiel zur Zählung von Referenzierungen in Objective-C. Zusammenfassend bedeutet dies, dass bei der Programmierung der Besitz von Objekten erklärt werden muss. Nach einer Freigabe (sprich einem Release) durch den letzten Besitzer eines Objekts wird dieses dealloziert. Beim Hinzufügen von Objekten in die Datenstruktur NSArray, eine Feldstruktur des Foundation-Framework, erhöht diese zunächst den Referenzierungszähler der jeweiligen Objekte um eins und erst nach der Entfernung aus der Datenstruktur wird der Zähler dekrementiert. Betrachtet man im Vergleich hierzu das Speichermanagement der Programmiersprache C++, stehen in dieser die Operatoren new und delete zur Verfügung, die zur Reservierung und Deallokation des Speichers dynamisch allozierter Objekte dienen. Da hierzu keine Konventionen existieren, ist der Umgang mit Speicher in der Sprache C++ zunächst ungewiss und kann nur durch die Einführung von eigenen Programmierrichtlinien kontrolliert werden. Für die Verwendung des Speichermanagements in Objective-C sind in der Memory Management Programming Guide for Cocoa (siehe [App10m]) diverse Konventionen festgelegt, die bei der Programmierung mithilfe von Objective-C und den zugehörigen Frameworks zu berücksichtigen sind und innerhalb sämtlicher bereitgestellter Frameworks einheitlich angewendet werden Fazit Bei der Entwicklung von iphone-applikationen ist die Auseinandersetzung mit der Programmiersprache Objective-C unumgänglich. Dennoch sollte die Sprache für Kenner von objektorientierten Programmiersprachen keine große Hürde darstellen. Die syntaktischen Erweiterungen der Sprache sind minimal und auf die zentralen Elemente der Objektorientierung beschränkt. So sind Protokolle eine gelungene Beschreibungsmöglichkeit für Schnittstellen, Kategorien eine elegante Möglichkeit zur Aufteilung von Funktionen oder Message-Forwarding eine leicht verständliche Alternative zur problembehafteten Mehrfachvererbung. Die Infix-Notation mag zu Beginn ungewohnt 32

49 4.5. Fazit wirken, kann jedoch bei korrekter Anwendung und bei der Verwendung von Parameterbezeichnungen zur Lesbarkeit des Quelltextes beitragen. Auch das von Smalltalk übernommene Konzept des Message-Passings ermöglicht zusammen mit der Reflexion zur Laufzeit die einfache Lösung vieler Probleme. Die Erweiterungen der Sprache in Version 2.0 ermöglichen unter anderem die automatisierte Erstellung von Zugriffsmethoden oder die vereinfachten Iteration über Collections, was letztendlich zu einer Minimierung des Aufwands bei sich wiederholenden Abschnitten führt und erneut zum besseren Verständnis des Quelltextes beiträgt. Zuletzt mag das Speichermanagement anfangs ungewohnt wirken, jedoch stellt dieses nach einer kurzen Eingewöhnungsphase eine sehr gute Möglichkeit dar, sogenannte Memory-Leaks 8 zu verhindern und den Speicherverbrauch der Applikation möglichst gering zu halten. Ob nun eine statisch ausgerichtete Programmiersprache, wie beispielsweise C++, oder eine dynamisch orientierte, wie Objective-C, besser oder schlechter ist, kann nicht undifferenziert beantwortet werden. Bei der Auswahl der geeigneten Programmiersprache ist das Anwendungsgebiet entscheidend. So bietet C++ viele Optimierungsmöglichkeiten an, die besonders die maschinennahe Programmierung unterstützen, die bei Verwendung von Objective-C-Sprachelementen gänzlich entfallen. Auch die Dynamik der Sprache führt zwangsläufig zu einer Verlangsamung der Programmausführung, da viele Aufrufe zuerst über Lookup-Tables aufgelöst werden müssen. Diese stellt jedoch bei Verwendung aktueller Hardware und, wie das iphone in der Praxis beweist, auf mobilen Endgeräten kein Problem mehr dar. Zusammen mit dem Foundation-Framework bildet Objective-C ein solides Fundament zur Entwicklung von modernen Desktop- und iphone-anwendungen, das besonders durch die dynamischen Elemente und das intelligente Speichermanagement in Verbindung mit dem Foundation-Framework zu gefallen weiß. 8 Objekte, für die Speicher reserviert und dieser nach erfolgter Verwendung zur Laufzeit nicht mehr freigegeben wird. 33

50

51 KAPITEL 5 Persistierung von Anwendungsdaten Ein wichtiges Thema der iphone-app-entwicklung ist die persistente Speicherung von Anwendungsdaten. Hierfür bieten sich dem Entwickler verschiedene Möglichkeiten, die im folgenden Abschnitt beschrieben werden. Im Anschluss wird das bei der Entwicklung verwendete Core-Data-Framework (vgl. zu diesem Kapitel [App09c; Zar09]) weiter erläutert und dem manuellen Zugriff über die SQLite-API gegenübergestellt. Die Entwicklung von performanten iphone-applikationen ist von großer Bedeutung. Dieser Anspruch wird nicht nur an die grafische Oberfläche (siehe Abschnitt 6.3) und an die hiermit interagierenden Controller gestellt, sondern auch an die Speicherung der Anwendungsdaten. Abschnitt 5.5 stellt einige Methodiken zur Optimierung des Persistenzmanagers und Datenmodells vor. Autor: Dominik Wilhelm Das Buch Core Data - Apple s API for Persisting Data on Mac OS X (siehe [Zar09]) sowie die vom Apple bereitgestellte Dokumentation Core Data Programming Guide (siehe [App09c]) bilden die Grundlage für den folgenden Abschnitt. 35

52 5. Persistierung von Anwendungsdaten 5.1. Gegenüberstellung verschiedener Techniken zur Persistierung von Daten Das iphone SDK bietet zur Speicherung von Anwendungsdaten verschiedene Möglichkeiten. Sechs dieser Varianten, die grob in drei Kategorien gegliedert werden können, werden an dieser Stelle kurz vorgestellt und miteinander verglichen Nutzung einer Dateistruktur Die manuelle Erstellung einer Dateistruktur ist die erste Methode, die für die Speicherung infrage kommt. Der Implementierungsaufwand ist jedoch immens. Das Öffnen, Einlesen, Speichern und Schließen der Dateien sowie die Aufrechterhaltung der Konsistenz der darin enthaltenen Daten muss vollständig implementiert werden. Bei zunehmender Komplexität der Anwendungsdaten wächst bei dieser Methode zudem der Verwaltungsaufwand. Alternativ hierzu bietet das Foundation Framework, ähnlich dem Serialisierungsmechanismus in Java, die Möglichkeit Klassen zu archivieren. Dies würde zwar den Aufwand reduzieren, jedoch sind die Daten hierbei nicht mehr plattformübergreifend nutzbar. In beiden Fällen liegen die Daten nach erfolgreichem Einlesevorgang komplett im Arbeitsspeicher und dies stellt im Falle von großen Datenmengen eine schlechte Möglichkeit der Datenverwaltung auf einer ressourcenbegrenzten Plattform dar Nutzung der Extensible Markup Language Die Speicherung mithilfe der Extensible Markup Language (kurz XML) ermöglicht eine bessere Datenstruktur, die auch von anderen Geräten verarbeitet werden kann. Der Entwickler muss sich auch bei Nutzung dieser Technologie um das Format und die Persistenz kümmern. Alternativ zu einem eigenen Format bietet sich die Nutzung sogenannter Property Lists (kurz Plists) an. Bei Nutzung dieser Variante kann zur Laufzeit eine Property List in ein NSArray oder ein NSDictionary geladen, oder im umgekehrten Fall der Inhalt dieser Datenstrukturen in einer Property List abgelegt werden. Hierbei wird vorausgesetzt, dass die Datenstrukturen gegen das Property-List-Format validieren. Der Vorteil der Property Lists gegenüber der direkten XML-Nutzung ist der 36

53 5.1. Gegenüberstellung verschiedener Techniken zur Persistierung von Daten Wegfall eines eigenen Parsingverhaltens, da dieses von den jeweiligen Collection-Klassen bereitgestellt wird. In beiden Fällen besteht jedoch dieselbe Problematik, die auch die bereits genannte, manuelle Speicherung mit sich bringt. Da auch hier die gesamte Datei eingelesen wird und somit der komplette Datenbestand im Arbeitsspeicher liegt, leidet bei großen Datenmengen die Performanz. Da XML-Dateien vor der Nutzung zunächst geparst werden müssen, reduziert sich die Performanz erneut und ist aufgrund dessen nur bei einem sehr geringen Datenvolumen zu empfehlen Nutzung von SQLite zur Persistierung von Datenstrukturen Die beste Variante, große Datenmengen zu sichern, stellt die Nutzung einer SQLite Datenbank dar, da hierbei nur die benötigten Daten im Arbeitsspeicher gehalten werden. Die Administration kann entweder direkt oder mithilfe des Persistenzmanagers Core Data realisiert werden. Während bei direktem Zugriff der Entwickler für die Ausarbeitung des Datenmodells und die Erzeugung der Datenbank verantwortlich ist, kann bei Nutzung von Core Data mithilfe des in Xcode integrierten Editors ein solches Modell, ähnlich einem Klassenmodell, erstellt werden. Die Generierung der zugrunde liegenden Datenbank geschieht hierbei automatisch zur Laufzeit. Bei direktem Zugriff muss vor Interaktion mit der Datenbank eine Verbindung zu dieser aufgebaut werden. Im Anschluss kann mithilfe von SQL-Anfragen mit der Datenbank gearbeitet werden. Core Data vereinfacht diesen Vorgang, indem es den Verbindungsaufbau übernimmt und mit den sogenannten Fetch-Requests eine etwas einfachere und übersichtliche Methode der Datenbankinteraktion bietet. Eine genauere Gegenüberstellung der direkten Nutzung mit Core Data erfolgt in Abschnitt

54 5. Persistierung von Anwendungsdaten 5.2. Das Framework Core Data In my experience of working with and writing persistence layers for various languages, I am constantly amazed at how simple and elegant the Core Data API is. (siehe [Zar09], Seite 51) Das Core-Data-Framework ging aus dem Web-Objects-Framework hervor, welches heute noch auf vielen Webseiten der Firma Apple eingesetzt wird 1. Core Data macht sich die Prinzipien des Key-Value-Coding (kurz KVC) und der Key-Value-Observation (kurz KVO) zunutze. Durch KVC kann zur Laufzeit dynamisch auf Variablen zugegriffen werden, ohne dass dies zu Speicherzugriffsfehlern führt (vgl. [App10l]). Im Falle einer Abfrage bzw. Änderung einer Variable werden mit Hilfe von KVO alle registrierten Beobachter benachrichtigt (vgl. [App09e]). Wie oft fälschlicherweise behauptet wird, handelt es sich bei Core Data nicht um ein Datenbanksystem. Das Framework ist vielmehr für die Verwaltung der darunter angesiedelten Datenquelle zuständig. Diese Quelle kann entweder aus Binärdateien oder Datenbanken bestehen 2. Core Data kümmert sich um die Persistenz und Validierung der Daten, stellt die Konsistenz der Relationen sicher und besitzt darüber hinaus ein Undo- bzw. Redomanagement. Zusätzlich verfügt das Framework über die Möglichkeit, die in der Datenquelle enthaltenen Daten durch Gruppierung und Filterung zu organisieren. Durch Nutzung des Core-Data-Framework wird die Komplexität der Anwendungsdatenspeicherung stark reduziert und erleichtert somit die Implementierung des Model-Parts (siehe Abschnitt 2.1.4) der Applikation. Im Folgenden wird der in Abbildung 5.1 gezeigte Core-Data-Stack weiter erläutert. Managed Object Context Der Managed Object Context ist für die Bildung des Objektgraphen verantwortlich und dient als zentrale Anlaufstelle für Anfragen an die Datenbank. Dieser gestattet zudem das Hinzufügen bzw. Löschen von Objekten, sammelt Änderungen an Attributen und 1 Beispielsweise 2 Auf dem iphone steht nur das Binär- und SQLite-Format zur Wahl, die Ausgabe als XML-Struktur entfällt. 38

55 5.2. Das Framework Core Data Managed Object Context Persistent Store Coordinator Managed Object Model Persistent Store Abbildung 5.1.: Der sogenannte Core Data Stack. Relationen und ermöglicht hierdurch das bereits erwähnte Undo- bzw. Redomanagement. Der Kontext hält temporäre Objekte (Managed Objects) der Datenbankobjekte und stellt die Validität der Werte und die Integrität der Relationen sicher. Innerhalb einer Applikation können mehrere Managed-Object-Context-Instanzen existieren, die jeweils ein temporäres Objekt eines Datenobjektes besitzen. Bei zeitgleichen Änderungen können Inkonsistenzen entstehen. In diesem Fall kann die Konsistenz bei Nutzung verschiedener bereitgestellter Methoden erfragt und somit gewahrt werden. Die an den Kontext gestellten Anfragen werden Fetch-Requests genannt. Diese enthalten den Namen der Entität und können die Ergebnismenge durch ein sogenanntes Predicate eingrenzen und mithilfe eines Sortierdeskriptors zusätzlich sortieren. Nachdem ein Fetch-Request gesendet wurde, wird dieser an den Persistent Store weitergeleitet, der die geforderten Objekte zurückliefert. Der Managed Object Context überprüft daraufhin, ob diese Objekte bereits ein zugeordnetes Managed Object besitzen. Ist dies der Fall, wird das bereits existierende Objekt an den Anfragesteller zurückgeliefert. Andernfalls wird ein temporäres Objekt erstellt und im Objektgraphen an geeigneter Stelle angehängt. Bei Zugriff auf ein mittels Relation verknüpftes Objekt wird dieses automatisch nachgeladen, ohne dass ein erneuter Fetch-Request gesendet werden muss. Der Objektgraph enthält somit nur die benötigten Elemente und bleibt hinsichtlich des Umfangs möglichst klein. 39

56 5. Persistierung von Anwendungsdaten Managed Object Alle Managed Objects sind entweder eine Subklasse oder Instanz der NSManagedObject- Klasse und dienen als Repräsentation der zugrundeliegenden Datenbankentitäten sowie der Abfrage und Manipulation des Datenbestandes. Jedes Managed Object besitzt eine Referenz zu seiner Entitätenbeschreibung und kennt den Managed Object Context, dem es angehört. Der Lebenszyklus dieser Objekte wird von Core Data und nicht vom Entwickler verwaltet. Persistent Store Coordinator Der Persistent Store Coordinator ist zwischen Managed Object Context und Persistent Store angesiedelt. Er stellt alle genutzten Persistent Stores als einen einzigen Store bereit und ist für das Routing der Anfragen an die einzelnen Stores zuständig. Der Persistent Store Coordinator kann nur mit einem einzigen Managed Object Model verbunden werden. Persistent Store Der Persistent Store hält die Verbindung zur eigentlichen Speicherquelle. Er ist für das Mapping zwischen den darin enthaltenen Daten und den Objekten im Managed Object Context verantwortlich. Der Persistent Store sollte niemals direkt angesprochen und nur für die Initiierung eines Speicher- oder Ladevorgangs verwendet werden. Managed Object Model Um die Graph- und Objektpersistenz zu gewährleisten, benötigt Core Data möglichst viele Informationen über die zu verwaltenden Objekte. Das sogenannte Managed Object Model stellt diese Informationen bereit. Im Normalfall kann dies mithilfe des in Xcode integrierten Data-Model-Tools ausgeführt werden. Das im Xdatamodel- Format vorliegende Modell wird während des Kompilierungsvorgangs in ein Binärformat konvertiert und den Ressourcen der Applikation hinzugefügt. Das Managed Object Model enthält eine Ansammlung von Entity-Descriptions. Diese Objektbeschreibungen 40

57 5.3. Das Framework Core Data im Vergleich zur SQLite-API bestehen aus dem Namen, dem zugehörigen Klassennamen, den Attributen und den Relationen der betreffenden Entität. Die Attribute und Relationen werden mithilfe von Attribute- bzw. Relation-Descriptions beschrieben Das Framework Core Data im Vergleich zur SQLite- API Zur Nutzung von SQLite kann, alternativ zu Core Data, die offizielle SQLite-API verwendet werden (vgl. zu diesem Abschnitt [SQL10]). Die Frage, welche Variante besser ist, ist vom Typ und den Anforderungen des Projekts abhängig. Soll eine Anwendung auf Basis einer bestehenden Datenbank entwickelt bzw. eine bestehende Datenbank in eine Anwendung integriert werden, so bietet sich der direkte SQLite-Zugriff an. Wird die Applikation von Grund auf entwickelt und umschließt somit auch den Entwurf einer Datenbank, ist die Nutzung von Core Data zu bevorzugen. Dieser Abschnitt stellt die beiden Varianten gegenüber und verdeutlicht die Vorteile von Core Data im Gegensatz zur Nutzung der SQLite-API anhand eines einfach gehaltenen Beispiels Initialisierung einer Datenbankverbindung Bevor die Datenbank genutzt werden kann, muss diese zunächst erzeugt werden. Dies geschieht bei Verwendung der SQLite-API über die Kommandozeile oder einen Datenbankeditor und muss anschließend in das Projekt eingebunden werden. Bei Nutzung von Core Data kann mit dem schon genannten Data-Model-Tool ein Datenmodell erstellt werden, das während des Kompiliervorgangs automatisch bereitgestellt wird. Die Klassen und Methoden, die für die Überführung und Synchronisation von Datenstrukturen zuständig sind, müssen bei Nutzung der SQLite-API manuell erstellt werden. Bei Verwendung von Core Data kann die automatische Generierung dieser Klassen durch die IDE Xcode genutzt werden. Sämtliche Zugriffsmethoden werden in diesem Fall dynamisch bereitgestellt oder stehen durch Vererbung 3 zur Verfügung. Nachdem die Vorbedingungen erfüllt sind, kann die Datenbank im Programm initialisiert und genutzt werden. Im Fall von Core Data müssen hierzu zuerst der Managed Object 3 Die generierten Klassen erben von der NSManagedObject-Klasse. 41

58 5. Persistierung von Anwendungsdaten Context, der Persistent Store Coordinator und das Managed Object Model angelegt werden. 1 // Pfad zur Momd-Datei ermitteln 2 NSURL * pfad = [[[NSURL alloc] initfileurlwithpath:[[nsbundle mainbundle] autorelease]; 3 // Managed Object Model anlegen 4 NSManagedObjectModel * managedobjectmodel = [[NSManagedObjectModel alloc] initwithcontentsofurl:pfad]; 5 // Persistent Store Coordinator anlegen 6 NSPersistentStoreCoordinator * persistentstorecoordinator = [[ NSPersistentStoreCoordinator alloc] initwithmanagedobjectmodel: managedobjectmodel]; 7 8 NSString * nutzerverzeichnis = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES) lastobject]; 9 NSURL * persistentstorecoordinatorpfad = [NSURL fileurlwithpath: [ nutzerverzeichnis 10 NSError * error = nil; 11 // Dem Persistent Store Coordinator einen SQLite-Store zuweisen 12 [persistentstorecoordinator addpersistentstorewithtype:nssqlitestoretype configuration:nil URL:persistentStoreCoordinatorPfad options:nil error :&error]; 13 // Den Managed Object Context anlegen und den Persistent Store Coordinator setzen 14 NSManagedObjectContext * managedobjectcontext = [[NSManagedObjectContext alloc] init]; 15 [managedobjectcontext setpersistentstorecoordinator: persistentstorecoordinator]; // Arbeit an der Datenbank Listing 5.1: Initialisierung von Core Data und Verbindung mit der Datenbank. Wie in Listing 5.1 gezeigt, wird für die Initialisierung des Managed Object Context zuerst der Persistent Store Coordinator und für dessen Initialisierung das Managed Object Model benötigt. Da, wie bereits erwähnt, die Xdatamodel-Datei während des Übersetzungsvorgangs in eine Mom-Datei umgewandelt wird und danach im Ressourcenordner der Applikation liegt, müssen bei der Initialisierung des Models dieser Pfad und das Format übergeben werden. Der Persistent Store Coordinator benötigt neben dem Verzeichnis, in dem die Datenbank liegt, auch die Beschreibung der Datenbank. 42

59 5.3. Das Framework Core Data im Vergleich zur SQLite-API Existiert die Datenbank nicht, so wird sie angelegt. Wenn die Applikation mehrere Stores benötigt, müssen diese mit der addpersistentstorewithtype-methode dem Coordinator hinzugefügt werden. Nachdem nun auch der Persistent Store Coordinator bereit steht, kann zu guter Letzt der Managed Object Context angelegt werden. Listing 5.2 zeigt die Initialisierung der Datenbank mithilfe der SQLite-API. 1 sqlite3 * datenbank = NULL; 2 3 // Pfad zur Datenbank 4 NSString * pfad = [[NSBundle mainbundle] "sqlite"]; 5 6 // Datenbank oeffnen 7 if (sqlite3_open([pfad cstringusingencoding:nsasciistringencoding], & datenbank) == SQLITE_OK) { 8 // Arbeit an der Datenbank 9 } 10 sqlite3_close(datenbank); Listing 5.2: Initialisierung der SQLite-Datenbank und Aufbau der Verbindung Abruf von Datensätzen Um Datensätze bzw. Datenobjekte aus der Datenbank abzurufen, muss ein Fetch- Request an den Managed Object Context übergeben werden. Dieser Request muss den Namen der Entität enthalten und kann zusätzlich Eingrenzungen und Sortierungen, in Form von NSPredicate und NSSortDescriptor, enthalten. 1 NSFetchRequest * request = [[NSFetchRequest alloc] init]; 2 3 // Ermitteln und setzen der Entity 4 NSEntityDescription * entity = [NSEntityDescription inmanagedobjectcontext:managedobjectcontext]; 5 [request setentity:entity]; 6 7 // Objekte anhand der Variable "Name" filtern 8 NSPredicate * predicate = [NSPredicate == Brasilien "]; 9 [request setpredicate:predicate]; 10 43

60 5. Persistierung von Anwendungsdaten 11 // Nach Datum sortieren 12 NSSortDescriptor * sort = [[[NSSortDescriptor alloc] DatumVon" ascending:yes] autorelease]; 13 NSArray * sortarray = [NSArray arraywithobject:sort]; 14 [request setsortdescriptors:sortarray]; // Maximal 5 Ergebnisse 17 [request setfetchlimit:5]; // Request ausfuehren und Ergebnis sichern 20 NSArray * reisen = [managedobjectcontext executefetchrequest:request error :nil]; 21 [request release]; Listing 5.3: Abruf aller Reisen nach Brasilien, sortiert nach Datum und limitiert auf fünf Ergebnisse. Parallel zu den im Rahmen von Core Data vorgestellten Fetch-Requests müssen, bei Verwendung der SQLite-API, SQL-Statements erstellt werden. Diese Statements müssen aus Performanzgründen kompiliert, die darin enthaltenen Parameter mithilfe der SQLite3-Bind-Methoden an Werte gebunden und die Datensätze nacheinander einem Array hinzugefügt oder direkt verarbeitet werden. Das folgende Beispiel speichert die Daten in eigens erstellten Objekten, die wiederum in einem Array gesammelt werden. 1 // Aufbau der Datenbankverbindung 2 3 NSMutableArray * reisen = [NSMutableArray array]; 4 const char * statement = "SELECT Name,Beschreibung,Von,Bis FROM Reisen WHERE Name =? ORDER BY Von ASC LIMIT 0, 5"; 5 6 sqlite3_stmt * compiledstatement; 7 8 // Statement kompilieren 9 if(sqlite3_prepare_v2(datenbank, statement, -1, &compiledstatement, NULL) == SQLITE_OK) { 10 // Filter setzen 11 sqlite3_bind_text(compiledstatement, 1, "Brasilien", -1, SQLITE_TRANSIENT); 12 // Ergebnisse durchlaufen und Werte formatieren 13 while(sqlite3_step(compiledstatement) == SQLITE_ROW) { 14 NSString * name = [NSString stringwithutf8string:(char *) sqlite3_column_text(compiledstatement, 0)]; 44

61 5.3. Das Framework Core Data im Vergleich zur SQLite-API 15 NSString * beschreibung = [NSString stringwithutf8string:(char *) sqlite3_column_text(compiledstatement, 1)]; 16 NSDate * von = [NSDate datewithtimeintervalsince1970: sqlite3_column_double(compiledstatement, 2)]; 17 NSDate * bis = [NSDate datewithtimeintervalsince1970: sqlite3_column_double(compiledstatement, 3)]; 18 // Formatierte Werte in spezieller Datenklasse speichern 19 Reise * reise = [[Reise alloc] initwithname:name anddescription: beschreibung from:von until:bis]; 20 // Datenklasse in Array ablegen 21 [reisen addobject:reise]; 22 [reise release]; 23 } 24 } 25 sqlite3_finalize(compiledstatement); // Datenbankverbindung beenden Listing 5.4: Abruf aller Reisen nach Brasilien mit den gleichen Einschränkungen. Der Entwickler muss, um mit der Datenbank arbeiten zu können, das zugrundeliegende Datenmodell kennen Hinzufügen von Datensätzen Bei Nutzung der SQLite-API muss, analog zu dem in Listing 5.4 dargestellten Vorgang, zunächst ein Insert-Statement erstellt werden und die zu speichernden Daten vor der Ausführung dessen bekannt sein. Core Data ermöglicht hingegen die Erstellung eines Managed Objects und somit die Möglichkeit, dieses direkt mit Werten zu füllen. 1 NSManagedObject * managedobject = [NSEntityDescription inmanagedobjectcontext: managedobjectcontext]; 2 Reise * reise = (Reise *) managedobject; 3 reise.name 4 reise.beschreibung 5 6 [managedobjectcontext save:nil]; Listing 5.5: Hinzufügen von neuen Datenobjekten mit Core Data. 45

62 5. Persistierung von Anwendungsdaten Wie in Listing 5.5 zu sehen ist, kann durch Nutzung der Akzessoren direkt auf die Attribute zugegriffen werden Änderungen von Datensätzen Die Änderung von Datensätzen unterscheidet sich bei beiden Varianten nur marginal von den bisher vorgestellten Methoden zum Abrufen und Hinzufügen von Datensätzen. Im Fall von Core Data wird mit einem Fetch-Request das gewünschte Objekt abgerufen und wie in Listing 5.5 gezeigt die Werte verändert. Ein SQL-Update-Statement wird bei Nutzung der SQLite-API benötigt Löschen von Datensätzen Zur Löschung eines Datenobjektes mit direkter SQLite-Anbindung wird mithilfe des Delete-Befehls realisiert und unterscheidet sich im Ablauf nicht von den bereits vorgestellten Datenbankinteraktionen. Core Datas Managed Object Context bietet hierfür die Methode deleteobject:(nsmanagedobject *), der lediglich das zu löschende Objekt übergeben werden muss Der Umgang mit Relationen Core Data validiert sämtliche angegebenen Werte vor der eigentlichen Sicherung des Managed Object. Dies trifft auch auf Relationen zu. Wird ein über eine Relation verknüpftes Objekt mit Zuhilfenahme der dynamisch generierten Methoden hinzugefügt oder gelöscht, so geschieht dies automatisch auf der Gegenseite der Relation. Core Data stellt somit zu jeder Zeit die Integrität der Relationen und die Konsistenz der Daten sicher. Bei direkter SQLite-Nutzung liegt diese Aufgabe in den Händen des Entwicklers. Der Zugriff auf ein über eine Relation verknüpftes Objekt kann mit Core Data über den entsprechenden Akzessor durchgeführt werden. Core Data lädt in diesem Fall automatisch das gewünschte Objekt aus der Datenbank nach. Bei direkter Nutzung muss hier das gewünschte Objekt mit einer erneuten Select-Anfrage nachträglich abgefragt werden. 46

63 5.4. Migration und Versionierung mithilfe des Core-Data-Framework 5.4. Migration und Versionierung mithilfe des Core-Data- Framework Auch bei der Wartung einer bestehenden und bereits im Verkauf befindlichen Anwendung spielt Core Data seine Stärken aus. Das in Xcode integrierte Werkzeug zur Erzeugung des Datenmodells erlaubt die Versionierung von Datenmodellen, die für etwaige Migrationen als Vorlage dienen. Der Migrierungsvorgang kann vom Persistent Store Coordinator automatisch oder alternativ manuell durchgeführt werden, was jedoch nur bei komplexen Änderungen zu empfehlen ist. Mithilfe dieser Technik kann auf recht einfachem Weg das Datenmodell wartbar und aktuell gehalten werden Optimierung des Datenmodells und des Persistenzmanagers Neben der Optimierung sämtlicher Programmaufrufe bietet sich auch die Optimierung des Datenmodells und des zugehörigen Persistenzmanagers an. Dies betrifft nicht nur die Reduzierung des genutzten Arbeitsspeichers, sondern auch die Geschwindigkeit, in der die Daten zur Verfügung gestellt werden. Die folgenden Optimierungen werden zur besseren Verständlichkeit anhand eines Beispiels erläutert. Zu jeder Reise kann der Gesamtkontostand berechnet werden. Dieser wird durch die Addition sämtlicher Buchungsbeträge kalkuliert Faultingverhalten Da, wie bereits erwähnt, der vom Managed Object Context verwaltete Objektgraph möglichst klein gehalten werden soll, werden stets nur die angeforderten Objekte geladen. Dies bedeutet, dass über Relationen verknüpfte Objekte durch Platzhalter (sogenannte Faults) repräsentiert werden. Erst bei einem Zugriff wird der eigentliche Inhalt dieser aus der Datenbank geladen. Dieses Verhalten ist unter dem Namen Faulting bekannt. Auf das oben beschriebene Beispiel angewendet bedeutet dies, dass bei der Berechnung des Gesamtkontostands auf den Betrag jeder mit der Reise verknüpften Buchung zugegriffen wird. Hierbei werden die gefaulteten Objekte aufgelöst 47

64 5. Persistierung von Anwendungsdaten und in den Arbeitsspeicher geladen. Da der Lebenszyklus dieser Objekte von Core Data verwaltet wird, ist nicht ersichtlich, wann diese Objekte wieder aus dem Speicher entfernt werden. Um die Speicherauslastung zu reduzieren, kann nach Nutzung der Daten das Objekt explizit gefaultet werden. Diese Maßnahme bewirkt, dass die nicht mehr benötigten Objekte wieder durch kleinere Platzhalterobjekte ersetzt werden und somit die Speicherauslastung reduziert wird Auslagerung von Binärdaten Das in Abbildung 5.2 gezeigte Model ermöglicht die Speicherung eines Bildes in der Buchungsklasse. Reise Attribute: Beschreibung : string DatumBis : string DatumVon: string Name: string 1 0..* Buchung Attribute: Bild : binary Betrag : float Abbildung 5.2.: Reduzierte Abbildung der Exkursions- und Buchungsklasse. Im Falle eines großen Datenbestands, zum Beispiel bei einer Reise mit vielen existierenden Buchungen, die jeweils ein Bild in Form eines BLOBs enthalten, wächst der Speicherbedarf bei der Berechnung des Gesamtkontostands enorm. Um dem entgegenzuwirken, müssen Binärdaten, in diesem Fall die Bilder, in einer eigenen Entität ausgelagert werden (siehe Abbildung 5.3). Dies bedeutet, dass bei Berechnung des Kontostands die Buchungen nachgeladen werden, die Bildobjekte aber nach wie vor gefaultet bleiben und somit nicht unnötig Speicher belegen Intelligente Relationen Wie bereits erwähnt, stellt Core Data die Integrität der Relationen zu jeder Zeit sicher. Dies bedeutet, dass im Fall der Löschung eines Objektes, die Inversen der Relationen angepasst werden müssen. Mithilfe des Data-Model-Tools kann die Art 48

65 5.5. Optimierung des Datenmodells und des Persistenzmanagers Reise Attribute: Beschreibung : string DatumBis : string DatumVon: string Name: string Buchung 1 0..* Attribute: Betrag : float Bild Attribute: Bild: binary Abbildung 5.3.: Reise- und Buchungsklasse nach Auslagerung des Bildes. und Weise, in der die Inverse verändert wird, eingestellt werden. Standardmäßig wird die inverse Relation bei Löschung eines Objekts genullt. Im oben aufgeführten Beispiel würde dies zu verwaisten Buchungsobjekten führen. Um dieses Problem zu beheben, könnten natürlich vor der Löschung der Reise manuell alle Buchungen entfernt werden. Eine bessere Lösung stellt jedoch die Nutzung des Löschverhaltens Cascade dar. Dies bedeutet, dass bei Löschung einer Reise die verknüpften Buchungen automatisch entfernt werden. Bei Löschung eines Währungsobjekts würden damit verknüpfte Buchungen ungültig werden. Dies bedeutet, dass solch ein Datenobjekt nur gelöscht werden kann, wenn kein Buchungsobjekt in Relation zu diesem steht. Um hier den Verwaltungsaufwand zu reduzieren, kann das Löschverhalten der Relation auf Deny gesetzt werden. Diese Einstellung bewirkt, dass eine Währung nur dann gelöscht werden kann, sobald keine weiteren Buchungsobjekte mit dieser verknüpft sind. Darüber hinaus existiert die No-Action-Option, die die Relation im Falle einer Löschung unberührt belässt. In diesem Fall ist die Konsistenz des Graphen nicht mehr gewährleistet und die Erhaltung dieser liegt in den Händen des Entwicklers. Neben dem Löschverhalten kann auch die minimale oder maximale Anzahl der verknüpften Datenobjekte bestimmt werden und somit zusätzliche Validierungsabfragen eingespart werden Weitere Optimierungen Neben diesen drei Methoden bieten sich noch weitere Möglichkeiten an, die Datenbank zu optimieren. So sollte bei Nutzung einer Relation stets eine Inverse erstellt werden. Diese Maßnahme wird von Core Data benötigt, um die Integrität der Relationen effizienter und somit schneller sicherzustellen. Wie in Listing 5.3 zu sehen ist, kann die 49

66 5. Persistierung von Anwendungsdaten Ergebnismenge auf eine bestimmte Anzahl limitiert werden. Dies macht immer dann Sinn, wenn vorab bekannt ist, wie viele Datensätze maximal benötigt werden. Ein Beispiel hierfür wäre die Darstellung der zehn teuersten Buchungen. Steht zu Beginn oder während der Entwicklung fest, dass der Undo-Manager nicht benötigt wird, kann dieser mithilfe des in Listing 5.6 gezeigten Befehls deaktiviert werden. 1 [managedobjectcontext setundomanager:nil]; Listing 5.6: Deaktivierung des Undo-Managers Fazit Die Nutzung des Core-Data-Framework erleichtert die Entwicklung einer Applikation ungemein. Mit relativ wenig Aufwand kann ein Datenmodell erstellt und die darin enthaltenen Entitäten automatisch generiert werden. Diese Entitätsklassen müssen lediglich an entsprechender Stelle eingebunden werden und sind im Anschluss vollständig objektorientiert verwendbar. Auch wenn die Integration des Core Data Stacks auf den ersten Blick aufwendiger wirkt, als beispielsweise die direkte Nutzung einer SQLite-Datenbank, so zahlt sich dieser Mehraufwand schnell aus. Die gesamte Interaktion mit der Datenbank kann unter Zuhilfenahme von Core Data mit weniger Aufwand als mit der Nutzung der SQLite-API umgesetzt werden. Der entstehende Quellcode ist somit übersichtlicher und einfacher zu warten. Die Nutzung einer SQLite- Datenbank als Speicherungsstruktur für Core Data hat aufgrund der in Abschnitt 5.1 aufgezeigten Punkte einen klaren Vorteil gegenüber den vorgestellten Alternativen. Da die Datenbank hierbei niemals vollständig im Arbeitsspeicher abgelegt wird, stellt dies eine besonders effiziente Methode der Datenspeicherung dar, die die Performanz gemeinsam mit den in Kapitel 6 entwickelten Klassen verbessert. Durch Optimierungen der Datenbank bzw. des Persistenzmanagers kann, wie gezeigt wurde, die Performanz weiter verbessert werden. 50

67 KAPITEL 6 Entwicklung und Optimierung von iphone-applikationen In Kapitel 4 und 5 wurden zwei fundamentale Bestandteile der iphone-entwicklung diskutiert: die Programmiersprache Objective-C und die Auswahl einer Methodik zur Serialisierung von Objekten. Für die Serialisierung wurde an dieser Stelle besonders der durch das iphone SDK bereitgestellte Persistenzmanger Core Data betont. Hierauf aufbauend dient dieses Kapitel zur Analyse zentraler Aspekte der iphone-entwicklung und der Präsentation möglicher Lösungsansätze zu wiederkehrenden Problemstellungen. Autor: Benjamin Glatzel Innerhalb des Abschnitts 6.1 wird zunächst die Entwicklung einer möglichst wartbaren und erweiterbaren Softwarearchitektur besprochen. Hierbei werden die durch das Framework UIKit propagierten Entwurfsmuster in die Gestaltung mit einbezogen und erweiterte Techniken zur Vermeidung von Redundanzen bei der Implementierung von Eingabemasken oder Serverkommunikationsfunktionalitäten erläutert. Für die Entwicklung von iphone-applikationen mit gesondertem Look-And-Feel nehmen die Frameworks Core Animation und Core Graphics eine zentrale Position ein. Abschnitte 6.2 und 6.4 dienen der Erörterung beider Frameworks, der Demonstration ihrer Möglichkeiten und letztendlich der Bereitstellung von dynamisch erzeugten Grafiken sowie angepassten Animationen im Kontext des iphone-benutzerinterface. Die Reaktivität 51

68 6. Entwicklung und Optimierung von iphone-applikationen und Effizienz des Benutzerinterface spielt bei der App-Entwicklung eine besondere Rolle und trägt maßgeblich zur Zufriedenheit der Endbenutzer bei. Viele Beispiele der offiziellen Dokumentation des iphone SDK zeigen bei der Ausführung auf dem Endgerät eine unzureichende Ausführungsgeschwindigkeit. Innerhalb des Abschnitts 6.3 werden aufgrund dessen Methodiken erläutert, welche dieses Defizit durch die Implementierung eines Caching-Algorithmus und spezieller Tabellenzellen kompensieren. Die Bereitstellung von Lite-Versionen, sprich Versionen mit gesondertem, meist reduziertem, Funktionsumfang haben sich innerhalb des App Store etabliert. Innerhalb des Abschnitts 6.5 wird eine Methodik besprochen, welche die Entwicklung dieser auf gleicher Codebasis zur Vollversion ermöglicht. Das Kapitel wird mit einer Diskussion des Apple-Review-Prozesses abgeschlossen (siehe Abschnitt 6.6) Diskurs der Softwarearchitektur Autor: Dominik Wilhelm Wie jedes größere Softwareprojekt sollte auch die Entwicklung einer iphone-applikation nach den Grundprinzipien eines guten Softwaredesigns erfolgen, sodass die Wartbarkeit und Erweiterbarkeit des Projekts gefördert wird. In den folgenden Abschnitten werden verschiedene Kernklassen vorgestellt, die die genannten Grundprinzipien auf die Entwicklung von iphone-applikationen übertragen Entwicklung einer Designgrundlage für Tabellenansichten Bei der Entwicklung von iphone-applikationen muss, wie in Abschnitt bereits erwähnt wurde, auf die strikte Anwendung des MVC-Patterns geachtet werden. Dies bedeutet, dass die Oberfläche von der Logik und den Anwendungsdaten separiert entwickelt werden kann. Das iphone SDK bietet hierfür ein entsprechendes Werkzeug. Der sogenannte Interface Builder ist eine Art grafischer Designer, mit dessen Hilfe eine funktionstüchtige Oberfläche, sprich der View-Part des MVC-Patterns, besonders komfortabel erstellt werden kann. Diese Views bestehen in der Regel aus mehreren GUI-Elementen und werden im Xib-Format gespeichert und zur Kompilierzeit in das Nib-Format umgewandelt. Das Xib-Format basiert auf XML und kann somit besser von Versionierungssystemen verwaltet werden. Innerhalb der entsprechenden Controllerklasse kann mithilfe der Methode initwithnibname die in der zugehörigen Nib-Datei 52

69 6.1. Diskurs der Softwarearchitektur enthaltene View geladen werden. Durch Nutzung der Schlüsselworte IBOutlet vor Variablen und IBAction vor Methoden kann während der Erstellung einer View, innerhalb des Quellcodes (siehe Listing 6.1), eine Verbindung zwischen diesen Ankerpunkten und den zugeordneten GUI-Elementen hergestellt werden. ExampleAppDelegate : NSObject <UIApplicationDelegate> { 2 UIWindow *window; 3 UIButton * mysubmitbutton; 4 } 5 (nonatomic, retain) IBOutlet UIWindow *window; (nonatomic, retain) IBOutlet UIButton * mysubmitbutton; 8 Listing 6.1: Mit IBOutlet versehene Variable. Durch die Dynamik der Sprache Objective-C kann die Applikation Interface Builder dynamisch die Verknüpfung zu Methoden und Attributen herstellen, indem der entsprechende Controller nach den genannten Markierungen durchsucht wird und diese innerhalb der Programmoberfläche zur Verfügung stellt. Durch Verbindung der Variable mit dem Anzeigeobjekt, wie in Abbildung 6.1 gezeigt, kann eine Verknüpfung hergestellt werden. Intern werden diese Markierungen bei Kompilierung des Programmcodes entfernt bzw. genullt und haben keinen weiteren Einfluss. Abbildung 6.1.: Verbindung einer Variablen mit einem GUI-Element. Ein Nachteil dieser Methode ist, dass für jede individuelle View eine eigene Xib-Datei erzeugt werden muss. Im Falle einer Designänderung müssten hierbei alle Views erneut 53

70 6. Entwicklung und Optimierung von iphone-applikationen angepasst werden. Um den Arbeitsaufwand bei der Implementierung zu reduzieren, kann eine Basisklasse entwickelt werden, die die Grundversion des Designs implementiert. Dies bedeutet im Fall einer auf Tabellen zur Datenpräsentation ausgelegten Applikation, dass es genau eine Xib-Datei gibt, die den grundlegenden Aufbau der View definiert. Diese View wird von einem entsprechenden View-Controller geladen und das Basisverhalten bzw. Aussehen angepasst. Alle weiteren View-Controller, die auf diesem Tabellendesign basieren sollen, erben von dieser View-Controller-Klasse und erhalten somit ein identisches Design und Verhalten. Diese Maßnahme reduziert neben dem Arbeitsaufwand auch die Konsistenz des Designs, da bei Änderungen nur noch diese eine Xib-Datei bzw. der Basis-View-Controller angepasst werden muss. Abbildung 6.2 zeigt eine Beispielimplementation dieses Konzepts. Die sogenannte WTTableViewController-Klasse erbt von der UIViewController-Klasse und bindet die für die Tabellen benötigten Delegaten-Protokolle ein. Alle View-Controller, die von der sogenannten WTTableViewController-Klasse erben, erhalten somit deren schon implementierte Methoden und müssen nur noch die in Abbildung 6.2 gezeigten Methoden überschreiben, um die Tabelle mit den entsprechenden Daten zu füllen. UIViewController WTTableViewController mytableview : UITableView mytoolbar : UIToolbar myhelpimageview : UIImageView myheaders : NSMutableDictionary +cellforrowatindexpath(tableview : UITableView, indexpath : NSIndexPath) : UITableViewCell +numberofsectionsintableview(tableview : UITableView) : NSInteger +numberofrowsinsection(section : NSInteger) : NSInteger +titleforheaderinsection(section : NSInteger) : NSString UIVIew HeaderView mytitle : NSString myheaderbackgroundimage : UIImage myheadermainfont : UIFont +initwithtitle(title : NSString) {disjoint,incomplete} MainMenuViewController SettingsViewController Abbildung 6.2.: Vererbung des Tabellendesigns und Verhaltens an alle Views. 54

71 6.1. Diskurs der Softwarearchitektur Gemäß dem in Abschnitt erläuterten Composite-Pattern besteht eine Tabelle aus mehreren UIView-Objekten. Kopf- und Fußzeilen basieren auf dieser Klasse und können durch Nutzung selbst erstellter UIView-Elemente an das Designkonzept angepasst werden. Die Erstellung eigener Kopfzeilen wird von der WTTableViewController-Klasse mithilfe der in Listing 6.2 gezeigten Methode realisiert. 1 - (UIView *)tableview:(uitableview *)tableview viewforheaderinsection:( NSInteger) section { 2 NSString * title = nil; 3 if (title = [self tableview:self.mytableview titleforheaderinsection: section]) 4 return [self buildheaderwithtitle:title addsuffix:[[self class] description]]; 5 else 6 return nil; 7 } Listing 6.2: Die Generierung der Kopfzeilen. Die UIView-Objekte, die die Kopfzeilen repräsentieren, werden zusätzlich mittels Caching effizient verwaltet, sodass deren Anzeige stets ohne Verzögerung durchgeführt werden kann. Dieses Cachingverhalten ist mittels der buildheaderwithtitle-methode realisiert und wird in Abschnitt näher erläutert. Neben der Individualisierung der Kopfzeilen ermöglicht die Basisklasse zudem die Darstellung von Hilfsnachrichten. Diese kurzen Informationen sollen den Benutzer während der Nutzung der Applikation unterstützen und stellen eine intuitive Variante einer Hilfsfunktion dar. Die Einblendung dieser Hilfsbilder ist bei initialer Nutzung der Anwendung nützlich, da sich die Benutzer einfacher mit dieser vertraut machen können. Die WTTableViewController-Klasse stellt Methoden zur Ein- und Ausblendung der Hilfsgrafiken bereit und alle von dieser Klasse erbenden Controller können die Darstellung durch Übergabe von Bildobjekten beeinflussen. Da die Tabellen nicht statisch sind, sprich die Manipulation des Datenbestands ermöglicht wird, können diese durch den Benutzer geleert werden. Auch in diesem Fall sollte automatisch ein Hilfsbild erscheinen. Um gemäß den Prinzipien für ein gutes Softwaredesign Redundanzen zu vermeiden, besitzt die WTTableViewController-Klasse eine weitere Variante der Hilfsanzeige- Methode. Die sogenannte showhelpimageatminimalcellamount-methode blendet das Hilfsbild bei einer Unterschreitung der übergebenen, minimalen Zellenanzahl ein. 55

72 6. Entwicklung und Optimierung von iphone-applikationen Abbildung 6.3.: Die individuellen Kopfzeilen und Zellen in Verbindung mit der Darstellung einer Hilfsnachricht im Vergleich zu einer normalen Tabelle Abbildung 6.3 zeigt das Hauptmenü von wetravel nach initialem Start der Anwendung. Neben den eigenen Kopfzeilen und den in Abschnitt beschriebenen Tabellenzellen kommt hier auch die angesprochene Hilfsfunktion zur Anwendung Generierung eigener Objekt-IDs mithilfe einer Basisklasse Core Data generiert für jedes Datenobjekt implizit eine ID. Die sogenannte Objekt-ID ist systemübergreifend eindeutig und kann nicht verändert werden. Bei Durchführung von Datenbankmigrationen stellte sich heraus, dass diese im Endergebnis zwischen Datenbankobjekten gewandert sind. Dieses Verhalten konnte unter Zuhilfenahme der Dokumentation nicht geklärt werden. Betrachtet man dieses Problem in Hinblick auf eine sich im Vertrieb befindende iphone-applikation, kann dies zu weitreichenden Problemen führen. Die Objekt-IDs können in bestimmten Fällen beispielsweise zur Speicherung von Einstellungen vermerkt werden. Wird bei der Entwicklung eines Updates eine Änderung an der Datenbank nötig, wird die in den Einstellungen gespeicherte Objekt-ID durch die Ausführung einer Migration bei sämtlichen Endbenutzern mit hoher Wahrscheinlichkeit ungültig. Die entstehenden Probleme können verschiedener Natur sein: Bei Betrachtung der Applikation wetravel hat dies zur Folge, dass die aktuell ausgewählte Reise nach erfolgter Migration zufällig getauscht wird. Auch bei 56

73 6.1. Diskurs der Softwarearchitektur der Übertragung von Buchungsreporten (siehe Listing B.1) kommen die Objekt-IDs zur Zuordnung von Entitäten zwischen iphone- und Webapplikation zum Einsatz. Durch eine zufällige Änderung dieser kann diese Zuordnung nicht mehr gewährleistet werden. Um diese Problematik zu umgehen, bietet sich der Einsatz einer manuell erzeugten ID an, die unabhängig von der Objekt-ID den Entitäten zugeordnet wird. Um diese ID nun allen relevanten Datenobjekten zuweisen zu können, bietet sich die Implementierung einer Basisklasse für sämtliche betroffenen Datenbankentitäten an, welche innerhalb dieses Beispiels als WTBase benannt ist. Abbildung 6.4 zeigt alle Datenentitäten, die für die Erzeugung eines Buchungsreports nötig sind und die hierarchische Anordnung zur Zuordnung der individuellen Objekt-ID. Für die Übertragung relevante Entitäten WTBase Stellt Objekt-ID zur Verfügung. Excursion 0..* 1 0..* 1 Exchange 0..* Participant 1..* 0..* 0..* Booking Abbildung 6.4.: Von WTBase erbende Entitäten. Wie in Listing 6.3 zu erkennen ist, besitzt diese Basisklasse lediglich eine Variable zur Speicherung der ID mit zugehöriger Zugriffsmethode sowie eine Erzeugungsfunktion, die bei Aufruf eine eindeutige ID generiert. 1 - (void) generateuniqueid { 2 3 if (![self { 4 CFUUIDRef theuuid = CFUUIDCreate(NULL); 5 CFStringRef string = CFUUIDCreateString(NULL, theuuid); 6 7 [self 8 [self setprimitivevalue:(nsstring *)string 9 [self 57

74 6. Entwicklung und Optimierung von iphone-applikationen CFRelease(string); 12 CFRelease(theUUID); 13 } 14 } (NSString *) uniqueid { 17 [self generateuniqueid]; 18 return [self 19 } Listing 6.3: Generierung der eigenen ID. Bei Aufruf der Zugriffsmethode wird zuerst die Generierungsfunktion aufgerufen. Falls für dieses Objekt keine ID generiert wurde, wird Core Data über eine anstehende Änderung informiert, die ID gesetzt und Core Data abschließend über die erfolgte Änderung in Kenntnis gesetzt. Nach Abschluss dieser Methode wird die soeben generierte ID zurückgegeben Erstellung einer Schnittstelle zur Datenbankkommunikation Jeder View-Controller innerhalb von iphone-applikationen dient der Bereitstellung und Aktualisierung von Daten. Um diesen Vorgang und den Umgang mit Core Data zu erleichtern und den Grundprinzipien eines guten Softwaredesigns gerecht zu werden, empfiehlt sich die Implementierung einer Wrapper-Klasse, die den Core Data Stack initialisiert und den Controllern die Kommunikation mit der Datenbank ermöglicht. Diese Klasse, in wetravel WTCentral genannt, bietet den Controllern alle benötigten Funktionalitäten, um mit Datenobjekten zu interagieren. Da es in diesem Fall ausreicht nur eine Instanz der Klasse bereitzustellen, bietet sich die Integration des in Abschnitt erklärten Singleton-Patterns an. Im Falle der WTCentral-Klasse wird innerhalb der Initialisierungsmethode zusätzlich überprüft, ob es sich um den Initialstart der Applikation handelt. Ist dies der Fall, so werden benötigte Daten, wie zum Beispiel die Währungen und Buchungskategorien, angelegt. 1 + (WTCentral *) sharedinstance { 2 if (!mywtcentral) { 3 mywtcentral = [[WTCentral alloc] init]; 4 [mywtcentral generatedefaultcurrencies]; 58

75 6.1. Diskurs der Softwarearchitektur 5 [mywtcentral generatedefaulttags]; 6 } 7 return mywtcentral; 8 } Listing 6.4: Die Initialisierungsmethode der WTCentral-Klasse. Listing 6.4 zeigt die entsprechende Klassenmethode, die das zuvor beschriebene Verhalten implementiert. Die Methoden generatedefaultcurrencies und generatedefaulttags erstellen je nach Stand der Datenbank die initialen Währungen und Kategorien. Innerhalb dieser Methode kann auch die in Abschnitt 5.3 gezeigte Initialisierung des Core Data Stacks erfolgen, auf die an dieser Stelle aus Gründen der Übersichtlichkeit verzichtet wurde. Nach Erzeugung der Klasseninstanz kann diese zur Interaktion mit der zugrunde liegenden Datenbank verwendet werden. Zudem bietet diese Klasse die Möglichkeit, Teilnehmer mit dem Adressbuch zu synchronisieren, was jedoch im Kontext dieser Arbeit nicht näher erläutert wird. Eine Anfrage an die Datenbank kann mithilfe der in Listing 6.5 gezeigten Methode gestellt werden. 1 NSPredicate * mypredicate = [NSPredicate subject == Essen"]; 2 NSArray * mysort = [[NSArray alloc] initwithobjects:[[[nssortdescriptor alloc] ascending:yes] autorelease],nil]; 3 4 NSArray * myresult = [[WTCentral sharedinstance] withpredicate:mypredicate sortby :mysort]; 5 [mysort release]; Listing 6.5: Datenbankabfrage mithilfe der getallobjectsfromentitytype-methode. Diese Methode bietet die Möglichkeit, die Ergebnismenge mithilfe eines NSPredicate-Objekts einzugrenzen und anhand verschiedener NSSortDescriptor-Objekte zu sortieren. Nach Ausführung des Fetch-Request wird diese Ergebnismenge an den Aufrufer zurückgegeben. Alternativ hierzu bietet die Klasse noch zwei weitere Abfragemethoden. 1 - (NSManagedObject *) getobjectforurirepresentation: (NSURL *) representation { 59

76 6. Entwicklung und Optimierung von iphone-applikationen 2 NSManagedObjectID * myobjectid = [self.mypersistentstorecoordinator managedobjectidforurirepresentation:representation]; 3 4 if (myobjectid) 5 return [self.mymanagedobjectcontext objectwithid:myobjectid]; 6 else 7 return nil; 8 } Listing 6.6: Datenbankabfrage mithilfe der getobjectforurirepresentation-methode. Die in Listing 6.6 gezeigte Methode liefert zu einer übergebenen Objekt-ID das dazugehörige Objekt zurück, gemäß dem Fall, dass dieses existiert. Mittels der in Listing 6.7 gezeigten Methode kann die Ergebnismenge lediglich in der Anzahl der abgefragten Datensätze beschränkt werden. 1 NSArray * myresult = [[WTCentral sharedinstance] limitby:10]; Listing 6.7: Limitierung des Abfrageergebnisses. Neben Datenbankabfragen ist ebenso das Hinzufügen und Löschen von Datensätzen möglich. Die addobjectfromentitytype-methode erzeugt ein neues NSManagedObject des übergebenen Typs. Nachdem das Objekt erzeugt wurde, können dessen Werte editiert werden. 1 Currency * mycurrency = (Currency *) [[WTCentral sharedinstance] 2 mycurrency.title 3 mycurrency.isocode Listing 6.8: Erstellung neuer Datensätze. Die WTCentral-Klasse ermöglicht, zusätzlich zur Löschung eines einzelnen Objekts, die Löschung aller Objekte eines Typs Entwicklung einer generalisierten Eingabemaske Die Darstellung der gespeicherten Daten wird innerhalb von wetravel, wie in Abschnitt beschrieben, mit speziellen Tabellen realisiert. Die Eingabe von Daten soll sich 60

77 6.1. Diskurs der Softwarearchitektur hiervon bewusst unterscheiden. Um dies dem Benutzer zu verdeutlichen, wurden spezielle Eingabemasken implementiert, die bei Klick auf ein mit Daten zu befüllendes Feld angezeigt werden. Diese Masken wurden im Standarddesign belassen. Da in vielen Tabellen die Möglichkeit der Dateneingabe besteht, empfiehlt sich auch hier wieder die Kapselung der Funktionalität. Das iphone bietet zur Dateneingabe, neben einer Standardtastatur, eine Vielzahl an Tastaturen (beispielsweise zur Nummern- bzw. Pinoder -Eingabe). Da in diesem Fall die Eingabemaske, abgesehen von der Tastatur und der Formatierung der eingegeben Werte, identisch ist, kann eine generische Klasse genutzt werden. Die in wetravel GenericEditViewController benannte Klasse nutzt eine spezialisierte Form des in Abschnitt erklärten Observer-Patterns, bei der nur ein Beobachter registriert sein kann. Jeder View-Controller, der das GenericEditViewObserver-Protokoll implementiert, kann mit Instanzen der Klasse GenericEditViewController interagieren und diese zur Datenerfassung nutzen. Die in diesem Protokoll deklarierte Methode dient der Benachrichtigung des Beobachters, sodass dieser über die bereitgestellten Akzessoren der Klasse GenericEditViewController die Werte nach Beendigung der Benutzereingabe abrufen kann. Der GenericEditViewController ermöglicht die Anzeige mehrerer Eingabefelder, zu deren Darstellung die Typen, Beschreibungen und eventuelle Initialinhalte der Felder benötigt werden. 1 // Setzen der Uebergabewerte 2 NSArray * desc = [[[NSArray alloc] ] autorelease]; 3 NSArray * types = [[[NSArray alloc] initwithobjects:[nsnumber numberwithint:genericeditviewtypestring],[nsnumber numberwithint: GenericEditViewTypePassword],nil] autorelease]; 4 NSArray * values = [[[NSArray alloc] autorelease]; 5 6 // Allozierung und Initialisierung der Eingabemaske 7 GenericEditViewController * gevc = [[[GenericEditViewController alloc] initwithdescriptions:desc andvalues:values anlegen" anddelegate:self andfieldtypes:types] autorelease]; 8 9 // Anzeige der Eingabemaske 10 [self.navigationcontroller pushviewcontroller:gevc animated:yes]; Listing 6.9: Initialisierung eines GenericEditViewControllers. 61

78 6. Entwicklung und Optimierung von iphone-applikationen Listing 6.9 zeigt die Initialisierungsmethode des GenericEditViewControllers, dem neben dem Beobachter und Anzeigenamen noch zwei gewünschte Eingabefelder übergeben werden. Der Beobachter kann vom Erzeuger auf ein beliebiges, protokollimplementierendes Objekt gesetzt werden. Abschließend muss der GenericEditViewController mittels der pushviewcontroller-methode auf dem View-Stack 1 abgelegt werden. Abbildung 6.5.: Eingabemasken für Texte und Datumsangaben. Neben der in Abbildung 6.5 gezeigten Eingabemaske für Texte, Zahlen und s wurden weitere Masken zur Eingabe von Textpassagen und Zeiträumen erstellt Bereitstellung einer Klasse für die Serverkommunikation Autor: Benjamin Glatzel Die Kommunikation mit der Webserviceschnittstelle muss innerhalb der iphone-applikation von vielen Controllern ausgeführt werden können. Innerhalb des Hauptmenüs der Applikation wetravel können beispielsweise Buchungsreports versendet werden, während in einer anderen Ansicht der Abschluss von Abonnements möglich ist (siehe Kapitel 8). Im folgenden Abschnitt steht der Diskurs einer Klasse im Mittelpunkt, die diese Funktionalität innerhalb der Applikation zur Verfügung stellt und die gesamte iphone-webservice-kommunikation kapselt. Die Webserviceschnittstelle wird im 1 Sämtliche dargestellten Ansichten werden bei der Entwicklung von iphone-applikationen auf dem sogenannten View-Stack abgelegt. Hierbei wird jeweils das oberste Element zur Darstellung genutzt und das Hinzufügen und Entfernen innerhalb des Stapels animiert dargestellt. 62

79 6.1. Diskurs der Softwarearchitektur weiteren Verlauf der Arbeit (siehe Abschnitt 7.7) diskutiert. Für das Verständnis des Abschnitts genügt es zu wissen, dass die Kommunikation über HTTPS in Form von HTTP-Datenpaketen erfolgt. Innerhalb der Datenpakete wird ein Schnappschuss des Datenbestands als fest definierte, leicht reduzierte XML-Struktur (siehe Anhang B.1) übertragen. Für die Übertragung kommt die HTTP-Methode POST zum Einsatz und die XML-Struktur wird innerhalb des HTTP-Bodys als URL-encodierte Zeichenkette, zusammen mit den für die Authentifikation benötigten Benutzerdaten, abgelegt. Die Datenpakete werden an eine spezielle URL gesendet, die unter anderem die auszuführende Action und den verwendeten Controller aufseiten des Webservice respektive der Webapplikation definiert. Als Beispiel dient in diesem Abschnitt das Versenden der erwähnten XML-Struktur (sprich das Versenden eines sogenannten Buchungsreports). Die Übertragung kann hierbei durch den Benutzer mittels der in Abschnitt 6.4 näher beschriebenen Tabellenzelle initiiert werden. Der erste Schritt besteht darin, das Grundgerüst für die Kommunikationsklasse zu entwerfen. Hierbei wird eine Klassenstruktur angestrebt, die innerhalb der Softwarearchitektur des Projekts vollständig unabhängig nutzbar ist. Nach der Initialisierung sollen einfache Methodenaufrufe zum Start der Kommunikation genügen. Da die Verbindungen asynchron ausgeführt werden sollen, muss das aufrufende Objekt über den aktuellen Stand der Übertragung und den Abschluss der Verbindung sowie anhand eines Statuscodes über das Ergebnis informiert werden. Hierzu bietet sich eine vereinfachte Form des in den Grundlagen erwähnten Observer-Patterns an. Kerngedanke ist hierbei, dass nach (oder direkt bei) der Initialisierung des Objekts eine Referenz auf einen sogenannten Observer (sprich Beobachter) gesetzt wird. Dieser wird während des Verbindungsvorgangs über den aktuellen Status informiert und kann nach Abschluss einer Transaktion weitere Schritte einleiten. Die Sprache Objective-C erlaubt verschiedene Möglichkeiten, das Pattern in die Tat umzusetzen. Die folgende Methode macht sich die Dynamik der Sprache zunutze: Hierzu wird in der Serverkommunikationsklasse für den Observer eine Referenz vom Datentyp id erzeugt. Während der Ausführung einer Verbindung kann diese Referenz zur Benachrichtigung des Observer verwendet werden. Zum Ausschluss von Laufzeitfehlern im Falle einer nicht-unterstützten Methodensignatur sollte vor dem Nachrichtenaufruf, wie in Listing 6.10 gezeigt, das Objekt auf die Unterstützung dessen geprüft werden. 63

80 6. Entwicklung und Optimierung von iphone-applikationen 1 if ([myobserver { 2 [myobserver finishedsendingreport:[nsnumber numberwithint:0]]; 3 } Listing 6.10: Prüfung auf eine Methodensignatur zur Laufzeit in Objective-C. Die beschriebene Lösung ist einfach zu implementieren und stellt eine gültige Adaption des Entwurfsmusters dar. Dennoch entstehen durch die Implementierung zwei entscheidende Nachteile: Die Methodensignaturen werden nur zur Laufzeit bei der Ausführung des entsprechenden Methodenaufrufs geprüft. Hierdurch können mögliche Fehlersituationen, wie beispielsweise durch Schreibfehler, erst bei der Ausführung erkannt werden. Der Verzicht auf festdefinierte Methodensignaturen ist im Hinblick auf größere Projekte ungeeignet, da diese zur Dokumentation derselben beitragen. Die zweite Lösungsmöglichkeit nutzt das Protokollkonzept der Sprache Objective-C und beseitigt somit die soeben genannten Problematiken. Abbildung 6.6 zeigt den zugrunde liegenden Aufbau der Lösung und bildet das Fundament für die Serverkommunikationsklasse WTServerConnection. Die dargestellte Klasse ist für Demonstrationszwecke im Vergleich zum Original hinsichtlich des Umfangs reduziert worden. NSObject WTServerConnection myconnection : NSURLConnection myresult : NSMutableData mytrustedhosts : NSArray myobserver : id <WTServerConnectionObserver> +dotransmitreportforexcursion(exc : Excursion) myobserver «interface» WTServerConnectionObserver finishedsendingreport(errorcode : int) datasentorreceived(completedbytes : int, remainingbytes : int) SendReportCell Abbildung 6.6.: Nutzung einer vereinfachten Form des Observer-Patterns für den Entwurf der Serverkommunikationsklasse. Um ein Objekt als Observer einer Instanz der Klasse WTServerConnection registrieren zu können, muss dieses zunächst das formelle Protokoll respektive Interface WTServerConnectionObserver adaptieren. Listing 6.11 zeigt die Objective-C-Syntax zur Deklarierung des Protokolls. 64

81 6.1. Diskurs der Softwarearchitektur WTServerConnectionObserver 3 - (void) datasentorreceivedwithcompletedbytes: (int) completedbytes andremainingbytes: (int) remainingbytes; 4 - (void) finishedsendingreport: (NSNumber *) errorcode; Listing 6.11: Deklarierung des Observer-Protokolls der Serverkommunikationsklasse. Das Protokoll definiert zwei Methodensignaturen. Diese sind als optional markiert, da je nach Anwendungskontext nur bestimmte Informationen für den Observer von Interesse sein können. Der allgemeine Datentyp id kann zudem, wie in Listing 6.12 gezeigt, auf protokolladaptierende Klassen beschränkt werden. 1 id <WTServerConnectionObserver> myobserver Listing 6.12: Beschränkung des Datentyps id. So kann der Compiler, ähnlich der statischen Typisierung, während des Übersetzungsvorgangs mögliche Verstöße erkennen. Zudem erhöhen die festdefinierten Methodensignaturen die Wartbarkeit des Projekts erheblich. Zur Ausführung des eigentlichen Datentransfers eignet sich die Nutzung der Klasse NSURLConnection des Foundation-Framework (vgl. zu diesem Abschnitt [App10o], Seite 13 ff.). Diese erlaubt es mittels eines sogenannten NSURLRequest die Verbindung zu einem über eine URL adressierbaren Server herzustellen. Die Klassen sind unabhängig von den zugrunde liegenden Übertragungsprotokollen und hinsichtlich des Protokolls HTTP stehen Methoden zur einfachen Erstellung von Anfragen bereit. Listing 6.13 zeigt eine exemplarische Implementierung der Methode dotransmitreportforexcursion, die zur Übertragung eines Buchungsreports an den Webservice dient. 1 - (void) dotransmitreportforexcursion:(excursion *)excursion { 2 // Die Uebertragungsdaten vorbereiten 3 NSString * poststring = [NSString toxml]]; 4 NSData * postdata = [poststring datausingencoding:nsutf8stringencoding allowlossyconversion:no]; 5 NSString * postlength = [NSString length]]; 6 NSURL * url = [self 7 // Die Anfrage initialisieren und mit den vorbereiteten Daten fuellen 65

82 6. Entwicklung und Optimierung von iphone-applikationen 8 NSMutableURLRequest *request = [NSMutableURLRequest requestwithurl:url cachepolicy:nsurlrequestreloadignoringlocalcachedata timeoutinterval :60.0]; 9 [request 10 [request sethttpbody:postdata] ; 11 [request setvalue:postlength 12 [request 13 // Die Verbindung asynchron ausfuehren 14 [[[NSURLConnection alloc] initwithrequest:request delegate:self] autorelease]; 15 } Listing 6.13: Methode zur Übertragung eines Buchungsreports an den Server. Für die Erzeugung der XML-Struktur stehen innerhalb der Entitätsklassen die Methoden toxml bereit. Die Klasse NSURLConnection nutzt das in den Grundlagen beschriebene Delegation-Pattern zur weiteren Bearbeitung von Serveranfragen, verzichtet hierbei jedoch auf die Verpflichtung zur Adaption eines formellen Protokolls. Der Delegat muss als Konstruktorargument bei der Instanziierung des Objekts übergeben werden. Innerhalb des Kontextes der Serverkommunikationsklasse bietet sich die Nutzung der aktuellen Objektinstanz als Delegat an. In dieser müssen die entsprechenden Methoden implementiert werden, um beispielsweise auf eine Authentifikationsanfrage des Servers oder auf ein empfangenes Datenpaket zu reagieren. Die empfangenen Bytes können mithilfe der Datenstruktur NSMutableData verkettet werden (siehe Variable myresult in Abbildung 6.6). Diese stellt eine veränderbare Datenstruktur dar und kann beispielsweise auch nach Instanziierung durch Zurücksetzen der Länge des Datenstroms geleert werden. Nach Abschluss der Verbindung muss der entsprechende Statuscode an den registrierten Beobachter der Klasse WTServerConnection über die Methode finishedsendingreport weitergeleitet werden. Auf eine detaillierte Beschreibung sämtlicher Delegaten-Methoden der Klasse NSURLConnection wird an dieser Stelle aufgrund der Komplexität verzichtet. Da die Kommunikation mittels HTTPS ausgeführt werden soll, müssen bei der Nutzung der Klasse NSURLConnection zunächst folgende Vorkehrungen getroffen werden: Falls von der Gegenseite ein unsigniertes Zertifikat für die Verschlüsselung bereitgestellt wird, verlangt diese vor der eigentlichen Datenübertragung zunächst die Bestätigung 66

83 6.1. Diskurs der Softwarearchitektur des Zertifikats durch den Delegaten. Es könnte an dieser Stelle beispielsweise der Benutzer in die Abfrage mit einbezogen werden, sodass dieser für die Validierung des Zertifikats verantwortlich gemacht wird. Kommt für das Projekt ein einziger, zentraler Server zum Einsatz, kann das Abgleichen der Hostbezeichnung innerhalb des Programmcodes genügen. Bei der Implementierung müssen hierzu zwei Methoden bereitgestellt werden: Die Erste teilt der Klases NSURLConnection mit, dass der Delegat die Authentifikationsanfrage beantworten kann. Die zweite Methode dient zur soeben beschriebenen Analyse und Freigabe des Zertifikats. Eine exemplarische Implementierung der notwendigen Methoden ist in Listing 6.14 gezeigt. Hierbei kommt das Array mytrustedhosts zum Einsatz, welches eine Menge von validen Hostnamen enthält. Diese können beispielsweise bei der Initialisierung der Klasse innerhalb des Konstruktors erzeugt werden. 1 - (BOOL)connection:(NSURLConnection *)connection canauthenticateagainstprotectionspace:(nsurlprotectionspace *) protectionspace { 2 return [protectionspace.authenticationmethod isequaltostring: NSURLAuthenticationMethodServerTrust]; 3 } 4 - (void)connection:(nsurlconnection *)connection didreceiveauthenticationchallenge:(nsurlauthenticationchallenge *) challenge { 5 if ([challenge.protectionspace.authenticationmethod isequaltostring: NSURLAuthenticationMethodServerTrust]) { 6 if ([mytrustedhosts containsobject:challenge.protectionspace.host]) { 7 [challenge.sender usecredential:[nsurlcredential credentialfortrust: challenge.protectionspace.servertrust] forauthenticationchallenge :challenge]; 8 } 9 } 10 [challenge.sender continuewithoutcredentialforauthenticationchallenge: challenge]; 11 } Listing 6.14: Überprüfung des Zertifikats vor Aufbau der HTTPS-Verbindung. Falls der Hostname in der soeben genannten Liste enthalten ist, wird das Zertifikat für die Verbindung verwendet, andernfalls wird eine nicht verschlüsselte Verbindung aufgebaut. 67

84 6. Entwicklung und Optimierung von iphone-applikationen Für das bessere Verständnis kann der Einsatz der Serverkommunikationsklasse nun wie folgt zusammengefasst werden: Die in diesem Beispiel als Aufrufer dienende Tabellenzelle muss zunächst das Protokoll WTServerConnectionObserver adaptieren, eine Instanz der Klasse WTServerConnection erzeugen und sich selbst als Beobachter dieser registrieren. Nach einer Aktion durch den Benutzer wird die gewünschte Reise innerhalb der Nachricht dotransmitreportforexcursion als Argument an die Instanz übergeben. Diese initiiert daraufhin eine Verbindung unter Verwendung der Klasse NSURLConnection und überträgt die XML-Struktur innerhalb des HTTP-Bodys an eine festdefinierte URL-Struktur. Nach erfolgter Übertragung wird die Tabellenzelle mithilfe eines Statuscodes über das Ergebnis informiert. Diese kann daraufhin beispielsweise eine Fehlernachricht ausgeben oder im Erfolgsfall in den Ursprungszustand übergehen Nutzung des Lokalisierungsmechanismus des Foundation- Framework Autor: Dominik Wilhelm In vielen Fällen sollen iphone-applikationen einer möglichst großen Zahl an Interessenten zur Verfügung gestellt werden. Dies bedeutet, dass die Applikation in mehreren Sprachen nutzbar sein sollte. Das iphone SDK bietet hierfür die Möglichkeit, ähnlich dem in Kapitel 7 vorgestellten Verfahren, Sprachdateien zu verfassen, mit deren Hilfe eine lokalisierte Fassung der Applikation erstellt werden kann. Für jede gewünschte Sprache kann eine Datei erstellt werden, in der Key-Value-Paare abgelegt werden. Mithilfe der NSLocalizedString-Methode wird innerhalb der Sprachdatei für die aktuell auf dem iphone genutzte Sprache nach dem Schlüssel gesucht und der entsprechende Wert zurückgegeben. Listing 6.15 zeigt die Nutzung dieser Methode. 1 // Deutsche Sprachdatei 2 "HELLO" = "Hallo, ich heisse Steve!"; 3 // Englische Sprachdatei 4 "HELLO" = "Hello, my name is Steve!"; 5 6 // Programm wird auf Deutsch ausgefuehrt 7 8 // Ausgabe: Hallo, ich heisse Steve! 9 10 // Programm wird auf Englisch ausgefuehrt 68

85 6.2. Techniken zur Generierung von grafischen Effekten // Ausgabe: Hello, my name is Steve! Listing 6.15: Nutzung der NSLocalizedString-Methode Techniken zur Generierung von grafischen Effekten Für die Entwicklung und Manipulation von grafischen Elementen stellt das iphone SDK zwei zentrale Technologien in den Mittelpunkt: Core Graphics und Core Animation. Core Graphics ist eine auf der Programmiersprache C basierende, systemnahe API zur Erzeugung von zweidimensionalen Grafiken (vgl. zum Folgenden [App09d], Seite 9). Core Graphics basiert auf der aus dem Mac-OS-X-Umfeld bekannten Zeichenengine Quartz 2D. Die Bibliothek ermöglicht beispielsweise primitive Zeichenoperationen, Kantenglättung, Maskierung von Grafiken, Erzeugung von Verläufen und Transformationen innerhalb des zweidimensionalen Koordinatenraums. Das Framework Core Animation ist tief in den View-Renderingprozess integriert und bietet einfache Methodiken zur Animation und Transformation von Views (vgl. [App10h], Seite 54 f.). Innerhalb dieses Abschnitts werden die Animationstechniken des Framework zunächst außer Acht gelassen, da diese in einem späteren Abschnitt (siehe Abschnitt 6.4) anhand der Entwicklung einer multi-touch-fähigen, interaktiven, Tabellenzelle näher erläutert werden. Als literarische Grundlage für diesen Abschnitt dienen die von Apple bereitgestellten Dokumentationen Core Graphics Framework Reference (siehe [App09d]), Quartz 2D Programming Guide (siehe [App09g]) und Core Animation Programming Guide (siehe [App10e]). Autor: Benjamin Glatzel Zur Analyse beider Frameworks steht innerhalb dieses Abschnitts die Erzeugung der in Abbildung 6.7 (c) gezeigten Grafik im Mittelpunkt. Als Grundlage für die Erzeugung dient die in Abbildung 6.7 (a) dargestellte PNG-Grafik. Die angestrebte Darstellungsform orientiert sich am Patent Cover Flow der Firma Apple (siehe Abbildung 6.8). Dieser Effekt kann beispielsweise zur verschönerten Darstellung von benutzerdefinierten Fotos innerhalb von Applikationen verwendet werden. Für die Erzeugung des Endergebnisses, gezeigt in Abbildung 6.7 (c), sind mehrere Schritte von Nöten: Core Graphics wird zunächst für die Ausgabe der Grafik und die Erzeugung eines Spiegelungseffekts verwendet (siehe Abbildung 6.7 (b)). Hierzu 69

86 6. Entwicklung und Optimierung von iphone-applikationen (a) Ursprüngliche Grafik (b) Schritt 1 und 2 (c) Schritt 3 Abbildung 6.7.: Erzeugung eines Grafikeffekts, welcher der Darstellungsform Cover Flow ähnelt. Abbildung 6.8.: Cover-Flow-Ansicht innerhalb des Dateimanagers Finder der Firma Apple. 70

87 6.2. Techniken zur Generierung von grafischen Effekten kommen primitive Zeichenoperationen und Matrixtransformationen zum Einsatz. Zudem muss das Spiegelbild maskiert werden, sodass dieses im unteren Abschnitt sanft, verlaufsartig ausblendet. Da Core Graphics nur affine Transformationen 2 unterstützt, muss für die perspektivische Ausrichtung der Grafik eine Alternative gefunden werden. In der aktuellen Version der iphone-applikation wetravel kommt nur eine pseudoperspektivische Darstellungsform zum Einsatz (siehe Abbildung 6.9), die durch Scherung der Grafik erreicht wird. Eine Kompensation des Defizits ist durch den Einsatz des Core-Animation-Framework möglich. Abbildung 6.9.: Eine Tabellenzelle, die ein generiertes Bild zu Darstellung eines angehängten Buchungsbildes nutzt Generierung eines Spiegelungseffekts mithilfe von Core Graphics Quartz 2D is an advanced, two-dimensional drawing engine available for iphone application development and to all Mac OS X application environments outside of the kernel. Quartz 2D provides low-level, lightweight 2D rendering with unmatched output fidelity regardless of display or printing device. (siehe [App09g], Seite 15) Das Framework Core Graphics ist im Gegensatz zum Core-Animation-Framework, das vollständig objektorientiert in der Sprache Objective-C verfügbar ist, eine reine C-Bibliothek. Sämtliche Zeichenoperationen des Framework beziehen sich auf einen sogenannten Graphics-Context. Dieser gibt das Ziel für die Zeichenoperationen an und stellt die aktuelle Transformationsmatrix, den Farbraum, die Zeichenfarbe und viele weitere Parameter zur Verfügung. Für die Ausführung von Zeichen- und Transformationsoperationen muss stets eine Referenz auf den Graphics-Context als Argument übergeben werden. Steht das Ergebnis bereit, bietet das UIKit-Framework Methoden zur Überführung des Graphics-Context in Instanzen der UIKit-Klasse UIImage. 2 Affine Transformationen erhalten stets die Parallelität und Abstandsverhältnisse der Ausgangsgrafik. 71

88 6. Entwicklung und Optimierung von iphone-applikationen Umgekehrt stellt die Klasse UIImage Zeichenoperationen für den aktuellen Graphics- Context bereit. Listing 6.16 zeigt die Vorgehensweisen zur Erzeugung eines neuen Graphics-Context, zum Zeichnen einer PNG-Grafik innerhalb dessen und letztendlich zur Überführung des Graphics-Context in eine Instanz der Klasse UIImage, die für die Darstellung mithilfe des UIKit-Framework geeignet ist. Zur Vereinfachung wird an dieser Stelle auf eine dynamische Anpassung der Seitenverhältnisse verzichtet und die PNG-Grafik fest in einer Größe von Pixel gezeichnet. Der Graphics-Context wird hierbei auf Pixel beschränkt. 1 // Einen neuen Graphics-Context erzeugen 2 UIGraphicsBeginImageContext(CGSizeMake(200, 200)); 3 // Eine Referenz auf den aktuellen Kontext speichern 4 CGContextRef context = UIGraphicsGetCurrentContext(); 5 // Das Bild laden und zeichnen (diese Methode nutzt intern den soeben erzeugten Kontext) 6 [[UIImage drawinrect:cgrectmake(0,0,128,128) blendmode:kcgblendmodenormal alpha:1.0]; 7 // Den Graphics-Context in eine Instanz der Klasse UIImage ueberfuehren 8 UIImage * resultimage = UIGraphicsGetImageFromCurrentImageContext(); 9 UIGraphicsEndImageContext(); 10 // Darstellung auf dem Display mittels einer Instanz der Klasse UIImageView 11 myimageview.image = resultimage; Listing 6.16: Ausgabe einer PNG-Grafik mithilfe von Core Graphics. Bei der Nutzung des UIKit-Framework muss beachtet werden, dass sich der Ursprung des Zeichenkoordinatensystems in der oberen linken Ecke des Displays befindet. Verwendet man einen von UIKit bereitgestellten Graphics-Kontext, wird das Koordinatensystem bei der Initialisierung dessen entsprechend angepasst. Im Kontrast hierzu liegt bei einem vom UIKit-Framework unabhängigen Graphics-Context (beispielsweise ein primitiver Bitmap-Graphics-Context) der Koordinatenursprung in der unteren linken Ecke. Nach Ausführung des in Listing 6.16 gezeigten Programmcodes wird die PNG-Grafik mit ihrer oberen linken Ecke im Ursprung platziert. Der nächste Schritt besteht nun in der Erzeugung eines Spiegelbildes der soeben platzierten Grafik. Hierzu sind zwei elementare Transformationen und die erneute Ausgabe des Bildes notwendig. Zunächst muss die zweite Grafik, die als Spiegelbild vorgesehen ist, an der x-achse gespiegelt werden. Dies kann durch eine negative Skalierung um den Faktor 1 72

89 6.2. Techniken zur Generierung von grafischen Effekten entlang der y-achse erreicht werden. Nach der Skalierung muss das Spiegelbild um seine zweifache Höhe (2 h) in positive Richtung entlang der y-achse verschoben werden. Die soeben erläuterten Transformationen sind in Abbildung 6.10 zur Verdeutlichung dargestellt. 2Δh Δh 1 Spiegelung an der x-achse x 2 Translation um 2Δh entlang der y-achse y Abbildung 6.10.: Verdeutlichung des Transformationsprozesses zur Erzeugung des Spiegelbildes. Bei jeder Zeichenoperation wird eine dem Graphics-Context zugeordnete Transformationsmatrix, die sogenannte Current Transformation Matrix (kurz CTM), für die Zuordnung der Bildpunkte aus dem Zeichenkoordinatensystem auf die des Displays verwendet. Für die Manipulation dieser stehen vielfältige Methoden bereit. Neben Methoden zur manuellen Erstellung von Matrizen bietet das Core-Graphics-Framework Hilfsmethoden zur Erzeugung und Zusammenfassung der gebräuchlichsten Transformationsmatrizen an. Für die Ausrichtung und Platzierung des Spiegelbildes könnten die zwei notwendigen Transformationen getrennt ausgeführt werden. Um unnötigen Rechenaufwand zu vermeiden, bietet es sich an, die Matrizen durch Matrix-Multiplikation zu einer einzigen Matrix zusammenzufassen. Dies kann einerseits durch die Verwendung von Hilfsmethoden oder von Hand durch die Berechnung der zugrunde liegenden Matrix 73

90 6. Entwicklung und Optimierung von iphone-applikationen (siehe Formel 6.1) erreicht werden = (6.1) Listing 6.17 zeigt die Erzeugung und Zusammenfassung der Matrizen mithilfe der von Core Graphics bereitgestellten Methoden. Die Ergebnis-Matrix wird letztendlich mit der CTM multipliziert. Nach Setzen der CTM kann die Grafik wie zuvor gezeichnet werden, jedoch sollte hierbei der Alpha-Wert 3 auf circa 0, 5 gesetzt werden, sodass eine halbtransparente Darstellung erreicht wird. Die Modifikation der CTM führt bei diesem Zeichenvorgang zu der in Abbildung 6.10 dargestellten Transformation. 1 // Spiegelung 2 CGAffineTransform transf1 = CGAffineTransformMakeScale(1, -1); 3 // Translation 4 CGAffineTransform transf2 = CGAffineTransformMakeTranslation(0,256); 5 // Zusammenfassung durch Multiplikation 6 CGAffineTransform transf3 = CGAffineTransformConcat(transf1, transf2); 7 // Zusammenfassung von CTM und der Transformationsmatrix 8 CGContextConcatCTM(context,transf3); 9 // Das Spiegelbild zeichnen 10 [[UIImage drawinrect:cgrectmake(0.0,0,128,128) blendmode:kcgblendmodenormal alpha:0.5]; Listing 6.17: Erzeugung des Spiegelbildes mit Core Graphics. Um den Spiegelungseffekt zu verbessern, sollte das Spiegelbild innerhalb der unteren Bildhälfte langsam ausblenden. Dies kann beispielsweise durch die Anwendung einer Maske erreicht werden (vgl. zu diesem Abschnitt [App09g], Seite 146 ff.). An dieser Stelle sei zunächst die Maskierungstechnik erklärt. Eine Maske kann als eine Art Schablone betrachtet werden, die sich auf eine Grafik anwenden lässt. Masken werden häufig als graustufige Bitmap codiert und die Grauwerte (G) der einzelnen Bildpunkte bestimmen den Durchlass der Bildpunkte des zu maskierenden Bildes. Der Grauwert weiß (G = 1, 0) blockiert den Durchlass, während schwarz (G = 0, 0) keine sichtbaren Auswirkungen zeigt. Grauwerte im Bereich von 0, 0 < G < 1, 0 bestimmen die Transparenz bzw. den Alpha-Wert. Ein Grauwert von 0, 5 lässt einen Bildpunkt beispielsweise nach erfolgter 3 Der Alpha-Wert bestimmt die Transparenz der einzelnen Bildpunkte eines Bildes. 74

91 6.2. Techniken zur Generierung von grafischen Effekten Maskierung halbtransparent erscheinen. Um diesen Prozess zu verdeutlichen, ist die Anwendung einer Verlaufsmaske auf das Spiegelbild in Abbildung 6.11 dargestellt. 1 Ursprüngliche Grafik 2 Maske 3 Ergebnis Abbildung 6.11.: Maskierung des Spiegelbildes mit einem graustufigen Verlauf. Für die Zeichnung der Maske genügt die Initialisierung einer einfachen Bitmap. Hierzu muss zunächst ein neuer Graphics-Context erzeugt werden. Da die Maske lediglich Grauwerte enthalten darf, muss der Grauwertfarbraum des Endgeräts verwendet und das Anlegen eines Alpha-Kanals ausgeschlossen werden. Listing 6.18 zeigt die Initialisierung eines Bitmap-Graphics-Context mit einem Grauwertbereich von 8 Bit (sprich 2 8 = 256 verschiedenen Grauwerten). Der Graphics-Context der Maske ist entsprechend der Größe des zu maskierenden Bildes auf Pixel begrenzt. 1 CGContextRef maskcontext = CGBitmapContextCreate(NULL, 200, 200, 8, 0, CGColorSpaceCreateDeviceGray(), kcgimagealphanone); Listing 6.18: Erzeugung eines Bitmap-Graphics-Context für die Maske. Bei der Verwendung des Bitmap-Graphics-Context muss, wie bereits erwähnt, die Position des Koordinatenursprungs beachtet werden. Für die Erzeugung der Maske bietet es sich zunächst an den Hintergrund schwarz zu färben, sodass sämtliche Bildpunkte nach erfolgter Maskierung sichtbar sind. So kann ein Verlauf im unteren Bereich der Spiegelung für den Ausblendungseffekt verwendet werden. Für die Erstellung von Verläufen sind einige Informationen notwendig. Zunächst muss der entsprechende Farbraum festgelegt werden, sprich in diesem Beispiel erneut der Grauwertfarbraum des Endgeräts. Zudem muss die Anzahl der Unterteilung des Verlaufs festgelegt werden. Für dieses Beispiel genügen zwei Bereiche, die eine Grauwertinterpolation zwischen den Farben schwarz und weiß erzeugen. Nach der Initialisierung des Verlaufs kann dieser für die Zeichnung innerhalb des erzeugten Graphics-Context verwendet werden. Hierzu müssen 75

92 6. Entwicklung und Optimierung von iphone-applikationen zwei Punkte im Koordinatensystem festgelegt werden, die den Start- und Endpunkt des Verlaufs definieren. Listing 6.19 zeigt die notwendigen Core-Graphics-Aufrufe, die für die Erzeugung und Ausgabe des Verlaufs nötig sind. 1 // Unterteilung des Verlaufs in zwei Bereiche 2 CGFloat locations[2] = { 0.0, 1.0 }; 3 // Festlegung der Grau- und Alpha-Werte 4 CGFloat components[4] = { 1.0, 1.0, 0.0, 1.0 }; 5 // Erzeugung des Verlaufs 6 CGGradientRef gradient = CGGradientCreateWithColorComponents( CGColorSpaceCreateDeviceGray(), components, locations, (size_t) 2); 7 // Den Hintergrund schwarz einfaerben 8 CGContextSetGrayFillColor(maskContext, 1.0, 1.0); 9 CGContextFillRect(maskContext, CGRectMake(0,0,200,200)); 10 // Den Verlauf zeichnen 11 CGContextDrawLinearGradient(maskContext, gradient, CGPointMake(0, 120), CGPointMake(0, 0.0), kcggradientdrawsafterendlocation); 12 // Uebertragung des Kontextes in eine Grafik 13 CGImageRef maskimage = CGBitmapContextCreateImage(maskContext); Listing 6.19: Erzeugung eines Verlaufs für die Maske. Die soeben erzeugte Bitmap kann nun, wie in Listing 6.20 gezeigt, für die Maskierung des Spiegelbildes angewandt werden und führt zu dem in Abbildung 6.7 (b) gezeigten Ergebnis. 1 // Anwenden der Maske auf das Gesamtbild 2 CGImageRef finalimage = CGImageCreateWithMask(resultImage.CGImage, maskimage); 3 // Erzeugung eines UIImage-Objekts 4 resultimage = [UIImage imagewithcgimage: finalimage]; 5 // Darstellung des Bildes auf dem Display mithilfe einer Instanz der Klasse UIImageView 6 myimageview.image = resultimage; Listing 6.20: Anwendung der Bitmap-Maske. 76

93 6.2. Techniken zur Generierung von grafischen Effekten Perspektivische Ausrichtung der Grafik mithilfe des Core- Animation-Framework Die letzte Aufgabe besteht nun darin, eine einfache, dreidimensionale Ausrichtung des Bildes zu erreichen. Zur Vereinfachung wird an dieser Stelle davon ausgegangen, dass die erzeugte Grafik bereits mittels einer Instanz der Klasse UIImageView auf dem Display des Endgeräts dargestellt wird. Diese Klasse nutzt intern als Tochterklasse von UIView das Core-Animation-Framework für die Renderingprozesse. Die Klasse UIView stellt eine Instanz der Core-Animation-Klasse CALayer bereit, die, vereinfacht gesagt, zur Transformation und Animation des Darstellungsfeldes verwendet werden kann. Um die in Abbildung 6.7 (c) gezeigte, leicht schräge Ausrichtung zu erhalten, muss zunächst eine Rotation um die y-achse ausgeführt werden. Für die Ausführung einer Rotation muss eine Transformationsmatrix erzeugt und übergeben werden. Ähnlich zu Core Graphics werden auch von Core Animation Hilfsmethoden für die Generierung der Transformationsmatrizen bereitgestellt. Listing 6.21 zeigt die Erzeugung und Anwendung einer Matrize zur Rotation des Darstellungsfeldes um 45 um die y- Achse. 1 myimageview.layer.transform = CATransform3DRotate(CATransform3DIdentity, 0.785f, 0.0f, 1.0f, 0.0f); Listing 6.21: Rotation des Darstellungsfeldes mithilfe des Core-Animation-Framework. Die Rotationsmethode benötigt einen Vektor zur Bestimmung der Rotationsachse und die Angabe des Rotationswinkel in Radiant (1 sind π 180 Radiant). Abbildung 6.12.: Core Animation nutzt intern eine orthogonale Projektion zur Abbildung. Das Ergebnis (siehe Abbildung 6.12) ist zunächst nicht zufriedenstellend. Core Animation verwendet intern eine orthogonale Projektionsmatrix zur Abbildung des 3D-Raums auf das 2D-Koordinatensystem des Endgeräts. Das genaue Verhalten ist jedoch nicht 77

94 6. Entwicklung und Optimierung von iphone-applikationen dokumentiert (siehe [App10e]), kann jedoch durch einige Translationen entlang der z-achse bewiesen werden, da die Grafik hierbei an allen Positionen keine Größenänderung zeigt. Durch Multiplikation mit einer orthogonalen Projektionsmatrix, gezeigt in Formel 6.2, wird die Position auf der z-achse außer Acht gelassen ( ) x y z = ( ) x y 0 1 (6.2) Um eine realistischere Darstellung zu erreichen, bietet sich der Einsatz einer perspektivischen Projektion an. Da die orthogonale Projektionsmatrix nicht ausgetauscht werden kann, muss eine spezielle Projektionsmatrix eingesetzt werden, die eine Projektion auf die Ebene z = 0 ausführt und von der orthogonalen Projektion erfasst wird. Die in Formel 6.3 gezeigte Transformationsmatrix projiziert sämtliche Bildpunkte in Abhängigkeit ihrer Position auf der z-achse auf die Ebene z = ( ) x y z / d = ( x 1 z d y 1 z d ) 0 1 (6.3) Der Wert d beeinflusst hierbei die Betrachtungsposition. Ein Wert d 0 verstärkt den perspektivischen Effekt und ein Wert d führt erneut zu einer orthogonalen Projektion. Ein Wert von d 250 hat sich als geeignete Intensität für die perspektivische Zerrung ergeben. Zur Verdeutlichung sind in Abbildung 6.13 die perspektivische und orthogonale Projektion auf die Ebene z = 0 dargestellt. Um das Beispiel abzuschließen, kann die in Formel 6.3 gezeigte, perspektivische Transformationsmatrix, wie in Listing 6.22 gezeigt, mit der Rotation zusammengeführt und zur Transformation des Darstellungsfeldes angewandt werden. 78

95 6.2. Techniken zur Generierung von grafischen Effekten y (x',y',0) (x,y,z) (x'',y'',0) Orthogonale Projektion Perspektivische Projektion Δd z = 0 z Abbildung 6.13.: Gegenüberstellung von perspektivischer und orthogonaler Projektion auf die Ebene z = 0. 1 CATransform3D persptransformation = CATransform3DIdentity; 2 persptransformation.m33 = 0; 3 persptransformation.m34 = -1.0/250.0; 4 myimageview.layer.transform = CATransform3DConcat(myImageView.layer. transform, persptransformation); Listing 6.22: Zusammenführung von Rotation und perspektivischer Projektion. Innerhalb dieses Abschnittes wurden einige Verwendungsmöglichkeiten des Core-Graphics-Framework sowie der Einsatz des Core-Animation-Framework zur dreidimensionalen Transformation demonstriert und analysiert. Die Verwendung von Core Graphics hat gezeigt, dass auch auf dem iphone qualitative Grafiken ohne großen Aufwand erzeugt werden können und hierbei zudem erweiterte Techniken, wie beispielsweise Bildmaskierung, Kantenglättung und Transparenz, verfügbar sind. Die gezeigten Techniken stellen jedoch nur einen Bruchteil der Möglichkeiten des Framework dar. Da Core Graphics speziell für den zweidimensionalen Raum entwickelt wurde, ist es nicht verwunderlich, dass lediglich affine Transformationen bereitgestellt werden. Für komplexe, dreidimensionale Transformationen steht in direktem Anschluss das native Core-Animation-Framework oder die systemnahe OpenGL-ES-API bereit. 79

96 6. Entwicklung und Optimierung von iphone-applikationen 6.3. Optimierung von iphone-applikationen Autor: Dominik Wilhelm Die vorherigen Abschnitte dieses Kapitels beschreiben, wie eine Applikation in Sachen Wartbarkeit und Individualisierung des Aussehens angepasst werden kann. Jedoch spielt besonders auf Geräten mit begrenzten Ressourcen die Performanz eine besondere Rolle. Neben Nutzung effizienter Algorithmen und der allgemeinen Optimierung des Quellcodes ist besonders die flüssige und schnelle Darstellung aller grafischen Elemente wichtig. Somit sind an dieser Stelle Optimierungen unumgänglich und zwingend notwendig. Abschnitt beschreibt die Nutzung von Caching zur Reduktion der Prozessor- und Arbeitsspeichernutzung und stellt neben dem vom SDK gebotenen System eine eigene Implementation vor. In großen Tabellen reicht Caching alleine jedoch nicht aus, um einen flüssigen Bildlauf gewährleisten zu können. Hierfür müssen die Tabellenzellen von Grund auf optimiert werden. Dies kann durch die Erstellung eigener Zellentypen realisiert werden und wird in Abschnitt im Detail erklärt. Zur weiteren Individualisierung kann dieser performantere Zellentyp noch angepasst und modifiziert werden. Ein Beispiel für eine Modifikation dieser Art wird in Abschnitt 6.4 anhand einer, mit dem Core-Animation-Framework animierten, drehbaren Zelle angeführt Implementierung eines Cachingsystems Eine der effizientesten Methoden die Arbeitsspeicher- und Prozessorauslastung zu reduzieren und somit auch die Performanz der Applikation zu steigern, nennt sich Caching. Im Folgenden wird der Vorteil dieser Methode anhand verschiedener Beispiele erläutert und die Nutzung der vom SDK bereitgestellten Caching-Methoden gezeigt. Im Anschluss wird die Implementierung eines eigenen Caching-Verhaltens mit diesen Methoden implementiert und verglichen. Erzeugung von Bildobjekten In nahezu allen iphone-applikationen ist Darstellung von Bildinhalten von Bedeutung, die unter Verwendung der Klasse UIImage erreicht werden kann. Die Initialisierung eines UIImage-Objekts ist in Listing 6.23 demonstriert. 80

97 6.3. Optimierung von iphone-applikationen 1 NSString *mypath = [[NSBundle mainbundle] "png"]; 2 UIImage * myimage = [UIImage imagewithcontentsoffile:mypath]; Listing 6.23: Initialisierung eines UIImage-Objekts. Bei geringer Nutzung von Bildobjekten ist dieses Vorgehen durchaus legitim. Werden mehrere UIImage-Objekte genutzt, die im schlimmsten Fall alle die selbe Bilddatei benötigen, würde bei Anwendung dieser Methode die Prozessor- und Speicherauslastung unnötig steigen, da jedes dieser Objekte alloziert und initialisiert werden muss. Um die Speicherauslastung und nötige Ladezeiten aus dem Festspeicher zu minimieren, bietet sich die Verwendung eines einzigen UIImage-Objekts pro Bilddatei an. Genau dieses Verhalten kann durch die Nutzung der in Listing 6.24 gezeigten Methode erzielt werden. 1 NSString *mypath = [[NSBundle mainbundle] "png"]; 2 UIImage * myimage = [UIImage imagenamed:mypath]; Listing 6.24: Nutzung des bereitgestellten Caches. Durch Nutzung der imagenamed-methode wird diese mehrfache Initialisierung verhindert. Vor Allokation eines neuen UIImage-Objekts wird die Existenz eines solchen Objekts, das die gewünschte Bilddatei enthält, überprüft. Im Falle eines Fundes wird das bereits existierende Objekt zurückgegeben. Existiert noch keine Instanz des Bildobjekts, so wird diese alloziert und initialisiert. Somit wird jedes Bild genau einmal alloziert und danach lediglich die existierende Instanz zurückgeliefert. Anzeige von Tabellenzellen Bei Nutzung der in Abschnitt angesprochenen Tabellen empfiehlt sich ebenfalls die Nutzung der integrierten Cachingmethoden (vgl. [App10n]). Bevor eine Zelle in den sichtbaren Bereich der Tabelle rückt, wird diese mithilfe der cellforrowatindex- Path-Methode innerhalb des zuständigen View-Controllers vorbereitet und übergeben. Analog zu Listing 6.23 kann das in Listing 6.25 gezeigte Verhalten implementiert werden, welches für jede Zelle ein UITableViewCell-Objekt initialisiert. Bei intensiver Nutzung des Bildlaufs innerhalb von Tabellen wird eine Vielzahl von Zellenobjekten 81

98 6. Entwicklung und Optimierung von iphone-applikationen initialisiert. Die Tabellenzellen können somit nicht mehr schnell genug angezeigt und die geforderte flüssige Darstellung des Bildlaufs kann hierdurch nicht gewährleistet werden. 1 - (UITableViewCell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { 2 cell = [[[UITableViewCell alloc] initwithstyle: UITableViewCellStyleDefault reuseidentifier:nil] autorelease]; 3 cell.textlabel.text = [NSString \%i \%i", indexpath.section,indexpath,row]; 4 5 return cell; 6 } Listing 6.25: Erzeugung von Tabellenzellen (ohne Caching). Ein besserer und von Apple empfohlener Ansatz ist die Nutzung des integrierten Cachingverhaltens. Hierfür wird bei der in Listing 6.25 gezeigten Methode der sogenannte Reuse-Identifier angegeben. Dieser dient zur Identifizierung gleicher Zellentypen und deren erneuter Nutzung. 1 - (UITableViewCell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { 2 UITableViewCell *cell = [tableview "Info"]; 3 4 if (cell == nil) { 5 cell = [[[UITableViewCell alloc] initwithstyle: UITableViewCellStyleDefault autorelease]; 6 } 7 cell.textlabel.text = [NSString \%i \%i", indexpath.section,indexpath,row]; 8 9 return cell; 10 } Listing 6.26: Erzeugung von Tabellenzellen (mit Caching). Listing 6.26 zeigt das von Apple empfohlene Vorgehen. Zu Beginn wird anhand des Reuse-Identifier überprüft, ob eine Zelle dieses Typs bereits existiert. Ist dies der Fall, wird diese Zelle zurückgegeben und deren Werte angepasst. Existiert keine 82

99 6.3. Optimierung von iphone-applikationen Zelle, wird eine mit entsprechendem Identifier erzeugt und als Ergebnis der Methode bereitgestellt. Somit wird bei großen Tabellen, die ausschließlich identische Zellentypen respektive Reuse-Identifier nutzen, nur ein einziges Zellenobjekt verwendet. Dies senkt die Speicher- und Prozessorauslastung und verbessert die Darstellungsperformanz. Gründe für ein eigenes Cachingverhalten Bei Nutzung der bereitgestellten Cachingmechanismen hat der Entwickler nur geringen Einfluss auf die Lebenszyklen der Objekte und das Verhalten im Falle einer Speicherwarnung. Diese Speicherwarnungen werden vom System an die Applikation gesendet, sobald der Arbeitsspeicher nahezu erschöpft ist. Mithilfe der didreceivememorywarning-methode kann das Verhalten nach Erhalt solch einer Warnung festgelegt werden. Bei Nutzung des bereitgestellten Cachings ist nicht ersichtlich, ob nicht mehr benötigte Bildobjekte noch im Speicher liegen oder diese gelöscht wurden. Um mehr Einfluss über diese Objekte zu haben, empfiehlt sich die Implementierung eines eigenen Cachingsystems, das innerhalb der didreceivememorywarning-methode sämtliche gecachten Objekte dealloziert. Aufbau des Cachingsystems Um auch in diesem Fall den Grundprinzipien guten Softwaredesigns gerecht zu werden, sollte eine zentrale Klasse das Cachingverhalten bündeln. Dies empfiehlt die Nutzung des Singleton-Patterns. Im Bezug auf wetravel enthält die sogenannte WTHelper- Klasse, neben den Cachingmethoden, die in Abschnitt 6.2 vorgestellten Methoden zur Bildanzeige. Diese Hilfsklasse nutzt ein statisches NSDictionary, das gemäß dem Key-Value-Grundsatz die zu cachenden Objekte bereitstellt. Listing 6.27 zeigt die eigene Fassung der imagenamed-methode. Als Schlüssel wird der Dateiname und als Wert das Bildobjekt genutzt. 1 - (UIImage *) imagenamed:(nsstring *)name { 2 // Pruefen, ob die Bilddatei bereits gecached wurde 3 UIImage * myimage = [thumbnailcache objectforkey:name]; 4 if (!myimage) { 5 // Bild wurde nicht gecached { 83

100 6. Entwicklung und Optimierung von iphone-applikationen 7 // Das gewuenschte Bild laden und dem Cache hinzufuegen 8 myimage = [UIImage imagewithcontentsoffile:[[nsbundle mainbundle] pathforresource:name 9 [thumbnailcache setobject:myimage forkey:name]; 10 } (NSException * e) { 12 myimage = nil; 13 } 14 } 15 return myimage; 16 } Listing 6.27: Die eigene Cachingmethode. Analog zu dieser Methode kann mithilfe der imageformanagedobject die in Abschnitt 6.2 vorgestellte Bildtransformation durchgeführt und das Ergebnis ebenfalls im Cache abgelegt werden. Durch diese Maßnahme muss jedes Bild nur ein einziges Mal angelegt und transformiert werden. 1 - (UIImage *) imageformanagedobject:(nsmanagedobject *)managedobject { 2 if (managedobject) { 3 UIImage * myimage = [imagecache objectforkey:[[[managedobject objectid ] URIRepresentation] description]]; 4 if (!myimage) { 5 // Das Bild aus dem Datenbankobjekt auslesen und transformieren 6 NSData * tempimage = [managedobject 7 myimage = [self maketransformedimage:[uiimage imagewithdata: tempimage] withsize:cgsizemake(50,50)]; 8 // Das Bild dem Cache hinzufuegen 9 [imagecache setobject:myimage forkey:[[[managedobject objectid] URIRepresentation] description]]; 10 } 11 // Reduziert den Speicherbedarf durch das Faulting von per Relation gelinkten Objekten 12 [[WTCentral sharedinstance].moc refreshobject:managedobject mergechanges:yes]; 13 return myimage; 14 } 15 return nil; 16 } Listing 6.28: Erzeugung der transformierten Bilder. 84

101 6.3. Optimierung von iphone-applikationen Listing 6.28 zeigt die genannte imageformanagedobject-methode. Datenbankobjekte werden anhand ihrer Core-Data-Objekt-ID im Cache abgelegt. Da die Objekt-ID nicht direkt genutzt werden kann, muss diese zuerst in ein konformes Format mittels der URIRepresentation- und description-methoden konvertiert werden. Zu Beginn muss hierbei die Existenz des Bildobjekts im Cache geprüft werden. Ist dieses noch nicht vorhanden, so wird es mit der objectpicture-zugriffsmethode abgefragt, transformiert und dem Cache hinzugefügt. Im Anschluss an die Generierung werden die Relationen des Managed Object zur Minimierung des Speicherverbrauchs gefaultet und das von nun an im Cache befindliche Bild zurückgegeben Bereitstellung effizienter Tabellenzellen Viele iphone-applikationen nutzen zur Visualisierung von Daten die Tabellen- bzw. Listenansicht des UIKit-Framework (vgl. zu diesem Abschnitt [App10n]). Bei dieser handelt es sich um eine einspaltige Struktur, die pro Zeile eine sogenannte Tabellenzelle zur Darstellung nutzt. Eine Tabellenzelle wird durch die Klasse UITableViewCell repräsentiert, deren Instanzen vor der eigentlichen Ausgabe auf dem Display des Endgeräts innerhalb eines verantwortlichen Controllers zur Anzeige von Daten vorbereitet werden. Für das Layout bietet die Klasse einige vordefinierte Stile an, die die Anordnung von zwei Textfeldern und einer Grafikansicht beeinflussen. Für die Verwendung in komplexen iphone-applikationen, besonders im Kontext von Applikationen mit angepasstem Look-And-Feel, sind diese zu primitiv und unflexibel, sodass die Entwicklung von angepassten Zellen zur Visualisierung unausweichlich ist. Innerhalb dieses Abschnitts steht der Diskurs verschiedener Ansätze zur Erzeugung von angepassten Tabellenzellen im Vordergrund. In diesem Sinne werden zunächst zwei gebräuchliche Formen und zuletzt eine besonders effiziente Methode zur Darstellung von Tabellenzellen analysiert. Autor: Benjamin Glatzel Die Tabellenzellen machen sich, wie sämtliche Darstellungsklassen des UIKit-Framework, das Composite-Pattern zunutze und erlauben somit eine hierarchische Anordnung von Unterelementen auf visueller und struktureller Ebene (vgl. hierzu Abschnitt 2.1.4). Zur Umsetzung des Konzeptes erbt die Klasse UITableViewCell zunächst von der Klasse UIView und stellt für die Entwicklung eine sogenannte Content-View bereit, die zur Darstellung weiterer Bedien- oder Darstellungselemente verwendet werden kann. Die Content-View wird bei der Initialisierung der Zelle auf die Ausmaße dieser 85

102 6. Entwicklung und Optimierung von iphone-applikationen gedehnt und als Unteransicht (eine sogenannte Sub-View) hinzugefügt. Von einer direkten Manipulation der Zelle, beispielsweise durch direktes Entfernen oder Hinzufügen von Unteransichten, außerhalb des Kontextes der Content-View ist abzusehen, da die Zelle verschiedene Zustände einnehmen kann. So kann beispielsweise durch das Ausführen einer horizontalen Fingerbewegung ein Löschvorgang des zugrunde liegenden Datenobjektes initiiert und zur Bestätigung dessen muss ein entsprechender Button innerhalb der Zelle eingeblendet werden. Die Content-View wird hierbei entsprechend des aktuellen Status in Form und Position ausgerichtet. Der allgemeine Aufbau einer Tabellenzelle, die sich im Normalzustand befindet, ist in Abbildung 6.14 dargestellt. UITableViewCell : UIView Accessory-View : UIView Content-View : UIView Abbildung 6.14.: Struktureller Aufbau einer UITableViewCell. Für die Erzeugung von angepassten Tabellenzellen bieten sich zunächst zwei offensichtliche Möglichkeiten an: die direkte Manipulation der Content-View durch das Schreiben von Programmcode oder durch Nutzung des Programms Interface Builder. Beide Ansätze führen zu einem identischen Endergebnis und unterscheiden sich letztendlich nur hinsichtlich des Komforts bei der Umsetzung. Mithilfe des Programms Interface Builder können GUI-Elemente erzeugt, angepasst und visuell innerhalb der Content-View platziert werden. Nach Fertigstellung der Zelle kann diese innerhalb des Programmcodes dynamisch geladen und als UITableViewCell-Instanz genutzt werden. Beide Methoden setzen die Nutzung der UIKit-GUI-Elemente voraus, die zur Darstellung von der Klasse UIView erben. Für die Darstellungen von Text oder Grafiken müssen somit Instanzen der Klassen UILabel bzw. UIImageView verwendet werden. Durch die Erzeugung von Sub-Views und die Ausnutzung des Composite-Patterns kann, je nach Verwendung, die Performanz der Applikation beeinflusst werden. Apple beschreibt dieses Problem in der Dokumentation wie folgt: 86

103 6.3. Optimierung von iphone-applikationen However, if you do take this approach, avoid making the views transparent, if you can. Transparent subviews affect scrolling performance because of the increased compositing cost. (siehe [App10n]) Bei der Entwicklung hat sich gezeigt, dass die Darstellung der in Abbildung 6.14 gezeigten Tabellenzelle unter Verwendung der Darstellungselemente des UIKit-Framework (auf einem ipod touch der zweiten Generation) zu starken Performanzeinbrüchen geführt hat. Dies hat sich besonders beim Scrolling innerhalb großer Datenbestände bemerkbar gemacht. Im soeben genannten Zitat ist die zugrunde liegende Problematik bereits beschrieben: Die in Abbildung 6.14 gezeigte Tabellenzelle nutzt einen angepassten Hintergrund in Form einer PNG-Grafik. Zudem besteht die Zelle aus zwei weiteren Grafikelementen sowie einer Vielzahl von Textelementen. Diese können aufgrund der Hintergrundgrafik nicht, wie Apple es vorschlägt, deckend dargestellt werden, da es sonst zu unschönen, undurchsichtigen Farbrahmen kommen würde. Da ein flüssiger Bildlauf eine wichtige Anforderung bei der Entwicklung von iphone- Applikationen ist, muss hierzu eine Lösung gefunden werden, die diese Problematik ohne Reduzierung der Tabellenzellenkomplexität behebt. Der im Folgenden besprochene Ansatz orientiert sich an einem Blogeintrag des Entwicklers des offiziellen iphone- Twitter-Client (siehe [Ate08]) und erweitert dessen Vorschlag beispielsweise um die statusabhängige Anpassung der Darstellung. Der Grundgedanke liegt darin, sämtliche Zeichenvorgänge manuell über das Core-Graphics-Framework auszuführen und nahezu vollständig auf die Nutzung der UIKit-Klassen zu verzichten. Hierzu bietet sich der Entwurf einer Basisklasse an, welche die Zeichenmethode der Content-View in der Tabellenzellenklasse verfügbar macht, sodass diese letztendlich von erbenden Klassen implementiert werden kann. Die Struktur des Konzepts ist in Abbildung 6.15 gezeigt. Für die Umsetzung des Konzeptes müssen zwei Klassen erzeugt werden. Die erste Klasse, in diesem Beispiel WTTableViewCell genannt, dient als Basisklasse für alle zukünftigen Tabellenzellen und stellt zunächst lediglich einen Methoden-Stub drawcontentview bereit. Um diese Methode an die tatsächliche Zeichenmethode der Content-View zu binden, muss eine Tochterklasse von UIView erstellt werden, die die Zeichenmethode drawrect dieser an die soeben besprochene Methode der Oberklasse weiterleitet. Diese zweite Klasse, WTTableViewCellView genannt, dient somit als Content-View und muss innerhalb des Konstruktors der Klasse WTTableViewCell entsprechend initiali- 87

104 6. Entwicklung und Optimierung von iphone-applikationen UITableViewCell UIView contentview : UIView mystatemask : mystatemask WTTableViewCell +initwithreuseidentifier(reuseidentifier : NSString) : id +setneedsdisplay +willtransitiontostate(state : UITableViewCellStateMask) +drawcontentview(r : CGRect) WTTableViewCellView +drawrect(r : CGRect) contentview Abbildung 6.15.: Entwurf einer Basisklasse zur effizienten Darstellung von angepassten Tabellenzellen. siert und gesetzt werden. An dieser Stelle sollte die Content-View auf opaque, sprich nicht-transparent, gesetzt werden, sodass möglichst wenige Berechnungen ausgeführt werden müssen. Der soeben beschriebene Ansatz kann für einfache Tabellenzellen zunächst ausreichend sein. Da die Content-View manuell erzeugt wird, muss zudem der Darstellungsrahmen dem Rahmen der Tabellenzelle entsprechend angepasst werden. Hierzu bietet sich die Implementierung der UIView-Methode layoutsubviews an, die bei einer Änderung des Layouts implizit ausgeführt wird. Listing 6.29 zeigt eine mögliche Implementierung der Methode zum Setzen des entsprechenden Darstellungsfeldes der Content-View. 1 - (void)layoutsubviews { 2 CGRect b = [self bounds]; 3 // Den Darstellungsbereich der Content-View setzen 4 [contentview setframe:b]; 5 [super layoutsubviews]; 6 } Listing 6.29: Anpassung des Rahmens der Content-View. Dennoch können, wie bereits erwähnt, Tabellenzellen verschiedene Zustände annehmen, in denen der Zelle weitere Bedienelemente hinzugefügt werden. Ließe man dies außer Acht, würde beispielsweise eine Zelle, die sich im Editiermodus befindet, den Inhalt der Content-View mit einem Löschbutton überlagern. Hierzu bietet die Klasse UITable- ViewCell zwei Methoden an, die bei einer Änderung des Zellenstatus aufgerufen werden. 88

105 6.3. Optimierung von iphone-applikationen Diese können innerhalb der Klasse WTTableViewCell überschrieben und beispielsweise zur Speicherung des aktuellen, als Integer encodierten Zellenstatus verwendet werden. Für dieses Beispiel wird die Methode willtransitiontostate zur frühzeitigen Erkennung eines Übergangs verwendet (siehe Listing 6.30). 1 - (void)willtransitiontostate:(uitableviewcellstatemask)state { 2 mystatemask = state; 3 [super willtransitiontostate:state]; 4 } Listing 6.30: Erfassung des aktuellen Zellenstatus. Der aktuelle Status der Klasse kann nun, wie beschrieben, in der Basisklasse WTTable- ViewCell durch Verwendung der Instanzvariable mystatemask in Erfahrung gebracht werden. Der letzte Schritt besteht nun darin, das Layout der Content-View entsprechend des aktuellen Zellenstatus auszurichten. Im Editiermodus werden ca. 30 Pixel zusätzlich im linken Bereich zur Darstellung des Löschbuttons benötigt. So bietet es sich an, die Content-View zunächst um 30 Pixel in der Breite zu vergrößern und um diesen Wert entlang der negativen x-achse zu verschieben. Die Zeichenfunktion draw- ContentView muss dieses Offset bei der Zeichnung der Zellenelemente entsprechend berücksichtigen. Das Konzept ist in Abbildung 6.16 dargestellt. Darstellungsbereich der UITableView Spielraum zur Verschiebung der Zelle Abbildung 6.16.: Konzept zur Ausrichtung von Tabellenzellen in Abhängigkeit zum aktuellen Zellenstatus. 89

106 6. Entwicklung und Optimierung von iphone-applikationen Demnach muss die bereits beschriebene Methode layoutsubviews angepasst werden, sodass diese zunächst die Content-View um 30 Pixel in der Breite erweitert und den Ursprung dieser entsprechend des aktuellen Zellenstatus verschiebt. Eine mögliche Implementierung dieser ist in Listing 6.31 dargestellt. 1 (void)layoutsubviews { 2 CGRect b = [self bounds]; 3 // 30 Pixel zur Breite der Content-View addieren 4 b.size.width += 30; 5 // Die Zelle stets 30 Pixel nach links verschieben, ausser dann, wenn im linken Bereich etwas dargestellt wird 6 b.origin.x -= ((mystatemask == 1 mystatemask == 3)? 0 : 30; 7 // Den Darstellungsbereich der Content-View setzen 8 [contentview setframe:b]; 9 [super layoutsubviews]; 10 } Listing 6.31: Ausrichtung der Zelle entsprechend des aktuellen Zellenstatus. Die soeben beschriebenen, effizienten Tabellenzellen lassen sich nun wie folgt verwenden: Zunächst muss eine Subklasse der Klasse WTTableViewCell angelegt und die Methode drawcontentview implementiert werden. Innerhalb dieser kann, wie in Abschnitt 6.2 gezeigt, der aktuelle Graphics-Context zur Zeichnung von Elementen verwendet werden. Für eine Zelle, die beispielsweise einen Titel enthält, muss dieser in Form eines String- Attributs für äußere Zugriffe erreichbar gemacht werden. Wird dieser beispielsweise über einen Akzessor verändert, muss die Methode setneedsdisplay der Content-View aufgerufen werden, sodass diese bei nächster Gelegenheit erneut gezeichnet und somit aktualisiert wird. Durch den nahezu vollständigen Verzicht auf die Nutzung des Composite-Patterns und der UIKit-GUI-Elemente kann eine deutliche Steigerung der Performanz vermerkt werden. Der Grund hierfür liegt darin, dass nur eine einzige View, die Content-View, für die Darstellung einer im Voraus berechneten Grafik zuständig ist. Zudem wird diese Grafik nur dann erneut berechnet, wenn ein Attribut ersetzt bzw. verändert wurde. Die beschriebene Methode bietet noch weiteren Raum für Optimierungen, wie beispielsweise durch Integration und Verwendung der zuvor beschriebenen Caching- Algorithmen. Es bietet sich zudem an, sämtliche Hintergrundgrafiken und Schriftarten statisch abzulegen, sodass diese nicht für sämtliche Zelleninstanzen erneut in den 90

107 6.4. Entwicklung erweiterter Tabellenzellen Speicher geladen werden müssen. Trotz der Effizienz der beschriebenen Methode bringt diese einen entscheidenden Nachteil mit sich: Die Nutzung des komfortablen Werkzeugs Interface Builder entfällt vollständig. Es sollte somit, bevor dieser Weg eingeschlagen wird, die Komplexität der Tabellenzelle analysiert und bestenfalls über kurze Tests auf dem Endgerät geprüft werden Entwicklung erweiterter Tabellenzellen Bei der Entwicklung von grafischen Elementen für das Benutzerinterface können dank des multi-touch-fähigen Displays und der weiträumigen Integration des Core-Animation- Framework in das UIKit-Framework neue Wege bei der Entwicklung von interaktiven Benutzeroberflächen eingeschlagen werden. Innerhalb dieses Abschnittes soll anhand eines einfachen Beispiels sowohl die Erkennung einer Multi-Touch-Geste erläutert, als auch das Core-Animation-Framework zur Erzeugung animierter Interface-Elemente demonstriert werden. Hierbei liegt der Fokus auf den wesentlichen Elementen, die bei der Entwicklung besondere Bedeutung haben und zum Verständnis der Grundkonzepte notwendig sind. Eine vollständige Implementierung der im Folgenden beschriebenen Funktionalität kann hierbei nicht gewährleistet werden. Der gesamte Abschnitt basiert auf den Informationen der iphone Application Programming Guide (siehe [App10h]). Für die Initiierung und Darstellung einer Datenübertragung können bei der Entwicklung des Benutzerinterface verschiedene Wege eingeschlagen werden. So könnte beispielsweise ein einfacher Button zum Start der Transaktion in Verbindung mit einer getrennten Ansicht zur Darstellung von Übertragungsinformationen verwendet werden. Um auf den Übergang zu einer getrennten Ansicht zu verzichten, könnte die aktuelle Ansicht beispielsweise direkt mit einer Statusanzeige visuell überlagert werden. Abbildung 6.17 (a) zeigt den Einsatz einer getrennt entwickelten View zur Überlagerung der Anzeige und der Darstellung von Statusinformation hinsichtlich der exemplarischen Übertragung einer Datensicherung. Bei der Betrachtung von aktuellen iphone-applikationen werden für ähnliche Aufgaben jedoch häufig gänzlich neue Wege eingeschlagen: Innerhalb des offiziellen iphone- Twitter-Clients kann beispielsweise eine Tabellenzelle durch Ausführung einer horizontalen Fingerbewegung beiseitegeschoben werden, um somit kontextbezogene Buttons 91

108 6. Entwicklung und Optimierung von iphone-applikationen (a) Overlay-View (b) Twitter-App Abbildung 6.17.: Zwei Ansätze zur Darstellung von kontextbezogenen Informationen und Optionen. freizulegen (siehe Abbildung 6.17 (b)). Als Beispiel soll dieses Konzept in ähnlicher Art und Weise umgesetzt und eine erweiterte Tabellenzelle entwickelt werden, die durch Ausführung einer horizontalen Fingerbewegung einen Übertragungsvorgang an einen Webserver initiiert. Die Nutzung dieser Geste ist zunächst nicht intuitiv. Dennoch schließt sie ein versehentliches Ausführen der Übertragung bei einer Vielzahl von Zellen aus. Die Beschriftung der Zellenvorderseite bietet sich als geeigneten Ort zur Beschreibung der Geste an, um Missverständnisse seitens der Benutzer auszuschließen. Nach dem Start der Übertragung soll die Tabellenzelle animiert auf ihre Rückseite gedreht und ein Aktivitätsindikator sowie eine textuelle Beschreibung dargestellt werden. Bei einer erneuten Ausführung der horizontalen Multi-Touch-Geste soll die Zelle in den Ursprungszustand zurückversetzt und der Übertragungsvorgang unterbrochen werden. Der Aufbau und die Interaktionsmöglichkeiten der Zelle sind in Abbildung 6.18 zur Verdeutlichung grafisch dargestellt. 92

109 6.4. Entwicklung erweiterter Tabellenzellen Ursprungszustand I Ausführung der Multi-Touch-Geste II Rotation der Zelle III Übertragungsvorgang IV Display-Berührungspunkt Abbildung 6.18.: Genereller Aufbau und Interaktionsmöglichkeiten der Beispielzelle. Die in Abschnitt erläuterten effizienten Tabellenzellen können durch Vererbung als direkte Grundlage dieser erweiterten Zellenform verwendet werden. Für die Umsetzung der Zelle wird nun zunächst die Implementierung einer individuellen Multi-Touch-Geste erläutert und im Anschluss die Umsetzung einer Rotationsanimation mithilfe des Core- Animation-Framework demonstriert. Die Erkennung bestimmter Bewegungsmuster auf dem Display kann mithilfe des iphone SDK vollständig objektorientiert implementiert werden. Die Klasse UIResponder ist die Superklasse sämtlicher UIView-Klassen und somit auch sämtlicher Tabellenzellen. Diese stellt, unter anderem, die für die Erkennung der angestrebten, horizontalen, Geste notwendigen Methoden bereit: touchesbegan:withevent: und touchesended:withevent:. Diese werden bei der Initiierung bzw. Beendigung von Displayberührungen aufgerufen und mithilfe eines Sets von Instanzen der Klasse UITouch über die Berührungspunkte auf dem Display informiert. Die UITouch-Instanzen können zur Ermittlung der Berührungspunkte in Relation zur aktuellen Ansicht, sprich der Tabellenzelle, verwendet werden. Für die Erkennung einer horizontalen Fingerbewegung muss eine Differenz zwischen dem Ausgangsberührungspunkt und der Position des Fingers nach Verlassen des Displays ermittelt werden. Diese zwei nichtnegativen Punkte seien im Folgenden x und y genannt. Um die Empfindlichkeit der Zelle festzulegen, sollte der Endpunkt der ausgeführten Fingerbewegung entlang der x-achse einen Mindestwert erreichen und zudem keine deutlichen Abweichungen auf der y-achse aufzeigen. Abbildung

110 6. Entwicklung und Optimierung von iphone-applikationen zeigt eine Fläche im 2D-Raum, die alle validen Endpunkte für die Ausführung einer horizontalen Fingerbewegung beinhaltet. Der Ausgangsberührungspunkt liegt hierbei im Ursprung der Koordinatenachsen. Δy Valide Berührungsendpunkte Ausgangsberührungspunkt Δx Breite des Displays Abbildung 6.19.: Fläche zur Eingrenzung der erlaubten Werte der Variablen x und y zur Bestimmung einer horizontale Fingerbewegung auf dem Display. Zur Implementierung muss somit der Ausgangsberührungspunkt mithilfe der Methode touchesbegan:withevent: vermerkt werden, beispielsweise unter Zuhilfenahme einer Instanzvariablen, und innerhalb der Methode touchesended:withevent: zur Kalkulation der Differenzpunkte verwendet werden. Listing 6.32 zeigt eine exemplarische Implementierung zur Erkennung einer horizontalen Fingerbewegung. Die Toleranz der Auswertung steht in Abhängigkeit zu den Ausmaßen der Tabellenzelle und der Breite des Displays. 1 - (void) touchesbegan:(nsset *)touches withevent:(uievent *)event { 2 UITouch * anytouch = [touches anyobject]; 3 // Den Ausgangsberuehrungspunkt speichern 4 mygesturestartingpoint = [anytouch locationinview:self]; 5 [super touchesbegan:touches withevent:event]; 6 } 7 - (void) touchesended:(nsset *)touches withevent:(uievent *)event { 8 UITouch * anytouch = [touches anyobject]; 9 // Die aktuelle Position des Fingers innerhalb der Tabellenzelle ermitteln 10 CGPoint currentpos = [anytouch locationinview:self]; 94

111 6.4. Entwicklung erweiterter Tabellenzellen 11 // Ermittlung der Deltawerte 12 CGFloat deltax = fabsf(mygesturestartingpoint.x-currentpos.x); 13 CGFloat deltay = fabsf(mygesturestartingpoint.y-currentpos.y); 14 // Die Deltawerte pruefen 15 if (deltay < 40 && deltax > 20) { 16 // Horizontale Fingerbewegung erkannt 17 [self togglestate]; 18 } 19 [super touchesended:touches withevent:event]; 20 } Listing 6.32: Auswertung einer horizontalen Fingerbewegung. Bei Betrachtung des Implementierungsbeispiels ist es auffällig, dass die Methode anyobject der Klasse NSSet verwendet wird. Hierdurch wird bei mehreren Berührungspunkten auf dem Display ein zufälliger Punkt gewählt und gewertet. So kann die Geste auch mit mehreren Fingern auf dem Display erkannt und ausgeführt werden. Die Erzeugung einer Rotationsanimation mithilfe von Core Animation kann nun mit der soeben beschriebenen Multi-Touch-Geste in Verbindung gebracht werden. Die Klasse UIView ist, wie bereits erwähnt, die Superklasse sämtlicher Tabellenzellen und bietet eine Schnittstelle zur einfachen Erzeugung von Animationen auf Basis des Core-Animation-Framework. Hierzu muss zunächst der Beginn einer Animation bei der Klasse UIView registriert und einige Parameter zur Definition der Animation übergeben werden. Zuletzt muss die Animation mit einem einfachen Methodenaufruf initiiert werden. Die Erzeugung einer dem Beispiel entsprechenden Rotationsanimation und Zellenrückseite kann wie folgt realisiert werden: Innerhalb des Konstruktors der speziellen Tabellenzelle müssen die Elemente für die Rückseite der Content-View hinzugefügt und der Alpha-Wert dieser genullt werden. Um die Elemente nach einer erfolgten Rotationsanimation darzustellen, müssen diese vor der eigentlichen Initialisierung der Animation sichtbar gemacht werden. Das Core-Animation-Framework übernimmt ab diesem Punkt sämtliche weiteren Schritte und lagert die Animation in einen getrennten Thread aus, sodass die Reaktivität des Benutzerinterface nicht beeinträchtigt wird. Listing 6.33 zeigt die Vorbereitung und Ausführung einer Rotationsanimation, nach deren Abschluss sämtliche der zuvor hinzugefügten GUI-Elemente (sozusagen auf der Rückseite) sichtbar gemacht werden. Hierbei wird die Existenz der booleschen Instanzvariablen myshowsbackside vorausgesetzt, die den aktuellen Status 95

112 6. Entwicklung und Optimierung von iphone-applikationen der Zelle widerspiegelt. Mit Rückblick auf die beschriebene Methodik zur Erzeugung effizienter Tabellenzellen kann anhand dieser beispielsweise auch der zu zeichnende Inhalt bestimmt werden. 1 - (void) togglestate { 2 if (!myshowsbackside) { 3 // Saemtliche Darstellungslemente einblenden 4 for (UIView * v in [contentview subviews]) { 5 v.alpha = 1.0; 6 } 7 // Eine neuen Animationsblock beginnen 8 [UIView context:nil]; 9 // Die Dauer der Animation festlegen 10 [UIView setanimationduration:0.4]; 11 // Den Animationstyp und die betroffene View festlegen 12 [UIView setanimationtransition:uiviewanimationtransitionflipfromleft forview:contentview cache:yes]; 13 // Den aktuellen Status speichern 14 myshowsbackside = YES; 15 // Die aktuelle View aktualisieren 16 [self setneedsdisplay]; 17 // Die Animation ausfuehren 18 [UIView commitanimations]; 19 } else { 20 // Paralleler Ablauf zur Vorderseite 21 } 22 } Listing 6.33: Erzeugung einer Rotationsanimation mithilfe von Core Animation. Diese exemplarische Implementierung setzt zunächst den Alpha-Wert der hinzukommenden Sub-Views auf 1, sodass diese nach erfolgter Animation sichtbar werden. Im Anschluss wird ein neuer Animationsblock erzeugt und die notwendigen Parameter für die Animation gesetzt. Vor dem Start der Animation wird der Status der Zelle angepasst und eine Aktualisierung des View-Layouts erzwungen. Um das Beispiel funktional zu vervollständigen, müsste an dieser Stelle zudem die Kommunikation mit dem Server initiiert und im Falle eines Fehlers die Zelle in den ursprünglichen Zustand rotiert werden. Um die Serverkommunikation, die mit der zuvor erläuterten Serverkommunikationsklasse (siehe Abschnitt 6.1.5) ausgeführt werden kann, erst nach erfolgter Rotation auszuführen, kann ein Delegat für eine bestimmte Animation und 96

113 6.5. Erstellung einer funktionsreduzierten Programmversion bestimmte Animationszustände registriert werden. Hierzu muss eine Referenz auf das zu benachrichtigende Objekt sowie eine Beschreibung der auszuführenden Methode, im Kontext von Objective-C ein sogenannter Selektor, übergeben werden. Dieser Abschnitt hat gezeigt, dass die Interpretation von einfachen Multi-Touch-Gesten dank des UIKit-Framework sehr elegant umgesetzt werden kann. Auch die Erzeugung von Animationen mithilfe des Core-Animation-Wrapper der Klasse UIView hat sich als sehr praktikable Lösung für die Bereitstellung interaktiver Bildschirmelemente bewiesen. Animationen und Multi-Touch-Gesten können dank der Frameworks sehr gut in das Benutzerinterface integriert und, je nach Einsatz, die Bedienbarkeit der Applikation fördern. Bei der Implementierung muss jedoch immer abgewogen werden, ob eine Animation oder die Nutzung von Multi-Touch-Gesten für den Endbenutzer nützlich ist und ob deren Verwendung intuitiv erschlossen werden kann. Wie das Beispiel des offiziellen Twitter-Clients gezeigt hat, wird häufig auf eine explizite Erläuterung der Methodik innerhalb der Applikation verzichtet. Dies kann die Bedienbarkeit besonders für Benutzer, die zuvor noch kein multi-touch-fähiges Gerät besessen haben, mindern. Zur Sicherstellung des Verständnisses sollte die nötige Geste vor Ort oder zumindest in Form einer kurzen Erläuterung innerhalb der Applikation oder Applikationsbeschreibung vermerkt sein Erstellung einer funktionsreduzierten Programmversion Vielen Interessenten reichen die im App Store enthaltenen Informationen und Screenshots bezüglich einer Applikation nicht aus. Um diesen potenziellen Käufern einen besseren Einblick in die Applikation zu bieten, sollte die Entwicklung und Bereitstellung einer sogenannten Lite-Version in Betracht gezogen werden. Diese Lite-Version ist eine eigenständige über den App Store erhältliche Applikation, die kostenlos angeboten wird und im Funktionsumfang beschränkt ist. Sowohl Kunden als auch Entwickler profitieren von dieser Lite-Version. Der Entwickler kann mehr Kunden an sich binden, die nach erfolgreichem Test die Vollversion kaufen. Durch in die Lite-Version integrierte In-App- Purchase-Produkte besteht die Möglichkeit zusätzlich Geld zu verdienen. Da mit dem Erwerb dieser Version keine weiteren Kosten verbunden sind, kann der Interessent die Autor: Dominik Wilhelm 97

114 6. Entwicklung und Optimierung von iphone-applikationen Applikation vorab testen und hat somit einen besseren Überblick über Funktionsumfang und Bedienung. Jede Applikation muss bei Einreichung zum Review-Prozess eine Primär- und eine Sekundärkategorie zugeteilt bekommen. Nach Veröffentlichung im App Store erscheint diese Applikation jedoch nur in der Primärkategorie. Durch Tausch der beiden Kategorien bei der Lite-Version kann somit in beiden Kategorien eine Applikation erscheinen. Die Erstellung mehrerer Programmversionen, in diesem Beispiel Lite- und Vollversion, kann über mehrere Möglichkeiten realisiert werden. Die administrativ aufwendigste Methode ist die Erstellung einer Kopie der Quell- und Ressourcendateien. Nachdem die Kopie erzeugt wurde, müssen lediglich die Applikationsinformationen angepasst sowie die eventuellen Limitierungen oder Erweiterungen integriert werden. Bei der Wartung beider Versionen wird jedoch der entscheidende Nachteil ersichtlich. Bei Fehlern oder Erweiterungen in identischen Codepassagen müssen beide Projekte angepasst werden. Dies ist nicht nur ein enormer Mehraufwand, sondern zudem eine zusätzliche Fehlerquelle. Eine weitaus bessere Variante bietet Xcode in Verbindung mit dem genutzten Compiler. Statt das Projekt zu kopieren, werden weitere sogenannte Targets hinzugefügt. Diese Targets besitzen eigene Profile für den Kompiliervorgang und können den Versionen angepasste Ressourcen einbinden. Innerhalb dieser Profile können Makros für den Präprozessor definiert und innerhalb des Quellcodes mithilfe verschiedener Kontrollstrukturen überprüft werden. Während des Kompilierungsvorgangs werden diese Präprozessoranweisungen analysiert und je nach Wert der zugehörige Quellcode kompiliert. Diese Vorgehensweise ermöglicht die einfachere Wartung des Codes, da nur noch eine Version existiert und somit an nur einer Stelle Anpassungen vorgenommen werden müssen. 98

115 6.5. Erstellung einer funktionsreduzierten Programmversion Abbildung 6.20.: Buildkonfiguration für eine Lite-Version Die in Abbildung 6.20 gezeigte Konfiguration setzt das Präprozessormakro namens LI- TE_VERSION. In Listing 6.34 wird die Überprüfung dieses Makros und die damit einhergehende Anpassung des Quellcodes gezeigt. Da in diesem Fall das LITE_VERSION - Makro definiert wurde, wäre die Ausgabe somit Ich bin eine Lite-Version. 1 NSString * typ 2 #ifdef LITE_VERSION 3 typ 4 #endif 5 bin eine Listing 6.34: Abfrage eines Präprozessormakros. 99

116 6. Entwicklung und Optimierung von iphone-applikationen 6.6. Anforderungen an die Software hinsichtlich des Apple- Review-Prozesses Nach Beendigung der Entwicklungsphase einer Applikation muss diese, bevor sie verkauft werden darf, von Apple analysiert und für den App Store freigegeben werden. Für diesen Prozess werden neben dem Namen und einer Detailbeschreibung noch weitere Daten benötigt. Hierzu zählen unter anderem ein Pixel großes Icon sowie die Auswahl einer Primär- und Sekundärkategorie. Der Entwickler muss neben der Annahme verschiedener Lizenzen auch Kontaktdaten sowie Screenshots der Applikation bereitstellen. Sind letztendlich alle Voraussetzungen erfüllt, kann die Applikation an Apple übertragen und von einem Mitarbeiter kontrolliert werden. Im Internet kursieren viele Gerüchte über diesen Prozess. Primär sollte sich jedoch an die iphone Developer Program License Agreement, kurz idpla (siehe [App10i]), gehalten werden. Dieses Lizenzabkommen enthält eine Vielzahl an Regelungen, die eingehalten werden müssen, sodass ein Verkauf der Applikation seitens Apple genehmigt wird. So dürfen ausschließlich dokumentierte APIs genutzt und nur in den Sprachen C, C++ und Objective-C angesprochen werden. Die Applikation muss in den genannten Sprachen geschrieben sein und darf keinen Quellcode zur Installation und Ausführung getrennter Applikationen beinhalten. Zusatzfeatures dürfen nur über den App Store als sogenannte In-App-Purchase-Produkte angeboten, verkauft und freigeschaltet werden. Lese- und Schreibzugriffe dürfen nur innerhalb des Applikationsverzeichnisses genutzt werden. Neben den Human Inteface Guidelines (vgl. [App10j]) und den restlichen, von Apple bereitgestellten, Dokumentationen muss die Applikation auch den lokalen Datenschutzgesetzen entsprechen. Bei Zugriff auf die geografischen Lokalisierungsfunktionen sowie weiteren Hardwarefeatures des iphone, wie zum Beispiel WLAN oder Bluetooth, muss der Benutzer explizit über deren Nutzung informiert werden. Vom iphone selbst stammende Nachrichten und Alarmmeldungen dürfen weder überschrieben, ignoriert noch entfernt werden. Fragliches Material in Text, Grafik, Bild und Ton ist nicht erlaubt, wie beispielsweise Pornographie. Der Einstufungsprozess liegt vollständig in den Händen von Apple und ist für Außenstehende nur schwer nachvollziehbar. Vor Einreichung der Applikation sollte diese aufgrund dessen intensiv auf die genannten Punkte geprüft und alle Widersprüche beseitigt werden. Neben der Einhaltung der Lizenzen und Richtlinien spielt die Qualität der Applikation 100

117 6.6. Anforderungen an die Software hinsichtlich des Apple-Review-Prozesses eine besondere Rolle. Vor Einreichung der Applikation sollte diese aufgrund dessen intensiv auf Fehler überprüft werden. Dies kann mithilfe des Programms Instruments, das dem SDK beiliegt, realisiert werden. Mit Instruments kann die Applikation sowohl im Simulator als auch auf einem Testgerät analysiert und hinsichtlich verschiedener Gesichtspunkte Rückschlüsse gezogen werden. So kann zum einen die Applikation in Bezug auf die Auslastung des Arbeitsspeichers und Prozessors optimiert werden. Zum anderen können Memory-Leaks ermittelt und im Anschluss entfernt werden. Neben diesen hilfreichen Funktionen bieten sich noch eine ganze Reihe an weiteren Analysefunktionalitäten, die Instruments zu einem unverzichtbaren Werkzeug für Entwicklung und Fehlerbehebung machen. Abbildung 6.21.: Das Analysewerkzeug Instruments Abbildung 6.21 zeigt Instruments während der Analyse der Objekt Allokationen und Suche nach Memory-Leaks. 101

118 6. Entwicklung und Optimierung von iphone-applikationen 6.7. Fazit Bei der Entwicklung von iphone-applikationen müssen viele verschiedene Kriterien beachtet und in den Entwicklungsprozess mit einbezogen werden. Durch den von Apple durchgeführten Review-Prozess als auch die begrenzten Ressourcen ist eine Optimierung der Applikation hinsichtlich Fehlerfreiheit bzw. Fehlertoleranz sowie Performanz zwingend notwendig. Dieses Kapitel hat Möglichkeiten aufgezeigt, diese Anforderungen zu erfüllen. Eine Verbesserung der Wartbarkeit wird durch strikte Anwendung der Grundprinzipien aus dem Bereich der Softwaretechnik erreicht und die Performanz der Applikation konnte durch Implementierung eines globalen Cachingsystems sowie der Nutzung der vorgestellten, angepassten Tabellenzellen gesteigert werden. Wie die Abschnitte und zeigen, dient die Bereitstellung zentraler Klassen zudem der Individualisierung der Applikation. Abschnitt 6.2 erläutert außerdem, wie die Darstellung von GUI-Elementen mittels Multi-Touch-Erkennung und dem Core- Animation-Framework erweitert werden kann und somit neue Möglichkeiten hinsichtlich der Bedienung erschaffen werden können. Durch Anwendung der von Apple genutzten Namenskonventionen und einer guten Dokumentierung wird die Verständlichkeit, auch für nicht mit dem Quellcode vertraute Entwickler, verbessert. Die Nutzung der im iphone-sdk enthaltenen Werkzeuge empfiehlt sich in vielerlei Hinsicht. So können komfortabel die benötigten Views mit dem grafischen Designer Interface Builder erstellt und mit den zugehörigen Klassen verknüpft werden. Auch das Datenmodell kann mit einem in Xcode integrierten Planungstool erstellt werden, während die Erzeugung von Klassengerüsten im Anschluss automatisch erfolgen kann. Xcode stellt die zentrale IDE des iphone-sdks dar, mit deren Hilfe der Großteil der Entwicklung durchgeführt wird. Mithilfe der in Abschnitt 6.5 vorgestellten Buildkonfigurationen können zudem mehrere Programmversionen aus einem gemeinsamen Projekt erstellt werden. Das kompilierte Programm kann letztendlich auf dem iphone Simulator bzw. mithilfe des Analyseprogramms Instruments getestet und auf Speicherfehler sowie Speicherlecks geprüft werden. 102

119 KAPITEL 7 Leichtgewichtige Webentwicklung und Webservice-Integration Das World Wide Web hat sich in den letzten zehn Jahren einem stetigen Wandel unterzogen und stellt viele neue Herausforderungen an die Entwickler von Webapplikationen. Moderne Web-Application-Frameworks wie Ruby on Rails sollen den neuen Anforderungen gerecht werden und die Entwicklung von sogenannten Web-2.0-Anwendungen erleichtern. Ziel dieses Kapitels ist es, Kernthemen bei der Entwicklung von Webapplikationen anhand des Dienstes wetravel online zu betonen und mögliche Lösungsansätze zu demonstrieren. Zudem steht die Ausarbeitung und Implementierung einer Webserviceschnittstelle im Mittelpunkt, welche die Integration der iphone-applikation wetravel ermöglicht. Autor: Benjamin Glatzel In diesem Kapitel steht zunächst eine einfache Variante des Webservices im Vordergrund, während dieser in Kapitel 8 zusammen mit der iphone-applikation um die Abonnementfunktionalität erweitert wird. Es ist nicht beabsichtigt, eine vollständige Einführung in Ruby on Rails bereitzustellen, da dies aufgrund der Vielschichtigkeit des Framework den Rahmen dieser Arbeit übersteigen würde. Vielmehr sollen einige Grundkonzepte verdeutlicht und die Eleganz des Framework anhand einiger Problemstellungen demonstriert werden. Als technische Grundlage für dieses Kapitel dienen 103

120 7. Leichtgewichtige Webentwicklung und Webservice-Integration die Bücher Agile Web Development with Rails (siehe [RTH09]) und Programming Ruby (siehe [Tho05]) sowie die offiziell bereitgestellte API-Dokumentation von Ruby on Rails (siehe [Han10b]). Grundkenntnisse in HTML und beliebigen, objektorientierten Programmiersprachen (bestenfalls Ruby und JavaScript) können zum Verständnis beitragen Das Web 2.0 als Evolutionsstufe des Internets Das Internet besteht seit Anbeginn aus drei Komponenten: dem Uniform Resource Locator (kurz URL), dem Hypertext Transfer Protocol (kurz HTTP), das für die Client-Server-Kommunikation verwendet wird, und der Hypertext Markup Language (kurz HTML), die für die Beschreibung des Inhalts zur Anwendung kommt (vgl. zu diesem Abschnitt [Ram09], Seite 52 ff.). Zusammen bilden diese drei Komponenten eine dezentralisierte Architektur, die das Anbieten von Inhalten ohne den Rückgriff auf einen zentralen Server ermöglicht. In den Neunzigerjahren rückte der Webbrowser als Werkzeug zur Betrachtung von Webseiten in den Mittelpunkt. Das zugrunde liegende Design des Webs ermöglichte das Verteilen von Inhalten auf verschiedenen Plattformen und die identische Darstellung derselben. Voraussetzung hierzu war lediglich die Installation eines zugehörigen Webbrowsers. In den Jahren 1995 bis 1999 führte die Konkurrenz zwischen den einzelnen Browser-Herstellern zur Einführung von vielen, herstellerspezifischen, HTML-Tags (zwei markante Beispiele sind blink oder marquee) wurde HTML 3.2 zur Dokumentation der gebräuchlichsten Entwicklungstechniken eingeführt und sollte die Arbeit der Webentwickler erleichtern. Kurz hierauf folgte die Einführung des HTML-4.0-Standards Hand in Hand mit den Cascading Style Sheets (CSS). In der Übergangszeit zwischen HTML 3.2 und HTML 4.0 dominierte der Internet Explorer 5 den Markt und diente als Vorbild der konkurrierenden Browser-Hersteller. Dies hatte zur Folge, dass sich das Web in diesem Zeitraum von dem Grundgedanken seines Schöpfers, Tim Berners-Lee, weiter entfernte, da sich die Erstellung von Webinhalten an den Verhaltensmustern eines einzigen Browsers orientierte, statt einen offenen Standard zur plattformunabhängigen Darstellung zu nutzen. Zudem stellte es sich als problematisch heraus, dass alle folgenden Webbrowsergenerationen die Implementierungen des Internet Explorers als Vorbild wählten, welcher wiederum viele Funktionen des Netscape-Browsers replizierte. Infolgedessen war es zu diesem Zeitpunkt, aufgrund der 104

121 7.1. Das Web 2.0 als Evolutionsstufe des Internets Differenzen bei der Implementierung des CSS-Standards, nahezu unmöglich Webseiten zu erstellen, die in den verschiedenen Webbrowsern ohne zusätzlichen Aufwand identisch dargestellt werden. Der HTML-4.0-Standard in Verbindung mit CSS hat sich zu Beginn des Jahrtausends durchgesetzt und formt zusammen mit JavaScript, als Technologie zur dynamischen Manipulation des Document Object Model (kurz DOM) und zur Erstellung interaktiver Webinhalte sowie zur Nutzung asynchroner Verbindungsaufrufe (XMLHttpRequests), die Grundlage für eine neue Generation des Internets Prinzipien und Praktiken im Umfeld des Web 2.0 Der Begriff Web 2.0 hat sich im Jahr 2005 dank des Artikels What Is Web 2.0 Design Pattern and Business Models for the Next Generation (vgl. zu diesem Abschnitt [O R05]) von Tim O Reilly weiträumig als Bezeichnung der aktuellen Evolutionsstufe des Internets durchgesetzt. Kernpunkt dessen ist es, dass das World Wide Web als eine Plattform zu betrachten ist und diese zur Distribution von Webapplikationen dient. Like many important concepts, Web 2.0 doesn t have a hard boundary, but rather, a gravitational core. You can visualize Web 2.0 as a set of principles and practices that tie together a veritable solar system of sites that demonstrate some or all of those principles, at a varying distance from that core. (siehe [O R05]) Wie dieses Zitat bereits andeutet, stellt das Konzept des Web 2.0 einige Prinzipien zur Verfügung, deren Einhaltung bei der Entwicklung die Zugehörigkeit der Webapplikationen bestimmt. So ist die Akkumulation von Gedankengut der Benutzer ein zentraler Aspekt von Web-2.0-Anwendungen. Ein besonders erfolgreiches Beispiel ist in diesem Fall der Algorithmus PageRank von Google, der nicht den Inhalt von Webseiten wertet, sondern die Wertigkeit jener anhand der Abhängigkeiten und Häufigkeiten von Verlinkungen bestimmt. Auch Blogs, Wikipedia, ebay und Amazon zählen zu den bedeutendsten Diensten des Web 2.0, da sie Benutzer in das Angebot integrieren und zur Verbesserung dessen beitragen lassen. Die im Vordergrund stehende Applikation ist jedoch nicht der einzige, entscheidende Faktor. Viele moderne Dienste nutzen einen enormen Datenbestand im Hintergrund, der unter hohen Investitionskosten zunächst 105

122 7. Leichtgewichtige Webentwicklung und Webservice-Integration aufgebaut werden muss. Die Firmen NAVTEQ und Tele Atlas investierten Hunderte Millionen Dollar zur Sammlung geografischer Daten. Diese finden in Webapplikationen, wie zum Beispiel Google Maps, Verwendung. Ebenso gilt es, gebräuchliche Softwareentwicklungsstadien (Planung, Entwicklung, Test, Veröffentlichung und Betrieb) zu durchbrechen und die Benutzer buchstäblich mit in die Entwicklung des Dienstes einzubeziehen. Oft zeichnet sich dies in langräumigen, öffentlichen Testphasen der Webapplikationen aus. Viele Dienste von Google sind beispielsweise seit der Veröffentlichung als Beta-Version gekennzeichnet. Es ist zudem wichtig, dass Software im Umfeld des Web 2.0 täglich aktualisiert wird, da viele Dienste andernfalls schnell an Wert verlieren würden. Der Einsatz von dynamischen Webseiten unter der Zuhilfenahme von serverseitigen Skriptsprachen und entsprechender Frameworks, wie später am Beispiel Ruby on Rails gezeigt wird, ist hierbei unverzichtbar Bereitstellung leichtgewichtiger Entwicklungsmodelle Die bereits erwähnten Technologien (HTTP, HTML, CSS und JavaScript) bieten die Grundlage zur Entwicklung mit leichtgewichtigen Entwicklungsmodellen. Dies lässt sich am Beispiel der Implementierung eines Webservices erklären: Statt auf komplexe Softwarelösungen zurückzugreifen, können diese Dienste über die Nutzung von XML-Strukturen zur Kapselung der zu übertragenden Daten und der Verwendung von HTTP als Übertragungsprotokoll realisiert werden. Architekturelle Entwürfe, wie zum Beispiel Representational State Transfer (kurz REST), können zur einheitlichen Gestaltung von Webservices verwendet werden. REST bietet hierzu ein Konzept zur Interaktion mit sogenannten Ressourcen, sprich persistente Entitäten, über eine fest definierte URL-Struktur unter Zuhilfenahme der HTTP-Verben POST, GET, PUT und DELETE. Als Ressourcen kommen jene Objekte infrage, für die sich die bekannten Datenbankoperationen CREATE, READ, UPDATE und DELETE eignen (vgl. [Rod08]). Alternativ findet das Simple Object Access Protocol (kurz SOAP) Anwendung. Die beschriebenen Techniken zur Realisierung von Webservices erlauben eine lose Kopplung von Dienstschnittstellen und werden weiträumig von Diensten, wie zum Beispiel Amazon, zur Übertragung von Suchanfragen verwendet. Unter der Zuhilfenahme von JavaScript und des DOMs wird die Entwicklung von Webapplikationen, die bis zu einem gewissen Grad die Interaktivität und den Komfort von Desktopsoftware 106

123 7.2. Ruby on Rails als Hilfsmittel bei der Entwicklung von Web-2.0-Applikationen replizieren können, ermöglicht. AJAX fasst, wie in den Grundlagen bereits beschrieben, sämtliche Technologien zusammen, die zur asynchronen Übertragung von Daten über den Browser notwendig bzw. hilfreich sind Ruby on Rails als Hilfsmittel bei der Entwicklung von Web-2.0-Applikationen Es bleibt nun zu klären, welche Stelle das Framework Ruby on Rails im Umfeld des Web 2.0 einnimmt. In Abschnitt 7.1 wurden bezüglich dessen zunächst die zentralen Aspekte herausgearbeitet. So ist es wichtig, dass gewohnte Software-Entwicklungsstadien durchbrochen und Alternativen gefunden werden, die sich für die schnelllebige Natur des Internets eignen. Webapplikationen werden häufig als sogenannte Public- Betas veröffentlicht und mithilfe des Feedbacks der Benutzer stetig im Hintergrund verbessert. Gewohnte Praktiken sind hier ungeeignet, da der Entwicklungsprozess auch nach der Veröffentlichung nicht beendet ist und stetig Erweiterungen, Verbesserungen und Aktualisierungen bereitgestellt werden müssen. Die Nutzung von Webframeworks, wie Ruby on Rails, sind bei der Entwicklung unverzichtbar. Zudem müssen Entwicklungsprozesse für die schnelllebige Natur des Web 2.0 gefunden werden. Eine Möglichkeit ist der Einsatz von agilen Entwicklungsprozessen (vgl. zu diesem Abschnitt [RTH09], Seite 18 f.). Die Kernpunkte des agilen Manifests (siehe [Bec+]) lassen sich direkt mit den von Ruby on Rails zur Verfügung gestellten Entwicklungsmethodiken in Verbindung bringen. Hierbei ist es nicht notwendig, diese explizit auf das Framework abzubilden, da sie bei einer ordnungsgemäßen Anwendung dessen impliziert werden. So besagt der erste Grundsatz, dass Individuen und Interaktionen über Prozesse und Tools zu stellen sind ( Individuals and interactions over processes and tools (siehe [Bec+])). Komplexe Entwicklungswerkzeuge sind, wie in den Grundlagen bereits erwähnt, für die Entwicklung nicht notwendig und der präferierte Texteditor ist vollkommen ausreichend. Die erleichterte Entwicklungsarbeit durch das Framework ermöglicht den Einsatz von kleinen Entwicklergruppen, während die Kunden respektive die Benutzer in kurzen Abständen Feedback liefern können ( Customer collaboration over contract negotiation (siehe [Bec+])). Auf eine detaillierte Betrachtung des agilen Manifests wird an dieser Stelle verzichtet. 107

124 7. Leichtgewichtige Webentwicklung und Webservice-Integration Ruby on Rails stellt, dank der Verwendung von Ruby als Programmiersprache und der Erweiterung der Kerngedanken dieser sowie des Verzichts auf komplexe Konfigurationsdateien, ein leichtgewichtiges Entwicklungsmodell dar (vgl. Abschnitt 7.1). Zudem werden die bereits erwähnten leichtgewichtigen Technologien respektive Konzepte weiträumig in allen Bereichen des Frameworks unterstützt. Mithilfe des sogenannten Scaffolding können beispielsweise REST-konforme Klassengerüste erzeugt werden. Hierbei werden, unter anderem, je ein Controller, eine Ansicht und eine Entitätsklasse erzeugt, die die Interaktion mit der zugrunde liegenden Ressource, sprich Datenbankentität, erlaubt. Für die Entwicklung von Webservices bietet Rails eine Vielzahl von unterstützenden Funktionen an, wie zum Beispiel zur Serialisierung von Datenstrukturen in XML oder JavaScript Object Notation (kurz JSON) Vertiefung des Konzepts der Webapplikation wetravel online Die iphone-applikation bietet die grundlegende Funktionalität und kann vollständig autonom verwendet werden, während die Webapplikation lediglich Erweiterungen zur Verfügung stellt und eine getrennte Benutzung ausschließt. Das Grundkonzept hierzu ist das Folgende: Falls ein gültiges Abonnement vorhanden ist, besteht innerhalb der iphone-applikation die Möglichkeit eine reduzierte Form des Datenbestandes an den Webservice zu übertragen. Die empfangenen Daten werden von der Webapplikation in die Datenbank übertragen und im internen Bereich des jeweiligen Benutzers verfügbar gemacht. Dieses Konzept nennt sich Report oder Buchungsreport. Dieser Datenbestand kann aufseiten des Servers zum Generieren und Drucken von Buchungsübersichten, zum Anzeigen einer Teilnehmerübersicht oder zum Versenden von Rechnungen an Teilnehmer verwendet werden. Reporte werden in der Datenbank nicht überschrieben, sondern stets getrennt zusammen mit dem eindeutigen Primärschlüssel der iphone- Applikation und einem Zeitstempel abgelegt. Bei der Generierung der Ansichten werden diese Informationen zur Gruppierung und Darstellung des Inhalts verwendet. Dies ermöglicht den Benutzern die Gegenüberstellung von verschiedenen Versionen einer Reise. Abbildung 7.1 zeigt eine Navigationsübersicht, die die jeweiligen Ansichten der Webapplikation in Verbindung bringt. 108

125 7.3. Vertiefung des Konzepts der Webapplikation wetravel online Benutzer meldet sich ab Anmeldung fehlgeschalgen wetravel online Anmeldemaske Gültiges Benutzerkonto Reportansicht Report und Typ gewählt Reportübersicht Anzeige in Form einer PDF Rechnungsvorschau Teilnehmeransicht Rechnungsversand Navigationsleiste Report und Typ gewählt Statistikansicht Statistiken Abbildung 7.1.: Navigationsübersicht zum strukturellen Aufbau von wetravel online. Die Darstellung orientiert sich an UML-Zustands- und UML-Aktivitätsdiagrammen. Beim Entwurf der Webapplikation wurde sich an bekannten Angeboten, wie beispielsweise MobileMe 1, orientiert. Zudem war die minimalistische Gestaltung der Oberfläche ein Primärziel, sodass die Benutzer nicht durch grafische Experimente vom eigentlichen Inhalt abgelenkt werden. Das Zentrum der Applikation besteht lediglich aus einer Navigationsleiste am oberen Rand und dem Inhaltsbereich im Zentrum (siehe Abbildung 7.2). Die Entwicklung der Weboberfläche wird in diesem Kapitel nicht genauer betrachtet. Es genügt an dieser Stelle zu sagen, dass für die Entwicklung dieser nur CSS und XHTML (validiert gegen XHTML 1.0 Strict) zur Anwendung kamen. An einigen Stellen wurden innerhalb der Stylesheets CSS-3.0-Übergangseigenschaften verwendet, um die manuelle Erstellung von Schatten oder abgerundeten Ecken zu vermeiden. Diese können in den neuen Versionen von Google Chrome, Apple Safari und Mozilla Firefox problemlos dargestellt werden, während die Verwendung in den aktuellen Versionen des Microsoft Internet Explorers zu keinem sichtbaren Ergebnis führt. 1 MobileMe ist ein kostenpflichtiger Webservice der Firma Apple. 109

126 7. Leichtgewichtige Webentwicklung und Webservice-Integration Abbildung 7.2.: Screenshot des internen Bereichs von wetravel online. 110

127 7.4. Einsatz und Verwendung von Buchungsreporten 7.4. Einsatz und Verwendung von Buchungsreporten Für die grundlegende Funktionalität zur Erzeugung von Buchungsreporten muss zunächst die Berechnungsmethodik der iphone-applikation repliziert werden. Während der Inhalt der jeweiligen Methoden an dieser Stelle von geringer Bedeutung ist, bleibt die Frage zu klären, welche Positionen sich im zugrunde liegenden Softwaredesign für die Implementierung eignen könnten. Die wiederholte Implementierung innerhalb der jeweiligen Controller stellt eine Möglichkeit dar, die jedoch zum Verstoß gegen das DRY-Prinzip führt, wenn eine Vielzahl von Reporten angeboten werden sollen. Die Auslagerung in einen übergeordneten Controller ist aus Sicht der Softwaretechnik ebenso ungenügend und führt zu einer schwachen Kohäsion. Bei der Entwicklung der iphone-applikation wurden die Berechnungsmethoden innerhalb der jeweiligen Entitätsklassen platziert. Diese Methodik kann auf die Webapplikation übertragen werden und wird vollständig von Active Record unterstützt. ActiveRecord::Base cd_object_id : string title : string - hash_password Trip + account_balance : float + account_balance_for_participant(participant) : float + exchange_rate_for_currency_code(string) : float Abbildung 7.3.: Die Klasse Trip bündelt sämtliche zugehörigen Berechnungsmethoden. Wie Abbildung 7.3 zeigt, werden der Klasse Trip die Methoden zur Berechnung der Gesamtkontostände (account_balance und account_balance_for_participant) hinsichtlich der gesamten Reise oder einzelner Teilnehmer zugeordnet. Hierbei besteht der Vorteil darin, dass diese Methoden direkt auf die über Relationen zugeordneten Datenbankobjekte zugreifen und die Berechnungsmethoden dieser verwenden können. Betrachtet man diese Lösung, hat man eine eindeutige Aufteilung von Zuständigkeiten erreicht, jede Funktionalität muss nur genau einmal implementiert werden und die Klassen sind nur durch ihre Relationen voneinander abhängig. Dieses Beispiel zeigt, dass Active Record eine vollständig transparente und objektorientierte Arbeit mit der zugrunde 111

128 7. Leichtgewichtige Webentwicklung und Webservice-Integration liegenden Datenbank ermöglicht. Diese Methoden können nun für die Generierung von verschiedenen Reporten, wie beispielsweise teilnehmer- oder exkursionsbezogenen Buchungsübersichten, verwendet werden. Die Implementierung der einzelnen Sichten und Controller kann mit wenig Aufwand realisiert werden und wird aufgrund dessen an dieser Stelle nicht weiter berücksichtigt Generierung von Statistiken mithilfe der Google Chart API Zur Integration von grafischen Statistiken bieten sich viele Möglichkeiten an. So könnte eine externe Bibliothek für die Generierung von Diagrammen verwendet werden. Als besonders leichtgewichtige Lösung bietet sich jedoch die Nutzung der Google Chart Tools an. Diese ermöglichen die Generierung einer Vielzahl von Diagrammtypen und können ohne die Installation externer Paketquellen verwendet werden. Bei Verwendung dieser bestehen zwei Zugriffsmöglichkeiten: Die Erste ermöglicht den Zugriff über eine JavaScript-Schnittstelle, die besonders für die Erstellung von interaktiven Statistiken geeignet ist. Die Zweite bietet die Nutzung einer REST-Schnittstelle an, die durch die Übergabe von URL-Parametern verwendet werden kann (vgl. zum Folgenden [Goo10]). Der Aufruf dieser liefert ohne Verzögerung das Ergebnis als Grafik im PNG-Format zurück und kann somit nahtlos in HTML durch die Verwendung eines Bild-Tags verwendet werden. Die API bietet somit nicht nur eine leichtgewichtige und leicht integrierbare Schnittstelle zur Generierung von Statistiken, sondern auch eine Entlastung des Webservers, da die Berechnungen vollständig von Google übernommen werden. Die Nutzung dieser Technik wird nun anhand der Integration in das Rails-Projekt demonstriert. Als Beispiel dient ein Kuchendiagramm zur Visualisierung der prozentualen Aufteilung von Buchungen pro Buchungskategorie. Listing 7.1 zeigt den verwendeten Aufruf und Abbildung 7.4 die hieraus resultierende, generierte Grafik. 1 Ausfluege Essen& chs=600x300&chd=t:25,60,15&chco=00a8ff Listing 7.1: Aufruf der Google Chart API zur Generierung eines Kuchendiagramms. 112

129 7.4. Einsatz und Verwendung von Buchungsreporten Abbildung 7.4.: Ein mit den Google Chart Tools generiertes Kuchendiagramm. Die Parameter des Aufrufs in Listing 7.1 definieren (von links nach rechts) den Diagrammtyp, die Beschriftungen der einzelnen Kreisausschnitte, die Auflösung der Ergebnisgrafik, die Werte und die gewünschte farbliche Codierung in hexadezimaler Form. Die Google Chart API kann dank der Hilfsmethoden von Rails sehr einfach zur Darstellung integriert werden. Hierzu genügen die Generierung der URL innerhalb einer Controller-Action und die Übergabe dieser als Klassenvariable an die Ansicht. Die Generierung der zugehörigen URL kann in Rails über eine Hashmap beschrieben und mit der von Rails integrierten Methode to_param in die gewünschte, URL-encodierte, Darstellungsform übertragen werden. Eine exemplarische Implementierung ist in Listing 7.2 zu sehen. 1 def tags 2 # [...] 3 chart_params = { :cht => "p3", :chl => tag_booking_count.keys.join(" "), :chs => "800x300", :chd => "t:" + tag_booking_count.values.join(","), :chco => "00a8ff" } = "http://chart.apis.google.com/chart?" + chart_params. to_param 5 end Listing 7.2: Integration der Google Chart API in einen Controller der Webapplikation. 113

130 7. Leichtgewichtige Webentwicklung und Webservice-Integration Die Variable tag_booking_count referenziert eine Hashmap, die die Bezeichnungen der Kategorien als Schlüssel und die zugehörigen Buchungsanzahlen als Werte beinhaltet. Die Methode join der Klasse Array fügt alle enthaltenen Elemente als Zeichenkette zusammen, während das als Argument übergebene Zeichen als Separatorsymbol bei der Konkatenation verwendet wird Integration der PDF-Bibliothek Prawn Die Webapplikation soll den Benutzern das Versenden von Rechnungen im Portable Document Format (kurz PDF) als -Anhang an Reiseteilnehmer ermöglichen. Die Nutzung von HTML als Möglichkeit zur Erzeugung von Rechnungen wird aufgrund der variierenden Unterstützung vieler -Clients als ungenügende Lösung angesehen. Für den Versand der Rechnungen können die Benutzer pro Reise eine beliebige Kombination von Teilnehmern aus einer Liste für den Versand auswählen. An dieser Stelle soll zudem eine Vorschau der Rechnungen einsehbar sein. Um die Erstellung der Rechnungen zu erleichtern, bietet sich die Nutzung der Bibliothek Prawn an, da diese die Erzeugung von PDF-Dateien mittels einer auf Ruby optimierten Klassenbibliothek ermöglicht. Für die im Folgenden beschriebenen Techniken dienen die offiziellen Beispiele des Prawn-Projekts (siehe [San]) sowie die bereits erwähnte Literatur zum Thema Ruby on Rails (siehe [RTH09; Han10b]) als Grundlage. Es bleibt nun zu klären, in welcher Art und Weise die Generierung der Rechnung in die Softwarearchitektur der Webapplikation integriert werden kann. Hierbei ist wichtig, dass die Rechnungen sowohl als Vorschau über das Webinterface als auch für den Versand als -Anhang verfügbar sind. Um dieses Problem zu lösen, bietet sich die Erstellung einer neuen Klasse an, die von der Klasse Prawn::Document erbt. In dieser muss lediglich ein Konstruktor und eine Methode to_pdf implementiert werden. Über den Konstruktor werden die zur Erstellung der Rechnung benötigten Objekte übergeben, sprich der betroffene Teilnehmer und die Reise, während die Methode to_pdf für die Generierung und Rückgabe des PDF-Dokuments zuständig ist (siehe Listing B.2 im Anhang). Innerhalb der Methode to_pdf können die von der Bibliothek Prawn bereitgestellten Aufrufe zur Erzeugung der PDF-Rechnung genutzt und letztendlich das PDF-Dokument in Form eines Byte-Stream als Ergebnis zurückgegeben werden. Um die Klasse im gesamten Projekt verfügbar zu machen, 114

131 7.5. Techniken zur Benutzerauthentifikation kann diese im Projektverzeichnis neben den Entitätsklassen abgelegt werden. Für die Implementierung einer Vorschaufunktion muss zunächst ein MIME-Typ für das Portable Document Format global definiert werden. Dies kann durch das Hinzufügen des in Listing 7.3 gezeigten Makros in der Datei mime_types.rb erreicht werden. 1 Mime::Type.register "application/pdf", :pdf Listing 7.3: Makro zur Registrierung des Portable Document Format als MIME-Typ. Nun kann innerhalb des für den Rechnungsversand zuständigen Controller eine Action implementiert werden, die mithilfe der soeben beschriebenen Klasse eine Rechnung erzeugt und diese unter Verwendung der Methode render zur Vorschau an den Client weiterleitet. Durch den definierten MIME-Typ wird die Rechnung bestenfalls direkt innerhalb des Webbrowsers zur Vorschau geöffnet. 1 def billing 2 # [...] 3 billing = Billing.new(:participant :trip 4 respond_to do format 5 format.pdf do 6 render :text => billing.to_pdf, :type => "application/pdf" 7 end 8 end 9 end Listing 7.4: Controller-Action zur Generierung einer Rechnungsvorschau. Die Nutzung der beschriebenen Klasse kann parallel für den Versand der Rechnung als -Anhang verwendet werden, was aufgrund dessen an dieser Stelle nicht näher erläutert wird Techniken zur Benutzerauthentifikation Die Integration eines Authentifizierungsmechanismus für Benutzerkonten kann je nach Anwendungsgebiet zu unterschiedlichen Ergebnissen führen und die folgende Lösung stellt somit nur eine unter vielen dar. Bei der Umsetzung dessen wird besonderen Wert auf die Einhaltung der Konventionen von Ruby on Rails gelegt und eine möglichst angriffssichere Realisierung angestrebt. 115

132 7. Leichtgewichtige Webentwicklung und Webservice-Integration Für die Authentifikation steht die Klasse User im Mittelpunkt, die den Zugriff auf die Benutzerentitäten in der zugrunde liegenden Datenbank über das Framework Active Record ermöglicht. Es muss zunächst ein geeigneter Ort für die Funktionalität im Softwaredesign gefunden werden. Hierzu bieten sich mehrere Möglichkeiten an: Die Datenbankabfrage für die Authentifikation könnte zu jeder Zeit bei Bedarf erneut implementiert werden. Diese Lösung widerspräche dem DRY-Prinzip vollständig, da identische Funktionalitäten hierbei mehrfach und demnach redundant vorhanden wären. Eine zweite Möglichkeit bestände darin, den Application-Controller zu verwenden, da dessen Methoden durch Vererbung in sämtlichen Controllerklassen verwendbar sind. Dieser Ansatz entspräche zumindest dem DRY-Prinzip. Dennoch könnte diese Klasse für alle Probleme dieser Art entfremdet werden. Aus Sicht der Softwaretechnik würde dies zu einer schwachen Kohäsion, sprich einer Ansammlung von Methoden mit differierenden Aufgabenbereichen, führen. Active Record bietet hierzu eine deutlich bessere Lösung: Sämtliche Entitätsklassen können neben Validierungen, auf die später eingegangen wird, ebenso um Methoden und sogenannte virtuelle Attribute ergänzt werden. So ist es möglich, den gesamten Authentifikationsmechanismus der Klasse User zuzuordnen (vgl. Abbildung 7.5). ActiveRecord::Base - hash_password User e_mail : string hashed_password : string salt : string is_administrator : bool password : string {virtual} password_confirmation : string {virtual} + authenticate(string,string) : User + password_changed? : bool + generate_random_password Abbildung 7.5.: Die Klasse User kapselt sämtliche Funktionalität für die Authentifizierung. Hierbei übernimmt die Klassenmethode authenticate die wichtigste Aufgabe. Diese gleicht die Argumente, sprich die -Adresse und das Passwort, mit der Datenbank ab. Bei einer gültigen Anfrage wird die entsprechende Instanz des Benutzerobjekts zurückgegeben und im Falle einer ungültigen Anfrage erfolgt die Rückgabe des Nil- 116

133 7.5. Techniken zur Benutzerauthentifikation Objekts. Die dargestellte Klasse beinhaltet zudem die Funktionalität für die Validierung von Abonnements, die in Kapitel 8 zur Geltung kommt. Es ist von großer Bedeutung, dass Benutzerpasswörter unter keinen Umständen im Klartext in der Datenbank abgelegt werden. Die Gründe hierfür sprechen für sich: Viele Benutzer nutzen ein einziges Passwort für sämtliche Online- und Offline-Dienste. Die Speicherung von Passwörtern im Klartext wird spätestens bei einer Offenlegung des Datenbestands durch einen Angriff oder einen Softwarefehler bedenklich. Um diesem Problem zunächst zu entgehen, sollten nur die Passwortprüfsummen gespeichert werden. Hierfür eignen sich besonders kollisionsfreie Hash-Algorithmen, wie zum Beispiel SHA-2. Bei der Zuweisung eines Passworts ist es somit nötig, die entsprechende Prüfsumme zu generieren und zu hinterlegen. Der Ablauf bei der Authentifikation ist somit der Folgende: Bei der Anmeldung eines Benutzers wird die Prüfsumme des eingegebenen Passworts generiert und mit der in der Datenbank vorhandenen Prüfsumme verglichen. Dieses Konzept bringt zunächst einige Besonderheiten mit sich, die das Softwaredesign stark beeinflussen können. Active Record stellt sogenannte Validations zur Verfügung, die die komfortable Validierung von Attributen ermöglichen. So können diese zur Verifizierung der Länge von Passwörtern oder zum automatischen Abgleich von Passwort- und Passwortbestätigung verwendet werden. Da nur die Prüfsummen der Passwörter in der Datenbank abgelegt werden, können Validierungen auf diese nicht mehr angewandt werden, da beispielsweise die Länge des Hashs in keiner Relation zur Länge des zugrunde liegenden Passworts steht. Es wäre in diesem Fall äußerst unschön, die nötige Validierung nach außen verlegen zu müssen. Für eine mögliche Lösung bietet sich die Nutzung von sogenannten virtuellen Attributen an, mit denen Entitätsklassen Attribute ohne Bezug zur Datenbank zugewiesen werden können. Das angesprochene Problem lässt sich mit den beschriebenen Mitteln wie folgt lösen: Es werden zwei virtuelle Attribute in der Klasse User angelegt, die Passwort und Passwortbestätigung repräsentieren. Mithilfe eines Filters kann vor der Speicherung oder Änderung des Objekts eine Funktion ausgeführt werden. Filter ähneln dem Konzept der Trigger im Umfeld der relationalen Datenbanken. Diese Funktion (vgl. Methode password_changed? in Abbildung 7.5) prüft, ob das virtuelle Passwort oder die virtuelle Passwortbestätigung gesetzt wurde. Ist dies der Fall, wird die entsprechende Prüfsumme (vgl. Funktion hash_password in Abbildung 7.5) nach dem Vergleich beider 117

134 7. Leichtgewichtige Webentwicklung und Webservice-Integration Passwörter, welcher wiederum durch den Einsatz von Validations erreicht werden kann, in die Datenbank übernommen. Die beiden virtuellen Attribute werden hieraufhin zurückgesetzt. Diese Methodik erlaubt bei der Programmierung die transparente Arbeit mit dem Active-Record-Objekt, ohne hierbei die Generierung der Prüfsumme im Hintergrund berücksichtigen zu müssen. Für den Fall, dass Benutzer ihr Passwort vergessen, muss es möglich sein, dieses zurückzusetzen. Hierzu kommt die Methode generate_random_password zur Anwendung. Diese generiert auf Anfrage zunächst eine zufällige Zeichenkette. Die Prüfsumme wird aus dieser, zusammen mit einer neu erstellten Salt-Zeichenkette (diese wird in Abschnitt genauer erläutert), generiert und im Datenbankobjekt gespeichert. Mithilfe des Framework Action Mailer kann nun eine mit dem neuen Passwort an den Benutzer gesendet werden. Da das Passwort im Klartext übertragen wird, ist es wichtig, dass der Benutzer an eine zeitnahe Änderung dessen erinnert wird Bereitstellung des Authentifikationsmechanismus für die AJAX-Anmeldemaske Der soeben beschriebene Mechanismus kann zur Bereitstellung der Authentifikationsmechanik für die im Folgenden beschriebene AJAX-Anmeldemaske verwendet werden. Abbildung 7.6 zeigt zunächst das zugrunde liegende Konzept. Die Benutzerdaten werden nach Betätigung des Submit-Buttons an den zuständigen Controller, in diesem Fall der Controller mit der Bezeichnung Online::LoginController, als JSON-Struktur über HTTPS übertragen. Hierzu muss lediglich eine Methode respektive Action bereitgestellt werden, die die Benutzerdaten mit der Datenbank abgleicht und im Erfolgsfall das Benutzerkonto für die aktuelle Session validiert. Zudem muss der Client über das Ergebnis des Vorgangs informiert werden. Eine exemplarische Implementierung ist in Listing 7.5 zu sehen. 118

135 7.5. Techniken zur Benutzerauthentifikation Client HTTPS Server Darstellung von Anmeldemaske und Statusinformationen HTTP-GET-Anfrage für Anmeldemaske Übertragung der Anmeldemaske Übertragung der Anmeldedaten Bestätigung der Anmeldung HTTP-GET-Anfrage für internen Bereich Prüfung der Anmeldung Abbildung 7.6.: Der zugrunde liegende Ablauf bei der AJAX-Authentifikation. 119

136 7. Leichtgewichtige Webentwicklung und Webservice-Integration 1 def ajax_login 2 result = false 3 if (User.authenticate params[:e_mail],params[:password]) 4 session[:user] = u.id 5 result = true 6 end 7 render :layout => false, :json => {:result => result} 8 end Listing 7.5: Die Authentifikationsmethode für die AJAX-Anmeldemaske. Die Methode ajax_login validiert die Benutzerdaten und speichert im Erfolgsfall den Primärschlüssel des Benutzers in der Session. Zudem wird der Client über das Ergebnis der Authentifikation in Form eines primitiven JSON-Objekts benachrichtigt Absicherung der Benutzerauthentifikation Für eine möglichst sichere Gestaltung der Authentifizierung müssen einige Situationen bei der Implementierung bedacht werden. Es darf zu keinem Zeitpunkt die Möglichkeit bestehen, personenbezogene Daten durch sogenannte Man-In-The-Middle-Angriffe im Klartext abzufangen. Die beschriebene Authentifikationsmethode überträgt den Benutzernamen und das Passwort asynchron an den Server. Wird HTTP zur Übertragung verwendet, könnten diese Informationen durch eine Analyse der Datenpakete offengelegt werden. Diese Problematik kann durch Generierung einer Passwortprüfsumme und alleinige Übertragung dieser gelöst werden. So wäre das Passwort zunächst nicht mehr im Klartext abfangbar. Dennoch könnte ein Angreifer die Prüfsumme in seinen Besitz bringen und direkt, ohne Nutzung der öffentlichen Anmeldemaske, an den Server übermitteln. Eine Lösungsmöglichkeit stellt die Mitübertragung einer zuvor ausgehandelten, temporären Zeichenkette (ein sogenannter One-Time-Seed) und die Einbeziehung dieser in die Prüfsumme dar. So ist auch die Prüfsumme des Passworts versteckt und die übertragene Zeichenkette nur für einen Versuch gültig. Der One-Time-Seed muss vom Server, beispielsweise in der Datenbank, vermerkt und nach einer Verwendung als ungültig markiert oder gelöscht werden. Die Nutzung des Übertragungsprotokolls HTTPS kann diesen Vorgang jedoch deutlich vereinfachen und verursacht keinen zusätzlichen Implementierungsaufwand. Dennoch 120

137 7.5. Techniken zur Benutzerauthentifikation müssen auch hierbei einige Details beachtet werden. Aufseiten des Benutzers kann die Adresszeile im Browser beliebig angepasst und somit auch das Übertragungsprotokoll beliebig ausgetauscht werden (wenn der Webserver beispielsweise HTTP und HTTPS zeitgleich unterstützt). Zudem muss in den betroffenen Controllern dafür Sorge getragen werden, dass stets das gewünschte Protokoll verwendet wird. Hierzu wird zunächst die Superklasse Online::OnlineController für alle Controller des internen Bereichs eingeführt. Mithilfe eines Filters können hierbei die Protokolle aller Anfragen geprüft und bei einer Abweichung eine Weiterleitung initiiert werden. Die Weiterleitung und Prüfung des Protokolls kann wie in Listing 7.6 gezeigt realisiert werden. 1 def force_ssl 2 redirect_to :protocol => "https://" if not request.ssl? 3 end Listing 7.6: Filter zu Weiterleitung bei abweichenden Übertragungsprotokollen. Somit sind Man-In-The-Middle-Angriffe ausgeschlossen. Dennoch müssen weitere Situationen bei der Absicherung bedacht werden. Rails protokolliert sämtliche HTTP- Aufrufe inklusive der Parameterwerte. Dies hat zur Folge, dass übertragene Passwörter in den Logdateien im Klartext zu finden sind. Um dieses Problem zu lösen können alle kritischen Parameter von der Protokollierung ausgeschlossen werden, sodass deren Werte in den Logdateien maskiert werden. Hierzu kann das Makro filter_parameter_- logging im Application-Controller eingesetzt werden. Bei der Entwicklung darf eine Offenlegung des Datenbestands durch Softwarefehler, Sicherheitslücken oder Fahrlässigkeit nicht ausgeschlossen werden. Dies ist besonders bei der Speicherung von personenbezogenen Daten bedenklich. Im Falle der beschriebenen Webapplikation wird lediglich die -Adresse und ein Passwort zur Identifikation des Benutzers verwendet. Von personenbezogenen Daten kann in diesem Fall nicht direkt die Rede sein. Dennoch können Unmengen von Passwörtern samt der zugehörigen -Adressen den Zugang zu bekannten Webangeboten (Amazon, Google usw.) offenlegen. Da Passwörter nur in Form von Prüfsummen unter Zuhilfenahme des SHA- 2-Algorithmus abgelegt werden, ist zumindest das direkte Auslesen der Passwörter zunächst ausgeschlossen. Einer aktuellen Langzeitstudie zufolge ist die durchschnittliche Stärke von Passwörtern sehr gering und das Internet wird von aus Kleinbuchstaben bestehenden Passwörtern dominiert (siehe [FH07]). 121

138 7. Leichtgewichtige Webentwicklung und Webservice-Integration Passwörter in dieser Form sind besonders für sogenannte Wörterbuchattacken anfällig. Hierbei wird ein zum verwendeten Hash-Algorithmus passendes Wörterbuch verwendet, das eine große Menge von Prüfsummen und den entsprechenden Klartexten enthält. Um den Abgleichungsvorgang zeitlich einzuschränken, bietet sich Folgendes an: Bei der Zuweisung eines Passworts wird zusätzlich eine pseudozufällige Zeichenkette (sogenanntes Salt) generiert und dem entsprechenden Objekt vom Typ User zugeordnet. Vor der Erstellung der Prüfsumme, also bei der Zuweisung oder des Abgleichs des Passworts, wird diese an die Passwortzeichenkette angehängt. Die direkte Anwendung der Passwortdatenbanken ist somit nicht mehr möglich. Dennoch können die Angriffsalgorithmen so angepasst werden, dass diese die Zeichenkette berücksichtigen und die Prüfsummen dynamisch generieren. Auch wenn der Vorgang hierbei verlangsamt wird, kann das Knacken von sehr schwachen Passwörtern in diesem Fall innerhalb eines endlichen Zeitraums nicht ausgeschlossen werden. Dennoch verhindert dieses Vorgehen das zeitnahe Entschlüsseln von sicheren respektive starken Passwörtern. Hierbei kommen häufig sogenannte Rainbow-Tables zum Einsatz (vgl. zu diesem Abschnitt [Swe10], Seite 81 ff.). Eine Rainbow-Table ist eine besonders platzsparende Datenstruktur zur Speicherung von pseudozufälligen Zeichenketten und den zugehörigen Prüfsummen. Das System basiert auf der Bildung von sogenannten Hash-Chains. Es reicht an dieser Stelle zu sagen, dass nur der Anfangs- und Endwert der Kette gespeichert und die platzsparende Struktur durch die Neuberechnung dieser erreicht wird. Durch die Einführung von Salt pro Instanz einer Benutzerentität müssen die Ketten für jeden dieser Werte getrennt vorberechnet werden. Eine ausreichende Länge des Salt ist somit ausschlaggebend für die Sicherheit. Bei der Arbeit mit Ruby on Rails werden zur sicheren Generierung von zufälligen Zeichenketten Hilfsfunktionen bereitgestellt. Listing 7.7 und 7.8 zeigen die soeben erarbeitete Technik anhand der Methoden zur Authentifikation und zur Generierung der Prüfsumme. 1 def hash_password 2 self.salt = ActiveSupport::SecureRandom.base64(8) 3 self.hashed_password = Digest::SHA2.hexdigest(self.salt 4 end Listing 7.7: Generierung der Prüfsumme unter Verwendung von Salt. 1 def self.authenticate e_mail, password 2 if user = find_by_e_mail(e_mail) 122

139 7.5. Techniken zur Benutzerauthentifikation 3 return user if (user.hashed_password == Digest::SHA2.hexdigest(user. salt + password)) 4 end 5 end Listing 7.8: Die Methode zur Authentifikation von Benutzerkonten. Bei der Implementierung eines Authentifikationsmechanismus ist meist die Integration eines Rangsystems von Nöten. Der im Folgenden beschriebene Mechanismus kennt lediglich Benutzer oder Administratoren. Administratoren werden durch das Setzen des Datenbankattributs is_administrator der Klasse User auf true ernannt (siehe Abbildung 7.5). Zur Absicherung dieses Mechanismus muss darauf geachtet werden, dass der Wert nicht durch Benutzerhand verändert werden kann. Häufig wird bei der Übernahme von Werten aus Webformularen eine Methode benutzt, die mithilfe von Hashmaps das komfortable Aktualisieren mehrere Datenbankattribute erlaubt. Diese ermöglicht jedoch durch Nutzung von kompromittierten Webformularen die Anpassung des Attributs is_adminstrator. Die genannte Problematik kann ebenso auf die Prüfsumme des Passworts, die von Benutzern niemals manuell angepasst werden darf, übertragen werden. Auch die -Adresse ist nicht für die Anpassungen durch Benutzer freigegeben. Hierzu bietet es sich an, die Attribute in der Entitätsklasse User als geschützt zu markieren oder lediglich für Lesezugriffe freizugeben. Ruby on Rails bietet hierzu die Makros attr_protected und attr_readonly an. Während geschützte Attribute von den Massenaktualisierungsmethoden ausgeschlossen werden, können Read-Only-Attribute nur beim Anlegen des Datenbankobjekts gesetzt werden. Die zuletzt genannte Möglichkeit eignet sich für die -Adresse, da diese nach der Erstellung von den Benutzern nicht mehr angepasst werden darf Entwicklung einer dynamischen Anmeldemaske mit jquery Für die Entwicklung einer dynamischen Anmeldemaske sind mehrere Technologien von Bedeutung. Zunächst wird HTML respektive XHTML (in Kombination mit CSS) zur Darstellung benötigt. Zudem müssen die Benutzerdaten asynchron an den Server übertragen und der Benutzer während der Durchführung des Vorgangs visuell über den aktuellen Status informiert werden. Hierzu ist der Einsatz einer Skriptsprache aufseiten des Clients unumgänglich und der Einsatz von JavaScript bietet sich dank 123

140 7. Leichtgewichtige Webentwicklung und Webservice-Integration der weiträumigen Unterstützung an. Für die Übertragung der Benutzerdaten können in JavaScript sogenannte XMLHttpRequests verwendet werden, während die dargestellte Webseite über Manipulation des DOM je nach Status und Ergebnis der Übertragung angepasst werden kann. Dennoch variiert die Unterstützung des W3C-DOM-Standards zwischen vielen Browsern stark, sodass bestimmte Funktionen abhängig vom Browser zu unterschiedlichen Ergebnissen führen können. Das W3C bietet hierzu ein Script zum Test 2 des aufrufenden Browsers an. Tabelle 7.1 stellt den Grad der Unterstützung einiger verbreiteter Webbrowser gegenüber. Document Object Model Browser Level 1 Level 2 Level 3 Gesamt Safari (Mac OS 10.6) 2 von 2 14 von 14 0 von 5 76, 1% Chrome (Windows 7) 2 von 2 14 von 14 0 von 5 76, 1% Firefox (Mac OS 10.6) 2 von 2 12 von 14 0 von 5 66, 6% IE (Windows XP SP2) 1 von 2 0 von 14 0 von 5 4, 76% IE (Windows XP SP3) 1 von 2 0 von 14 0 von 5 4, 76% IE (Windows 7) 1 von 2 0 von 14 0 von 5 4, 76% Tabelle 7.1.: Unterstützung des W3C-DOM-Standards im Vergleich. Um die Unterschiede zwischen den verschiedenen Browsern zu kompensieren, bietet sich der Einsatz von speziellen JavaScript-Frameworks als Zwischenschicht an. Ein aktueller Vertreter dieser ist das Framework jquery, das sowohl Möglichkeiten zur Manipulation des DOM als auch zur Ausführung von asynchronen Verbindungsaufrufen bietet. Das Framework ist so konstruiert, dass es bei einer Vielzahl von Browsern zu identischen Ergebnissen führt. jquery bietet, wie der Name des Framework bereits andeutet, eine elegante Beschreibungssprache zur Auswahl von Elementen innerhalb des DOM (vgl. zu diesem Abschnitt [SC10]). Bei der Implementierung der Anmeldemaske ist zunächst die Darstellung der Zustandsinformationen von Bedeutung. Hierzu wird an der Stelle, an der der Statustext erscheinen soll, zunächst ein Blockelement mit einer eindeutigen Identifikationsnummer erzeugt. Dieses kann daraufhin unter Zuhilfenahme einer jquery-anfrage manipuliert werden. In Listings 7.9 ff. wird das Anhängen eines HTML-Inline-Elements an ein HTML-Blockelement demonstriert

141 7.5. Techniken zur Benutzerauthentifikation 1 <div id="message"></div> Listing 7.9: Ein leeres HTML-Blockelement. 1 $("#Message").append( <span>anmelden...</span> ); Listing 7.10: jquery-methode zum Anhängen eines Elements an das Blockelement. 1 <div id="message"> 2 <span>anmelden...</span> 3 </div> Listing 7.11: HTML-Blockelement mit zusätzlichem Inline-Element. Als Nächstes müssen die Benutzerdaten an die in Abschnitt beschriebene Methode respektive Action des Controllers übermittelt werden. Die Anmeldemaske besteht aus je einem Eingabefeld für Benutzername und Passwort sowie einem Button zur Initiierung des Übertragungsvorgangs (siehe Abbildung 7.7). Diese drei Elemente werden einem Formularelement zugeordnet. Die eigentliche Übertragung der Benutzerdaten soll beim Absenden des Formulars ausgeführt werden. Hierzu wird nach Beendigung des Seitenladevorgangs dem Absendeereignis des Webformulars eine JavaScript-Funktion zugeordnet. Damit das Standardverhalten des Events unterbunden wird, sprich das Absenden des Formulars, kommt zunächst die Methode preventdefault zur Anwendung. Hierauf folgt die Funktionalität zur Übertragung der Benutzerdaten. Hierzu bietet jquery die Methode $.ajax an, die die asynchrone Übertragung und zeitgleiche Serialisierung von Datenstrukturen erlaubt. Dieser werden als Argumente der Typ der zu übermittelten Datenstruktur, die Benutzerdaten, als auch eine call back function, die nach erfolgter Übertragung ausgeführt wird, übergeben. Die genannte Methode kann im Anschluss den gelieferten booleschen Wert der Controller- Methode (siehe Listing 7.5) auswerten und je nach Ergebnis eine Fehlernachricht anzeigen oder die Weiterleitung in den internen Bereich initiieren. Eine vereinfachte Form des Endergebnisses ist in Listing 7.12 zu sehen und ist dem HTML-Kopfbereich der Anmeldemaske zuzuordnen. 1 var onsuccess = function (data) { 2 // Auswertung des Anmeldevorgangs 3 if (data.result) { 4 [...] // Anmeldung war erfolgreich 5 } else { 125

142 7. Leichtgewichtige Webentwicklung und Webservice-Integration Abbildung 7.7.: Screenshot der Anmeldemaske von wetravel online. 126

143 7.6. Techniken zur Bereitstellung multilingualer Webapplikationen 6 [...] // Anmeldung fehlgeschlagen 7 } 8 } 9 $(document).ready(function() { 10 // Zuordnung des Anmelde-Events 11 $("#LoginForm").submit(function(e) { 12 e.preventdefault(); 13 // Uebertragung der Anmeldedaten 14 $.ajax({ datatype:"json",url:"<server_url>/ajax_login",data:{e_mail: $ ("#e_mail").val(), password: $("#password").val() }, success: function(data) { onsuccess(data) } } ); 15 return false; 16 }); 17 } Listing 7.12: Reduzierte Version des AJAX-Authentifikationsmechanismus Techniken zur Bereitstellung multilingualer Webapplikationen Die Bereitstellung von multilingualen Applikationen erlaubt die Erfassung eines größeren Benutzerumfelds und kann somit maßgeblich zum Erfolg dieser beitragen. In Kapitel 6 wurde bereits das Vorgehen bei der Implementierung von mehrsprachigen iphone-applikationen beschrieben. Ruby on Rails unterstützt in den aktuellen Versionen (genauer gesagt seit der Veröffentlichung von Version 2.2) eine ähnliche Methodik. Hierzu kommt das Framework I18n (Kurzform von Internationalization) zur Anwendung (vgl. zu diesem Abschnitt [Han10a]). Das Framework ist tief in den Kern von Rails integriert und erlaubt, neben der Übersetzung anhand von Platzhaltertexten, die lokalisierte Darstellung von Zeitangaben oder Geldbeträgen. Für die Nutzung der Lokalisierungs- und Übersetzungsfunktionalität ist zunächst das Anlegen von Sprachdateien notwendig. Diese werden in YAML (YAML Ain t Markup Language) formuliert, die ähnliche Strukturierungsmöglichkeiten wie XML oder JSON bietet. Zur Lokalisierung der durch Ruby und Ruby on Rails bereitgestellten Klassen und Hilfsklassen, wie zum Beispiel zur länderspezifischen Anpassung der Datums- oder der Dezimaldarstellung, können der Projekthomepage vorgefertigte 127

144 7. Leichtgewichtige Webentwicklung und Webservice-Integration Übersetzungsdateien entnommen werden 3. Für die Übersetzung oder Lokalisierung stehen die Befehle translate und localize (alternativ t und l) zur Verfügung. Zur Übersetzung von einzelnen Worten, Sätzen oder Abschnitten kann nun wie folgt vorgegangen werden: Innerhalb der jeweiligen YAML-Dateien werden Stichwörter und zugehörige Übersetzungstexte hinterlegt. Bei der Programmierung der Webapplikation werden statt sprachabhängiger Texte die Übersetzungsfunktion und das entsprechende Stichwort verwendet. Die Übersetzungsmethode schlägt beim Aufruf der Webseite abhängig von der aktuell aktiven Sprache die definierten Begriffe nach und gibt die Ergebnisse der Übersetzung zurück. Listings 7.13 ff. zeigen Ausschnitte zweier YAML- Dateien und die Anwendung der I18n-Übersetzungsmethode vor und nach dem Wechsel der Sprache. 1 de: 2 welcome: "Willkommen!" Listing 7.13: YAML-Datei für die deutsche Sprache. 1 en: 2 welcome: "Welcome!" Listing 7.14: YAML-Datei für die englische Sprache. 1 I18n.locale = "de" 2 puts t "welcome" 3 # Ausgabe: Willkommen! 4 I18n.locale = "en" 5 puts t "welcome" 6 # Ausgabe: Welcome! Listing 7.15: Übersetzung mithilfe von I18n. Das Bereitstellen von mehrsprachigen Webseiten ist dank des Framework I18n einfach umsetzbar. Dennoch sollten die Mechanismen für die Auswahl der Sprache seitens der Besucher respektive Kunden möglichst einfach, verständlich und bestenfalls automatisiert arbeiten. Benutzer erwarten bei der Weitergabe von URLs, dass die Gegenseite exakt den gleichen Inhalt zu Gesicht bekommt (vgl. [Han10a]). Bei der Verwendung eines Internationalisierungs-Framework muss die aktuelle Sprache zur Darstellung im Backend bekannt sein. Dies könnte durch die Speicherung der aktiven Sprache

145 7.6. Techniken zur Bereitstellung multilingualer Webapplikationen in der Benutzersession erreicht werden. Beachtet man jedoch die Anforderungen eines RESTful Webs, ist es wichtig, dass zwischen Aufrufen keine Daten aufseiten des Servers gespeichert werden und stattdessen alle zur Anzeige notwendigen Daten in die URL codiert werden (vgl. [Rod08]). Eine ansprechendere Lösung stellt somit das Weiterreichen der Sprache innerhalb der URL dar. Hierbei ist es nötig, dass alle in der Webapplikation verwendeten Hyperlinks den entsprechenden Parameter mit der derzeit aktiven Sprache enthalten. Ruby on Rails stellt für die Erstellung von Hyperlinks Hilfsfunktionen bereit, die bei kontinuierlicher Verwendung zu einer einheitlichen Lösung des Problems beitragen können. Für sämtliche Hilfsfunktionen, die die Generierung von URLs nutzen, können Standardparameter definiert werden. So kann die aktuelle Sprache des Framework I18n komfortabel mit einbezogen und in sämtlichen Hyperlinks verfügbar gemacht werden. Hinsichtlich des DRY-Prinzips müssen, wie sich gleich zeigt, bei einer möglichen Änderung nur an einer zentralen Stelle Modifikationen durchgeführt werden. Um die aktuelle Sprache in sämtliche URLs zu integrieren und die Auswahl über einen URL-Parameter zu ermöglichen, müssen dem Application-Controller zwei Methoden hinzugefügt werden. Die erste Funktion (set_locale) dient in Verbindung mit einem Before-Filter zur Übergabe der Sprache an I18n. Die zweite Methode, default_url_options(options={}), stellt die übergebene Sprache als Standardoption für die URL-Hilfsfunktionen bereit, sodass diese automatisch in allen Hyperlinks mit einbezogen wird. Ist dies geschehen, kann die deutschsprachige Anmeldemaske unter der Adresse erreicht werden. Die Form der genannten URL ist jedoch unbefriedigend und kann mit einer Anpassung der Standardroute in der Datei routes.rb des Projekts verbessert werden. Das Definieren einer Route in der Form :locale/:controller/:action/:id macht die Anmeldemaske unter der Adresse verfügbar. Mit der beschriebenen Technik können Benutzer die Sprache zunächst nur über die Adresse der Webanwendung beeinflussen. Das Implementieren einer Funktionalität zum Wechsel der Sprache, beispielsweise in Form eines Hyperlinks oder einer Auswahlliste, ist unproblematisch, da eine Aktualisierung der aktuell angezeigten Webseite mit einem angepassten URL-Parameter genügt. Bedenkt man jedoch, dass die Webapplikation von Benutzern aus verschiedenen Regionen und Ländern benutzt wird, ist es unbefriedigend diese für die Auswahl der entsprechenden Sprache verantwortlich zu machen. Um das genannte Problem zu lösen, könnten die vom Webbrowser gelieferten Informationen 129

146 7. Leichtgewichtige Webentwicklung und Webservice-Integration verwendet werden. Das Feld Accept-Language, das über den HTTP-Header übergeben wird, kann Auskunft über die präferierte Sprache geben, ist jedoch vom Browser und von den Einstellungen des Benutzers abhängig (vgl. [Han10a]). Eine deutlich bessere Alternative stellt die Nutzung einer geografischen Datenbank dar. Diese Datenbanken beinhalten Zuordnungen von IP-Adressbereichen zu Ländern und Städten. Die Firma MaxMind stellt hierzu eine kostenlose Datenbank auf Stadt- und Länderebene zur Verfügung 4, die sich mithilfe des Gems (RubyGems ist das Paketverwaltungssystem von Ruby) geoip in eine Ruby-on-Rails-Applikation integrieren lässt. Der Umfang der Datenbank unterscheidet sich marginal hinsichtlich der Genauigkeit zur kostenpflichtigen Variante 5. Bei der Integration der geografischen Datenbank in die Applikation kann zur Ermittlung der Sprache nun wie folgt vorgegangen werden: Zunächst wird geprüft, ob der Benutzer bereits explizit eine Sprache gewählt hat. Ist dies nicht der Fall, wird die IP-Adresse der HTTP-Anfrage zur Auflösung über die geografische Datenbank verwendet und der Ländercode als aktive Sprache für das Framework I18n genutzt. Im umgekehrten Fall werden keine weiteren Schritte eingeleitet und die über die URL übergebene Sprache verwendet. Diese Funktionalität kann in die bereits erwähnte Filterfunktion set_locale, wie in Listing 7.16 gezeigt, integriert werden. 1 def set_locale 2 if params[:locale] 3 I18n.locale = params[:locale] 4 else 5 require geoip 6 geo = GeoIP.new("#{RAILS_ROOT}/app/geoip/GeoLiteCity.dat") 7 g = geo.city(request.remote_ip) 8 I18n.locale = g[2].downcase if g 9 end 10 end Listing 7.16: Nutzung der geografischen Datenbank zur Bestimmung der Sprache. Die Standardsprache sollte innerhalb des Rails-Projekts auf Englisch gestellt sein, sodass im Falle eines Versagens der geografischen Datenbank eine möglichst weitverbreitete Sprache verwendet wird. Die gezeigte Methode ist leicht reduziert und berücksichtigt zum Beispiel keine deutschsprachigen Länder wie Österreich oder die Schweiz. Dies kann durch Einführung einer Hashmap zur Zuordnung der Ländercodes erreicht werden Auf Länderebene liegt der Genauigkeitsunterschied bei ca. 0.3 % und auf Stadtebene bei ca. 4 %. 130

147 7.7. Verbindung von iphone- und Webapplikation Die Verwendung einer geografischen Datenbank zur automatischen Erkennung der Sprache von Endbenutzern ist nur eine Einsatzmöglichkeit. Im Rahmen dieser Arbeit wird die Nutzung von geografischen Daten innerhalb des Abschnitts 8.4 bezüglich der Erfassung von Interessentenstatistiken erneut aufgegriffen Verbindung von iphone- und Webapplikation Innerhalb dieses Abschnitts steht die Erarbeitung eines Webservicekonzepts im Mittelpunkt, das den Empfang von Buchungsreporten, die von der iphone-applikation übertragen werden können, ermöglicht. Hierbei wird die Entwicklung einer leichtgewichtigen Schnittstelle angestrebt, die aufseiten des iphone möglichst einfach und transparent verwendet werden kann. Diese soll, unabhängig von externen Technologien, mit Ruby on Rails, HTTP und XML entwickelt und vollständig in die bestehende Webapplikation integriert werden können. Dieses Konzept wird abschließend einer alternativen Umsetzung als RESTul Webservice gegenübergestellt. Wie bereits in Abschnitt 7.3 erwähnt, basiert das gesamte Angebot der Webapplikation wetravel online auf der Übertragung von Buchungsreporten seitens der iphone- Applikation. Diese stellen einen Schnappschuss einer Reise dar und werden in Form einer festdefinierten XML-Struktur (siehe Listing B.1 im Anhang) übertragen. Der Funktionsumfang der Schnittstelle beschränkt sich somit auf den Empfang von Buchungsreporten, die unter Verwendung von Active Record in die Datenbank übertragen und den entsprechenden Benutzerkonten zugeordnet werden Bereitstellung einer Webserviceschnittstelle Für den Aufbau der Kommunikation wird innerhalb der Webapplikation die Controller- Klasse mit dem Namen ApiController verwendet. Diese ermöglicht der iphone-applikation das Übertragen von Reporten über die Action ip_send_report (siehe Abbildung 7.8). Als Übertragungsformat bietet sich beispielsweise die Encodierung als URL innerhalb des Bodys einer HTTP-Post-Anfrage an, da die Größe der XML-Strukturen 131

148 7. Leichtgewichtige Webentwicklung und Webservice-Integration Online::OnlineController + index + ip_send_report ApiController - initialize - create_trip_from_xml_document(rexml::document) : bool - validate_api_token : bool - validate_user_account : bool Abbildung 7.8.: Die Klasse ApiController dient als Schnittstelle zur Kommunikation mit der iphone-applikation. die standardmäßig erlaubte Übertragungsgröße von HTTP-GET-Anfragen oft übersteigt. Ein HTTP-Datenpaket, welches in dieser Form von der iphone-applikation zur Kommunikation mit dem Webservice erstellt wird, ist in Listing 7.17 dargestellt. 1 POST de/online/api/ip_send_report HTTP/1.1 2 Host: localhost 3 Content-Type: application/x-www-form-urlencoded 4 Listing 7.17: Beispiel für ein HTTP-Datenpaket der iphone-applikation. Die Webapplikation kann nach Erhalt einer Anfrage die XML-Struktur den URL- Parametern entnehmen und diese als Argument an die private Methode create_trip_- from_xml_document des Controllers weiterleiten, die der Übernahme der Struktur in die Datenbank dient. Zum Parsen der XML-Struktur bietet sich die Verwendung des XML-Parsers REXML an, der unter anderem die Verwendung von XPath-Ausdrücken erlaubt und besonders für die Verwendung in Ruby optimiert ist. Die Attribute der Entitätsklassen müssen jedoch nicht vollständig von Hand initialisiert werden, da Active Record für das Auslesen von XML-Strukturen eine Methode in diesen bereitstellt. So kann die Struktur mithilfe von REXML in Teile zerlegt und die Teilstrukturen unter Verwendung der Methode from_xml zur Übertragung der Attribute verwendet werden. Voraussetzungen hierfür sind die Einhaltung des entsprechenden Namensschemas und die identische Benennung von XML-Tags und Datenbankattributen beim Entwurf der XML-Struktur. Da ein Report nur dann vollständig ist, wenn sämtliche Entitäten fehlerfrei aus der XML-Datei übertragen wurden, sollte der gesamte Vorgang atomar ablaufen. Hierzu bietet sich die Verwendung der Transaktionsmechanismen des 132

149 7.7. Verbindung von iphone- und Webapplikation verwendeten Datenbanksystems an. Listing 7.18 zeigt die Definition einer Transaktion mittels eines Ruby-Blocks. Dieser führt in jeder Fehlersituation, wie beispielsweise dem Auftreten einer Exception, zu einem Rollback des zugrunde liegenden Datenbestands. 1 ActiveRecord::Base.transaction do 2 # Import der XML-Struktur mittels REXML 3 end Listing 7.18: Nutzung von Transaktionen in Ruby on Rails. Controlleraktionen werden meist in Verbindung mit Ansichten und Layouts verwendet, weshalb Rails diese implizit anhand eines Namensschemas nach der Ausführung einer Aktion zur Ausgabe verwendet. Für den Webservice eignet sich dieses Verhalten jedoch nicht, da für die Antwort an die iphone-applikation eine einfache Zeichenkette als Fehler- bzw. Statuscode genügt. Dieses Verhalten kann durch die explizite Verwendung des Befehls render in den jeweiligen Action- und Filter-Methoden aufgehoben werden und ermöglicht zudem die Ausgabe der erwähnten Statuscodes über die Option :text. Für die Statuscodes eignet sich eine einfache Konvention: Die negativen Ganzzahlen bilden die Menge der Fehlercodes, während alle positiven, natürlichen Zahlen den Erfolg der Aktion bestätigen. Die Werte 1 und 1 repräsentieren einen allgemeinen Erfolg oder Misserfolg. Für die Authentifikation der Benutzer bietet sich die Implementierung eines Filters an, der vor jeder Anfrage der öffentlichen, auf Benutzerkonten beschränkten Methoden zunächst die Benutzerdaten mit der Datenbank abgleicht und im Fehlerfall die weitere Ausführung der Anfrage durch Ausgabe eines Fehlercodes unterbricht. Diese Methode ist in Abbildung 7.8 als validate_user_account bezeichnet. In dieser kann die zuvor beschriebene Klassenmethode authenticate der Klasse User zur Verifizierung des Benutzerkontos verwendet werden Sicherheitstechnische Analyse des Kommunikationsprozesses Die sicherheitstechnischen Aspekte, die bereits hinsichtlich der AJAX-Anmeldemaske genannt wurden, sind auch bei der Entwicklung des Webservices von Bedeutung. Aufgrund dessen wird auch bei diesem HTTPS als Übertragungsprotokoll verwendet. 133

150 7. Leichtgewichtige Webentwicklung und Webservice-Integration Mithilfe eines Filters kann das Protokoll geprüft und bei einer Abweichung ein entsprechender Fehlercode als Information für die zugreifende Applikation bereitgestellt werden. So sind Man-In-The-Middle-Attacken bei der Kommunikation zwischen iphone und Webservice ausgeschlossen. Die beschriebene Architektur erlaubt zunächst den öffentlichen Zugriff auf den Controller. Sind dessen Adresse und die zur Übertragung verwendete Aktion bekannt, kann dieser mit wenig Aufwand und ohne Verwendung der iphone-applikation verwendet werden. Hierzu kann ein einfaches Programm oder Skript geschrieben werden, das die Aufrufe der iphone-applikation imitiert. Auf diese Art und Weise könnten zum Beispiel Brute-Force-Attacken auf Benutzerkonten gestartet werden, da der Controller zunächst keine Maßnahmen gegen Anfragen in kurzen Zeitabständen bereitstellt. Hierzu bietet sich die Generierung einer zufälligen, kryptografisch sicheren Zeichenkette an, die nur der iphone-applikation und dem Webservice bekannt sind. Diese wird bei jeder HTTP-Post-Anfrage übermittelt und kann beispielsweise unter Verwendung eines weiteren Filters vor jeder Aktionsausführung überprüft werden (siehe Methode validate_api_token in Abbildung 7.8). Da die Kommunikation über HTTPS ausgeführt wird, kann diese während des Übertragungsvorgangs nicht abgefangen werden und erschwert die unsachgemäße Verwendung des Controllers erheblich. Einen vollständigen Schutz kann diese Vorgehensweise jedoch nicht bieten, da die Zeichenkette durch eine Disassemblierung der Binärdatei der iphone-applikation offengelegt werden kann. Hierzu müssten Maßnahmen zur Verschleierung in die iphone-applikation integriert werden, wie zum Beispiel eine Verschlüsselung der Zeichenkette Betrachtung von REST als alternative Webservice-Architektur Die beschriebene Webservice-Architektur beweist, dass einzig die Verwendung der Techniken HTTP und XML in Verbindung mit Ruby on Rails für die leichtgewichtige Umsetzung von Webservices im Sinne des Web 2.0 geeignet sind. Alternativ hätte sich die Verwendung von REST als architekturelle Grundlage angeboten. In diesem Fall würde jede Entität, die Bestandteil eines Reports ist, als sogenannte Ressource bereitgestellt. Über die Verwendung eines Namensschemas wird das Auslesen, die Manipulation oder die Erstellung neuer Entitäten ermöglicht. Für iphone-applikationen könnten hierbei die Daten als XML-Struktur lesbar gemacht werden, während die Daten 134

151 7.7. Verbindung von iphone- und Webapplikation für die Darstellung innerhalb von Webbrowsern mittels HTML und CSS aufbereitet werden. Im Gegensatz zum aktuellen Entwurf wäre in diesem Fall die jeweilige iphone- Applikation für den Aufbau eines Reports zuständig. Es bleibt nun zu klären, ob der Einsatz von REST für die Anforderungen des beschriebenen Webservices geeignet ist. Die besondere Stärke von REST liegt in der Strukturierung und Lesbarkeit der URLs (vgl. zu diesem Abschnitt [PZL08], Seite 807) sowie der einheitlichen Gestaltung der Anfragen über den expliziten Einsatz der HTTP-Verben. Dies ermöglicht die Integration und Wiederverwendung von Webservices in jeder denkbaren Art und Weise. Da der beschriebene Webservice jedoch nicht für die Öffentlichkeit bereitgestellt werden soll und für die interne Kommunikation zwischen iphone und Webapplikation dient, relativiert sich diese. RESTful Webservices ermöglichen die zeitgleiche Verarbeitung vieler Anfragen durch Caching, Lastverteilung und Clustering. Dies ist jedoch nicht dem Konzept an sich zu akkreditieren, sondern vielmehr den verwendeten Technologien. HTTP in Kombination mit einem Apache- Webserver ermöglicht von Haus aus die dynamische Lastverteilung zwischen Servern, während Rails die komfortable Steuerung des Caching innerhalb von Controller-Klassen durch Manipulation des HTTP-1.1-Cache-Control-Headers erlaubt. Bei der Verwendung von XHTML-Formularen werden nur die Verben POST und GET unterstützt. Für PUT und DELETE müssen weiträumig Alternativlösungen gefunden werden. So kompensiert Ruby on Rails das Defizit durch den Einsatz von unsichtbaren Formularelementen. Auch der strikte Einsatz von HTTP-GET zur Anfrage von Daten kann bei der Verwendung vieler Eingabedaten problematisch werden, da lange URLs von vielen Servern zurückgewiesen werden 6. Der Entwurf eines Webservices ist stets von den Anforderungen und dem Umfeld abhängig. Während sich REST besonders für öffentliche Webservices, die eine Vielzahl von Informationen bereitstellen, eignet, ist das Konzept für die Übertragung von Buchungsreporten ungeeignet. Obwohl Buchungsreporte aus einer Vielzahl von Datenbankentitäten bestehen, ist die Manipulation einzelner Bestandteile nicht vorgesehen, da nur ein Lesezugriff über die Webapplikation ermöglicht werden soll. Der Einsatz von REST könnte sich jedoch für die Entwicklung einer fortgeschrittenen Version eigenen, die einen Synchronisationsmechanismus und die vollständige Funktionalität der iphone- Applikation aufseiten der Webapplikation vorsieht. Es sind derzeit erste Frameworks in 6 HTTP Code 414: Request-URI Too Long. 135

152 7. Leichtgewichtige Webentwicklung und Webservice-Integration Entwicklung, die die Kommunikation zwischen iphone und Ruby on Rails erleichtern sollen. So kann das Framework ObjectiveResource 7, welches ein Gegenstück zum Rails- Subframework Active Resource 8 aufseiten des iphone bildet, zur Vereinfachung des Prozesses verwendet werden Fazit Wie sich gezeigt hat, ist die Entwicklung einer Webapplikation und die Integration eines Webservices mit Ruby on Rails sehr gut umsetzbar. Sämtliche Problemsituationen konnten auf einfache Art und Weise und hauptsächlich ohne den Einsatz von Bibliotheken Dritter gelöst werden. Besonders der Webservice ließ sich sehr einfach und kompakt realisieren und kann aufseiten des iphone mit wenig Aufwand verwendet werden. Für die Lösung von komplexeren Problemen, wie beispielsweise der dynamischen Erzeugung von Rechnungen, werden weitreichende Bibliotheken von der Ruby- und der Ruby-on-Rails-Community bereitgestellt. Dank der zwei Paradigmen (Conventions over Configuration und DRY) und dem sehr strukturierten Aufbau von Rails wird man stetig dazu motiviert, ein gutes Softwaredesign anzustreben. Wie sich gezeigt hat, können viele Kernpunkte der Softwaretechnik leicht angewandt und die Wartbarkeit des Projekts somit gesteigert werden. Die Sprache Ruby und die reichhaltigen Bibliotheken von Rails unterstützen nicht nur die Programmierung, sondern motivieren ebenso zu einer stetigen Verbesserung des eigenen Programmcodes. Die genannten Technologien des Web-2.0-Konzepts haben sich für die Realisierung der Webapplikation gut geeignet. Dennoch lässt sich die Applikation im Sinne von Tim O Reilly (siehe [O R05]) nicht vollständig dem Web-2.0 zuordnen, da diese durch das geschlossene Angebot einigen Kerngedanken widerspricht. Die Applikation macht sich vielmehr die genannten Techniken zunutze und stellt den Benutzern somit ein modernes Webangebot zur Verfügung, welches sich durch den Einsatz offener Standards in einer Vielzahl von Webbrowsern identisch darstellen lässt und aufseiten der Entwickler stetig im Hintergrund erweitert sowie verbessert werden kann Das Framework Active Resource dient der komfortablen Abbildung von Ressourcen auf Ruby- Objekte. 136

153 KAPITEL 8 Integration von In-App-Purchases in iphone- und Webapplikation Seit der Einführung des iphone OS 3.0 im Juni 2009 (siehe [App09b]) hat sich die Nutzung der sogenannten In-App-Purchases, sprich Kaufangebote innerhalb von iphone- Applikationen, weiträumig im Umfeld des App Store etabliert. Eine über das iphone SDK bereitgestellte Schnittstelle, das sogenannte Store-Kit-Framework, ermöglicht das Anbieten und Abwickeln von App-Store-Verkäufen innerhalb von Apps. Das Framework stellt für die Entwicklung drei Produkttypen bereit: Verbrauchsgüter (Consumables), Nicht-Verbrauchsgüter (Nonconsumables) und Abonnements (Subscriptions). Verbrauchsgüter eignen sich zum Beispiel für die Erzeugung von Einmal-Diensten (sogenannte One-Time-Services). Bei diesen muss bei jeder Beanspruchung erneut eine Zahlung durchgeführt werden. Im Gegensatz hierzu müssen Nicht-Verbrauchsgüter nur ein einziges Mal gekauft werden. Wurde eine zusätzliche Funktionalität einer Applikation erworben, muss diese auch auf möglichen Zweitgeräten der Endbenutzer verfügbar gemacht werden können. Beide Produkttypen sind vollständig durch das Framework gestützt und können ohne den Einsatz eines externen Servers bereitgestellt werden. Der Abschluss von Abonnements muss im Kontrast hierzu unter Zuhilfenahme eines getrennten, selbstständig bereitgestellten Servers erfolgen. Für das Anbieten von Autor: Benjamin Glatzel 137

154 8. Integration von In-App-Purchases in iphone- und Webapplikation In-App-Purchases verlangt die Firma Apple 30 % des über den Dienst erwirtschafteten Erlöses (siehe [App09a]), die restlichen 70 % des Verkaufspreises gehen an den Anbieter der Applikation. Die Bereitstellung von kostenpflichtigen Inhalten ist innerhalb des iphone Developer Program License Agreement (siehe [App10i]) explizit auf den App Store limitiert. Die Nutzung von externen Freischaltungs- und Zahlungstransaktionsmechanismen, wie zum Beispiel Kreditkartenzahlungen innerhalb eines externen Onlinestores, ist nicht erlaubt und führt mit hoher Wahrscheinlichkeit innerhalb des App-Review-Prozesses zu einer Ablehnung der Applikation seitens Apple. Innerhalb dieses Abschnitts steht die Entwicklung eines sogenannten In-App-Purchases im Mittelpunkt. Hierbei soll ein Abonnement innerhalb einer iphone-applikation abgeschlossen und in Verbindung mit einem Kundenkonto seitens der Webapplikation freigeschaltet werden können. Zur Veranschaulichung des Gesamtkonzepts wird dieses zunächst abstrakt in Abschnitt 8.1 diskutiert. Innerhalb von Abschnitt 8.2 folgt ein Überblick über das Store-Kit-Framework und eine Erörterung einiger Kernpunkte bei der Integration dessen in eine bestehende iphone-applikation. Zudem werden an dieser Stelle mögliche Risiken, die durch Abwicklung des Kaufprozesses aufseiten des iphone entstehen können, und Möglichkeiten zur Milderung dieser besprochen. Innerhalb von Abschnitt 8.3 wird die Integration der Kaufschnittstelle aufseiten der Webapplikation diskutiert und Techniken zur Absicherung des Abonnementabschlusses erörtert. Das Kapitel wird mit der Beschreibung einer einfachen Möglichkeit zur Breitstellung einer Interessentenstatistik innerhalb einer kostenlosen Lite-Version, die ohne Nutzung externer Statistikdienste und weiterer Frameworks funktioniert, abgeschlossen (siehe Abschnitt 8.4). Die In App Purchase Programming Guide (siehe [App10g]) bildet das Fundament zur Entwicklung von In-App-Purchases in Verbindung mit dem Store-Kit- Framework und bildet somit die literarische Grundlage dieses Kapitels Einführung in das grundlegende Konzept zum Abschluss von Abonnements Für die Bereitstellung von Abonnements müssen ein getrennter Server und eine für diese Aufgabe entwickelte Webapplikation eingesetzt werden. Innerhalb dieses Kapitels 138

155 8.2. Nutzung und Integration des Store-Kit-Framework dient, wie bereits erwähnt wurde, die Entwicklung und Integration einer Abonnementfunktionalität als Beispiel. Der Benutzer soll hierzu einen Kauf innerhalb der iphone-applikation tätigen können und nach erfolgter Zahlungstransaktion im Gegenzug ein zeitlich begrenztes Benutzerkonto seitens der Webapplikation erhalten. Abbildung 8.1 zeigt zunächst eine vereinfachte Form der in diesem Kapitel verwendeten Vorgehensweise. Nach Abschluss einer Kauftransaktion aufseiten der iphone-applikation wird, vereinfacht gesagt, eine Verkaufsquittung in Verbindung mit den gewünschten Benutzerdaten (die Benutzerdaten bestehen aus einer -Adresse sowie einem Passwort und der zugehörigen Passwortbestätigung) an den Server übermittelt, von diesem validiert und entsprechend des Ergebnisses der Validierung ein Benutzerkonto freigeschaltet oder die Erzeugung verweigert. In den folgenden Abschnitten werden beide Stationen, sprich die Integration des Store-Kit-Framework innerhalb der App und die Bereitstellung der Kauf-Webserviceschnittstelle, detailliert diskutiert und die Kernpunkte der Thematik offengelegt Nutzung und Integration des Store-Kit-Framework Das von Apple bereitgestellte Store-Kit-Framework (siehe [App10g]) stellt, wie schon erwähnt, die Schnittstelle zum App Store dar. Mithilfe dieses Frameworks können verfügbare In-App-Purchase-Angebote sowohl abgerufen, als auch gekauft werden. Autor: Dominik Wilhelm Abruf von In-App-Purchase-Produkten Die Anzeige der mit In-App-Purchase-Angeboten verbundenen Informationen kann mithilfe eines Anfrage-Objekts realisiert werden. Die Instanz des Anfrage-Objekts, das durch die SKProductsRequest-Klasse dargestellt wird, kann an beliebiger Stelle innerhalb der Applikation initialisiert werden. Der Initialisierungsmethode müssen lediglich die Product-Identifier der In-App-Purchase-Produkte übergeben werden (siehe Abbildung 8.2 Schritt 1). 139

156 8. Integration von In-App-Purchases in iphone- und Webapplikation 1 Übertragung der Benutzerdaten zur Validierung HTTP-POST Validierung der Benutzerdaten 2 3 Abschluss eines Kaufs über das Store-Kit- Framework Benutzerdaten sind valide Kauf war erfolgreich 4 Übertragung von Benutzerdaten und Verkaufsquittung HTTP-POST Validierung der Verkaufsquittung über Apple-Webservice- Schnittstelle 5 Quittung ist gültig 7 Benachrichtung des Benutzers und Übernahme der Kontodaten in die Einstellungen der Applikation Benutzerkonto freigeschaltet Freischaltung des Benutzerkontos für 90 Tage 6 Abbildung 8.1.: Ablauf zur Freischaltung eines innerhalb der iphone-applikation erworbenen Abonnements. 140

157 8.2. Nutzung und Integration des Store-Kit-Framework 1 NSSet * myidentifiers = [NSSet 2 SKProductsRequest * myrequest = [[SKProductsRequest alloc] initwithproductidentifiers:myidentifiers]; 3 // Setzen des Delegaten (in diesem Beispiel die aktive Instanz der Klasse) 4 myrequest.delegate = self; 5 [myrequest start]; Listing 8.1: Initialisierung der SKProductsRequest-Klasse. Nach erfolgreicher Initialisierung wird der Delegat gesetzt und die Anfrage an den App Store übermittelt (siehe Abbildung 8.2 Schritt 2). Da nach Übermittlung und Verarbeitung der Anfrage die Applikation asynchron benachrichtigt wird, muss die Delegat-Klasse das SKProductsRequestDelegate-Protokoll einbinden und die darin enthaltene didreceiveresponse-methode implementieren. Die SKProductsRequest-Instanz informiert ihren Delegaten mittels dieser Methode über den Erhalt einer Antwort und teilt ihm diese mit (siehe Abbildung 8.2 Schritt 4). Die Antwort wird durch ein SKProductsResponse-Objekt dargestellt, das zu jedem angeforderten Produkt ein SKProduct-Objekt bereitstellt (siehe Abbildung 8.2 Schritt 3). 1 - (void)productsrequest:(skproductsrequest *)request didreceiveresponse:( SKProductsResponse *) response { 2 for(skproduct * myproduct in response.products) { 3 4 } 5 } Listing 8.2: Verarbeitung eines SKProductResponse-Objekts. 1 Erdbeerkuchen 2 Kartoffelsalat Listing 8.3: Ausgabe der obigen Methode. Das in Listing 8.2 dargestellte Beispiel stellt die Verarbeitung der Antwort auf die in Listing 8.1 gestellte Anfrage dar. Die SKProduct-Objekte enthalten letztendlich die auf das Produkt bezogenen Informationen in einer lokalisierten Fassung. Diese Lokalisierung ist von der mit der Apple-ID verknüpften App-Store-Variante abhängig. Neben der lokalisierten Variante des Titels, der Beschreibung und des Product-Identifiers, enthält 141

158 8. Integration von In-App-Purchases in iphone- und Webapplikation das SKProduct-Objekt zusätzlich den Preis und dessen lokalen Wert 1. Abbildung 8.2 stellt den soeben beschriebenen Vorgang nochmals bildlich dar. App Store SKProductsResponse «interface» SKProductsRequestDelegate ExampleViewController SKProductsRequest Product-Identifiers: "Rezept1" und "Rezept2" SKProduct Name: Erdbeerkuchen Description: [...] Price: [...] SKProduct Name: Kartoffelsalat Description: [...] Price: [...] Abbildung 8.2.: Ablauf zu Ermittlung von In-App-Purchase-Produkten Integration der Kauffunktionalität für In-App-Purchases Der zweite Teil des Store-Kit-Frameworks ist für den Kauf von In-App-Purchase- Produkten zuständig. Vor Implementierung des genauen Ablaufs empfiehlt sich die gründliche Planung dessen, da dieser Mechanismus während des Review-Prozesses besonders ausführlich getestet und somit fehlerfrei sein muss. Dies hat den Hintergrund, dass bei einem Fehlverhalten ein Produkt mehrmals gekauft wird, obwohl dies nicht erwünscht war. Das in diesem Abschnitt aufgegriffene Beispiel ist in Abbildung 8.1 aufgeführt. Bei konsumierbaren bzw. abonnierbaren In-App-Purchase-Produkten muss der Entwickler deren Lebenszeit selbst verwalten. Dies bedeutet, dass nach Ablauf der vorgegebenen Zeitspanne bzw. nach Konsum die Funktionalität von der Applikation deaktiviert werden muss. In dem in Abschnitt 8.1 beschriebenen Konzept bedeutet dies, dass nach Ablauf des Abos der Webserver das Benutzerkonto sperrt. 1 Eine Applikation, die im amerikanischen App Store einen Wert von 2,99 $ hat, kostet im deutschen App Store 2,39 e. 142

159 8.2. Nutzung und Integration des Store-Kit-Framework Ein Kaufvorgang kann somit in zwei Teile getrennt werden. Zum einen der eigentliche Kaufvorgang und zum anderen die Interaktion mit dem Server. Da an verschiedenen Stellen der Applikation der Kaufmechanismus sinnvoll sein kann, empfiehlt sich auch hier wieder die Bündelung des Funktionsumfangs. Die nach dem Singleton-Pattern aufgebaute Klasse, in diesem Beispiel WTOnlineStoreManager benannt, stellt die Verbindung zu Store Kit her, wickelt den Kauf ab und übernimmt die Kommunikation mit dem Server. Hierfür bietet sich die Nutzung der in Abschnitt vorgestellten WTServerConnection-Klasse an. Damit In-App-Purchase-Produkte gekauft werden können, muss zuerst die Verbindung zum Store-Kit-Framework hergestellt werden. Dies geschieht indem eine beliebige Klasse, in diesem Fall die eigens dafür erstellte WTOnlineStoreManager-Klasse, die SKPaymentQueue-Klasse instanziiert und das dazugehörige SKPaymentTransactionObserver-Protokoll implementiert (siehe Abbildung 8.3 Schritt 1). Diese SKPaymentQueue-Klasse ist ebenfalls mithilfe des Singletonund Observer-Patterns realisiert und informiert bei Aktualisierungen der in der Warteschlange enthaltenen Kaufvorgänge die entsprechenden Beobachter. Abbildung 8.3 verbildlicht den Kaufvorgang und zeigt alle benötigten und im Folgenden erklärten Komponenten auf. 1 [[SKPaymentQueue defaultqueue] addtransactionobserver:self]; Listing 8.4: Beobachteranmeldung bei der SKPaymentQueue-Klasse. Der in Listing 8.4 gezeigte Methodenaufruf wird innerhalb der Initialisierungsmethode der WTOnlineStoreManager-Klasse platziert und registriert diese als Beobachter für die genannten Aktualisierungen. Das iphone bietet die Möglichkeit den Kauf von Applikationen zu unterbinden. Bevor der Kauf eines Produkts eingeleitet werden kann, sollte mithilfe der canmakepayments-methode der SKPaymentQueue-Klasse zunächst die Verfügbarkeit dieser Funktionalität überprüft werden. Da jedes Abonnement mit der Erstellung eines Benutzerkontos auf dem Webserver verbunden ist, müssen die zuvor eingegebenen Benutzerdaten, bestehend aus der -Adresse und Passwort sowie Passwortbestätigung, validiert werden (siehe Abbildung 8.1 Schritte 1 und 2). Durch Nutzung der docheckaccountwithcontent-methode der WTServerConnection- Klasse können die Benutzerdaten an den Server übermittelt und von diesem überprüft werden. Mittels der im WTServerConnectionDelegate definierten finishedcheckingaccountwitherrorcode-methode wird das Ergebnis der Überprüfung an den Aufrufer zurückgeliefert. Existiert noch kein Benutzerkonto für die überprüfte -Adresse, 143

160 8. Integration von In-App-Purchases in iphone- und Webapplikation App Store «interface» SKPaymentTransactionObserver 4 WTOnlineStoreManager 2 Instanziieren SKPayment Produktidentifikation: Kartoffelsalat Anzahl: 1 1 Instanziieren 5 Aktualisierung 6 Abschluss 3 Wird übergeben SKPaymentQueue SKPaymentTransaction SKPayment Produktidentifikation: Kartoffelsalat Anzahl: 1 [...] Abbildung 8.3.: Der Kauf eines In-App-Purchase-Produkts. 144

161 8.2. Nutzung und Integration des Store-Kit-Framework so kann der Kaufvorgang durchgeführt werden (siehe Abbildung 8.1 Schritt 3). Dies wird mithilfe des in Listing 8.5 gezeigten Hinzufügens eines SKPayment-Objekts zur SKPaymentQueue realisiert (siehe Abbildung 8.3 Schritte 2 und 3). 1 SKPayment * mypayment = [SKPayment ]; 2 3 [[SKPaymentQueue defaultqueue] addpayment:mypayment]; Listing 8.5: Durchführung eines Kaufvorgangs. Für das übergebene SKPayment-Objekt wird eine Transaktion in Form eines SKPaymentTransaction-Objekts erstellt. Über die im SKPaymentTransactionObserver-Protokoll definierte und zu implementierende paymentqueue:updatedtransactions-methode erhält der angemeldete Beobachter Aktualisierungen bezüglich der SKPaymentTransaction-Objekte (siehe Abbildung 8.3 Schritt 5). Der in den SKPaymentTransaction- Objekten enthaltene Status gibt Aufschluss über den Fortschritt der Transaktion. Steht dieser auf SKPaymentTransactionStatePurchased, konnte der Kauf erfolgreich durchgeführt werden und der Webserver kann mit der Erstellung des Benutzerkontos beauftragt werden (siehe Abbildung 8.1 Schritt 4). 1 - (void)paymentqueue:(skpaymentqueue *)queue updatedtransactions:(nsarray *)transactions { 2 for (SKPaymentTransaction *transaction in transactions) { 3 if(transaction.transactionstate == SKPaymentTransactionStatePurchased) { 4 [mycontent setvalue:[wtbase64 encodewithdata:transaction. transactionreceipt] 5 [[[[WTServerConnection alloc] initwithdelegate:self] autorelease] docreateaccountwithcontent:mycontent]; 6 [[SKPaymentQueue defaultqueue] finishtransaction: transaction]; 7 } 8 } 9 } Listing 8.6: Überprüfung des Transaktionsstatus. Listing 8.6 zeigt die Überprüfung des Status und die Erzeugung des Benutzerkontos mithilfe einer erneuten Anfrage an den Server. Die Transaktion enthält neben SKPayment-Objekt und Status auch eine Quittung, genannt Receipt. Diese Quittung 145

162 8. Integration von In-App-Purchases in iphone- und Webapplikation wird zusammen mit den bereits validierten Benutzerdaten an den Server übertragen. Abgeschlossene Transaktionen müssen letztendlich noch aus der Queue entfernt werden (siehe Abbildung 8.3 Schritt 6). Auf Seiten des Servers wird die übertragene Quittung, wie in Abschnitt 8.3 beschrieben, überprüft (siehe Abbildung 8.1 Schritt 5). Das Ergebnis der Überprüfung und Erstellung des Benutzerkontos wird mithilfe der im WTServerConnectionDelegate definierten finishedcreatingaccountwitherrorcode- Methode an die WTOnlineStoreManager-Klasse übermittelt. Für den Fall, dass bei Erstellung des Benutzerkontos die Verbindung zum Server abbricht, müssen spezielle Sicherheitsvorkehrungen getroffen werden. Der Benutzer würde zwar das Abo kaufen, die Erstellung eines Benutzerkontos kann jedoch nicht gewährleistet werden. Um diesen Fall auszuschließen, wird im Falle eines Fehlers die Quittung gespeichert und der Benutzer über den Fehler informiert. Damit das Abonnement nicht erneut gekauft wird, darf die Erstellung des SKPayment-Objekts nur durchgeführt werden, wenn keine gespeicherte Quittung existiert. Im Falle, dass ein solches Quittungs-Objekt existiert, wird ein erneuter Versuch zur Erstellung des Benutzerkontos unternommen. Wird dieses Konto letztendlich erfolgreich angelegt, so muss die gespeicherte Quittung entfernt werden, sodass nicht mehrere Benutzerkonten mit nur einem bezahlten Abonnement erstellt werden können Bereitstellung der serverseitigen Abonnementfunktionalität Autor: Benjamin Glatzel Im vorhergehenden Abschnitt stand die Integration von Kauffunktionalitäten mithilfe des Store-Kit-Framework innerhalb von iphone-applikationen im Mittelpunkt. Innerhalb dieses Abschnitts wird nun die Bereitstellung einer entsprechenden Schnittstelle diskutiert, die, ausgehend von der Übertragung der zuvor beschriebenen Verkaufsquittungen und Benutzerdaten, die Bereitstellung der Funktionalität zur Erzeugung von Benutzerkonten und die Absicherung des Prozesses aufseiten der Webapplikation ermöglicht. Für die Komplettierung der Kauffunktionalität muss die in Kapitel 7 beschriebene Controllerklasse ApiController um zwei öffentliche Actions erweitert werden. Die Erste dient hierbei der Verifizierung der vom Benutzer angegebenen Anmeldedaten und die Zweite der abschließenden Erzeugung des Benutzerkontos. Für diesen Abschnitt 146

163 8.3. Bereitstellung der serverseitigen Abonnementfunktionalität gelten die in Kapitel 7 erläuterten Methoden zur Entwicklung von leichtgewichtigen Webserviceschnittstellen und die bereits erwähnten Paradigmen bei der Entwicklung von Ruby-on-Rails-Applikationen. Die Verlängerung von Benutzerkonten kann parallel umgesetzt werden und wird aufgrund dessen innerhalb dieses Abschnitts nicht explizit erläutert. Online::OnlineController + index + ip_send_report + ip_validate_account_data + ip_create_account ApiController - initialize - create_trip_from_xml_document(rexml::document) : bool - validate_api_token : bool - validate_user_account : bool - validate_receipt : bool - validate_account_data : bool - validate_subscription : bool Abbildung 8.4.: Die für die Bereitstellung der Kauffunktionalität erweiterte Controllerklasse ApiController. Abbildung 8.4 zeigt zunächst die erweiterte Struktur der Klasse ApiController. Hierbei sind jene Elemente schwarz hervorgehoben, die innerhalb dieses Abschnitts von besonderer Bedeutung sind. So bilden die Actions ip_validate_account_data und ip_- create_account die Schnittstelle zur Erzeugung von Konten für die iphone-applikation. Bei der Umsetzung der Funktionalität sind zunächst drei Schritte von Bedeutung: die Bereitstellung einer Benutzerdatenvalidierung innerhalb beider Actions, die Validierung und Persistierung der übertragenen Verkaufsquittung vor der Freischaltung des Benutzerkontos sowie die eigentliche Erzeugung der entsprechenden Benutzerkonten in Abhängigkeit zu den Ergebnissen beider Validierungen. An dieser Stelle sei zunächst die Validierung der Benutzerdaten erwähnt. Die Action ip_validate_account_data dient nur der Überprüfung der Anmeldedaten des Benutzers vor der Ausführung des eigentlichen Kaufvorgangs aufseiten der iphone-applikation (siehe Abbildung 8.1 Schritt 2). Diese müssen zur Sicherheit auch vor der Freischaltung des neuen Benutzerkontos, sprich vor der Ausführung der Action ip_create_account, geprüft werden. Um Redundanzen zu vermeiden, sollte die Validierung innerhalb 147

164 8. Integration von In-App-Purchases in iphone- und Webapplikation eines Filters, in Abbildung 8.4 ist die zugehörige Methode validate_account_data genannt, implementiert werden, sodass diese vor der Ausführung beider Actions erfolgt. Hierbei sollte die -Adresse mithilfe eines regulären Ausdrucks geprüft sowie die Übereinstimmung von Passwort- und Passwortbestätigung sichergestellt werden. Um die Zuständigkeiten möglichst eindeutig aufzuteilen, sollten für die Verifizierung der Benutzerdaten die durch das Subframework Active Record bereitgestellten Validations genutzt werden. Um diese innerhalb des Filters einzusetzen, kann beispielsweise, wie in Listing 8.7 gezeigt, ein Dummyobjekt erzeugt und explizit auf bestimmte Validations geprüft werden. An dieser Stelle können entsprechende Fehlercodes in Abhängigkeit dieser an die iphone-applikation übertragen werden. 1 def validate_account_data 2 temp_user = User.new(:e_mail => params[:e_mail], :password => params[: password], :password_confirmation => params[:password_confirm]) 3 if not temp_user.valid? 4 # Mindestens eine Validation ist fehlgeschlagen 5 if temp_user.errors.invalid? :e_mail 6 # Ungueltige -Adresse 7 render :text => return false 9 elsif temp_user.errors.invalid? :password 10 # Ungueltiges Passwort 11 render :text => return false 13 end 14 else 15 # Die Benutzerdaten sind valide 16 return true 17 end 18 # Nicht explizit differenzierbarer Fehler 19 render :text => return false 21 end Listing 8.7: Validierung der Benutzerdaten mithilfe eines Filters und eines Dummyobjekts. Für die Freischaltung der Benutzerkonten (siehe Abbildung 8.1 Schritte 5 und 6) müssen mehrere Aspekte bei der Absicherung des Prozesses bedacht werden. Zunächst dürfen nur Käufe gewertet werden, die tatsächlich über den App Store ausgeführt wurden. Hierzu können die von der iphone-applikation übertragenen App-Store-Verkaufsquittungen 148

165 8.3. Bereitstellung der serverseitigen Abonnementfunktionalität in ihrer base64-enkodierten Form an eine von Apple bereitgestellte Schnittstelle zur Validierung übermittelt werden. Für die Protokollierung sämtlicher Kaufaktivitäten und zum Ausschluss der wiederholten Verwendung von Quittungen sollten diese vollständig innerhalb der Datenbank abgelegt werden. Nach Übertragung des Base64-Strings gibt der Apple-Webservice den Inhalt im Klartext als JSON-Objekt zurück und stellt innerhalb der Variablen status die Validität der Anfrage dar. Innerhalb der offiziellen Dokumentation steht lediglich, dass valide Quittungen einen Statuscode gleich null und invalide Quittungen hingegen einen Statuscode ungleich null besitzen. Die genauen Fehlercodes werden nicht näher spezifiziert. Der Validierungsprozess der Quittungen sollte, wie zuvor, als Filter vor der Ausführung der Kontoerzeugung implementiert werden. Innerhalb dieser muss der Base64-String als JSON-Objekt kodiert und innerhalb einer HTTP-Post-Anfrage an die Webserviceschnittstelle übermittelt werden. Listing 8.8 zeigt zunächst, in welcher Form dieser Aufruf mithilfe der Ruby-Bibliotheken ausgeführt werden kann. 1 def validate_receipt 2 uri = URI.parse("https://buy.itunes.apple.com/verifyReceipt") 3 http = Net::HTTP.new(uri.host, 443) 4 http.use_ssl = true # Die Verbindung ueber SSL ausfuehren 5 # Initiierung der Uebertragung 6 http.start do http 7 req = Net::HTTP::Post.new("/verifyReceipt") 8 req.body = "{ \"receipt-data\" : \"#{params[:receipt]}\" }" 9 response = http.request(req) 10 # Erzeugung einer Hashmap aus den Ergebnisdaten 11 json_response = ActiveSupport::JSON.decode(response.body) 12 # Pruefung des Statuscodes 13 if (json_response["status"] == 0) 14 # Die gueltige Quittung als Instanzvariable bereitstellen = json_response["receipt"] 16 return true 17 end 18 end 19 render :text => # Ungueltige Quittung 20 return false 21 end Listing 8.8: Übertragung einer base64-enkodierten Quittung zur Validierung. 149

166 8. Integration von In-App-Purchases in iphone- und Webapplikation Für die Validierung wird hierbei zunächst eine Verbindung über HTTP aufgebaut, der Base64-String innerhalb des HTTP-Body in der JavaScript Object Notation übertragen, die Antwort des Webservices auf Gültigkeit geprüft und für die weitere Verwendung als Instanzvariable bereitgestellt. Quittungen sollten, wie bereits erwähnt, zur Sicherheit vollständig innerhalb der Datenbank abgelegt werden. Hierzu muss zunächst die Datenbank entsprechend vorbereitet und migriert sowie eine Active- Record-Klasse mit den nötigen Attributen erzeugt werden. Der Einfachheit halber sollten diese identisch zu den durch die Validierung bereitgestellten JSON-Attributen benannt werden (siehe Abbildung 8.5) und das Anlegen von identischen Quittungen mithilfe einer Validation, in Form von validates_uniqueness_of :transaction_id, aus Sicherheitsgründen unterbunden werden. ActiveRecord::Base Receipt quantity : integer transaction_id : string purchase_date : date original_purchase_date : date original_transaction_id : string item_id : string version_external_identifier : string bid : string bvrs : string Abbildung 8.5.: Die Entitätsklasse zur Speicherung der Transaktionsquittungen innerhalb der Datenbank. Ein Benutzerkonto und die zugehörige Verkaufsquittung können nun, wie in Listing 8.9 gezeigt, erstellt und miteinander in Verbindung gebracht werden. 1 def ip_create_account 2 # Eine Datenbanktransaktion verwenden 3 ActiveRecord::Base.transaction do 4 # Das zukuenftige Benutzerkonto anlegen 5 u = User.new(:e_mail => params[:e_mail],:password => params[:password ], :password_confirmation => params[:password_confirm]) 6 # Die Quittung zurechtschneiden *Receipt.column_names 8 # Die Quittung erzeugen und an das Benutzerobjekt binden 9 r = 150

167 8.3. Bereitstellung der serverseitigen Abonnementfunktionalität 10 u.receipts << r 11 # Die Daten persistieren 12 u.save! 13 r.save! 14 # Den Statuscode fuer die iphone-applikation bereitstellen 15 render :text => 1 16 return 17 end 18 end Listing 8.9: Erzeugung des Benutzerkontos. Bei dieser Implementierung wurde zusätzlich beachtet, dass die durch den Apple- Webservice bereitgestellten Daten variieren können. Sollte eine Quittung aus unerfindlichen Gründen neue Attribute erlangen, werden diese zunächst mithilfe der Methode slice! entfernt, sodass nur jene Attribute übernommen werden, die innerhalb der Datenbankstruktur vorgesehen wurden. Beachtet man dies nicht, könnte im Ernstfall an dieser Stelle eine Exception auftreten und die Erzeugung des Benutzerkontos unterbrochen werden. Abschließend muss die Verifizierung in den in Kapitel 7 beschriebenen Authentifikationsmechanismus integriert werden. Dieser sollte wie zuvor direkt innerhalb der Entitätsklassen bereitgestellt werden, um erneut aus Sicht der Softwaretechnik eine möglichst strikte Kapselung von Zuständigkeiten zu erreichen. Listing 8.10 zeigt eine Methode, die der in Kapitel 7 beschriebenen Active-Record-Klasse User zuzuordnen ist und die Quittungen des Benutzers auf eine aktive Mitgliedschaft prüft. Hierzu werden sämtliche Quittungen des Benutzers geprüft und nur dann als gültig angesehen, wenn diese ein Kaufdatum besitzen, welches nicht länger als drei Monate zurückliegt. 1 def has_valid_subscription? 2 # Alle Quittungen des Benutzers pruefen 3 receipts.each do r 4 # Pruefen ob diese vor weniger als drei Monaten erworben wurde 5 compare_result = r.purchase_date.advance(:months => 3) - Date.today 6 # Gueltige Quittung gefunden 7 if compare_result > 0 8 return compare_result 9 end 10 end 11 # Keine gueltige Mitgliedschaft 151

168 8. Integration von In-App-Purchases in iphone- und Webapplikation 12 return nil 13 end Listing 8.10: Prüfung der Mitgliedschaft anhand der gespeicherten Quittungen. Diese Methode kann nun für die Authentifikationsmechanismen der Webserviceschnittstelle und der AJAX-Anmeldemaske verwendet und in diese integriert werden. Je nach Umsetzung könnte beispielsweise der Zugriff nach Ablauf einer Mitgliedschaft vollständig verwehrt oder aufseiten der iphone-applikation eine Erneuerung der Mitgliedschaft angeboten werden. Innerhalb der Beispielklasse ApiController ist die Methode validate_subscription (siehe Abbildung 8.4) für den Aufruf der soeben beschriebenen Methode has_valid_subscription? nach Auflösung des angeforderten Benutzerkontos zuständig und dient als Filter für alle auf eine Mitgliedschaft beschränkten Actions. An dieser Stelle ist zu beachten, dass für die Authentifizierung der Benutzerkonten zusätzlich der in Kapitel 7 beschriebene Filter verwendet und die Authentifikation an dieser Stelle nicht erneut ausgeführt wird Erfassung von Interessentenstatistiken Wie bereits in Abschnitt 6.5 erwähnt wurde, dient die Veröffentlichung von sogenannten Lite-Versionen der Erschließung eines größeren Benutzerumfeldes und der Überzeugung potenzieller Käufer. Innerhalb dieser kostenfreien Programmversionen kommt häufig eine Weiterleitung in Form eines Buttons oder Werbebanners auf die Verkaufsseite der Vollversion im App Store zum Einsatz, die letztendlich von Interessenten zur komfortablen Informationsbeschaffung und zum Kauf verwendet werden kann. Für die Entwickler von iphone-applikationen stellt Apple über den Dienst itunes Connect Verkaufs- und Downloadstatistiken bereit. Verkaufsstatistiken kommerziell erfolgreicher Apps zeigen, dass das Verhältnis des Bezuges von Lite- und Vollversion im Verhältnis 100 zu 1-3 steht (siehe [WS10], Seite 111). Dies beweist, dass der Einsatz von Lite- Versionen einen nicht unerheblichen Einfluss auf den Verkaufserfolg der Applikationen hat. Die erwähnten itunes-connect-statistiken erlauben lediglich die Betrachtung der Verkaufs- und Downloadstatistiken. Besonders beim Vertrieb von iphone-applikationen in Verbindung mit kostenfreien Lite-Versionen können diese Statistiken zur Analyse des angestrebten Verkaufskonzepts zunächst unzureichend sein. So können beispielsweise 152

169 8.4. Erfassung von Interessentenstatistiken keine Rückschlüsse auf Käufer, die nach Betrachtung der Vollversion von einem Kauf abgesehen haben, gezogen werden. Auch die Positionierung des App-Store-Hyperlinks könnte ungünstig gewählt sein, sodass Interessenten diesen nicht unmittelbar erkennen können. Um diese Problematiken frühzeitig zu erkennen und den Verkaufserfolg der Applikation zu steigern, eignet sich der Einsatz einer primitiven Statistikfunktionalität innerhalb der Lite-Version in Verbindung mit einem entsprechenden Webservice und bestenfalls einem grafischen Frontend. Innerhalb dieses Abschnitts wird ein Ansatz zur einfachen Integration einer Interessentenstatistik innerhalb einer bestehenden iphone- Applikation erläutert und der entstehende Nutzen einer solchen Funktionalität diskutiert. Hierbei dienen die in Kapitel 6 beschriebene Serverkommunikationsschnittstelle seitens der iphone-applikation und die in Kapitel 7 erläuterte Webserviceschnittstelle als Ausgangspunkte für die Integration. Für die Erfassung der gewünschten Statistik genügt seitens der Webapplikation die Implementierung eines primitiven Mechanismus. Innerhalb der zuvor beschriebenen Webserviceschnittstelle muss hierfür eine weitere Action erzeugt werden, die erneut in Form von URL-Parametern im HTTP-Body Daten entgegen nehmen kann. Diese sei hier exemplarisch ip_log_invocation genannt und ist der zuvor genannten Controllerklasse ApiController zuzuordnen. Nach erfolgtem Aufruf dieser wird die IP-Adresse des Aufrufers zusammen mit einer Zeichenkette zur Identifizierung des Aufruftyps und einem Zeitstempel innerhalb der Datenbank gespeichert. Um wiederholte Aufrufe auszuschließen, sollte in Form einer angepassten Validation das wiederholte Logging einer identischen IP-Adresse pro Identifizierungsstring für einen bestimmten Zeitraum (zum Beispiel für einen Tag) ausgeschlossen werden. Der Aufruf dieser Action innerhalb der Serverkommunkationsklasse der iphone-applikation kann parallel zu den vorherigen Beispielen implementiert werden. Hierzu muss, wie bereits erwähnt, lediglich ein Identifikationsstring an die entsprechende URL übergeben werden. So können beispielsweise unter der Bezeichnung LITE_APP_STORE_LINK serverseitig Aufrufe des App-Store-Hyperlinks protokolliert und zur Erzeugung von Statistiken verwendet werden. Mithilfe der Serverkommunikationsklasse kann vor dem Aufruf des App-Store-Hyperlinks eine Protokollierung dessen erreicht werden. Aufseiten des iphone kann die Anzeige des App Stores über den Aufruf einer festdefinierten URL-Struktur erfolgen. Hierzu stellt die UIKit-Klasse UIApplication die Methode openurl: bereit. Zur Darstellung des App Stores muss, ähnlich zum Aufruf 153

170 8. Integration von In-App-Purchases in iphone- und Webapplikation einer Webseite im Safari-Webbrowser, die aktuell aktive Applikation beendet werden. Durch Ausführung der Protokollierung sollte der Benutzer unter keinen Umständen beeinträchtigt werden. Ein Beispiel hierfür wäre, dass nach Aufruf des App-Store- Hyperlinks erst auf einen nicht erreichbaren Logging-Server gewartet wird. Um dieses Verhalten auszuschließen, sollte ein Aufruf maximal 1 3 s andauern dürfen und die Verbindung stets asynchron erfolgen. Dies kann durch Verzögerung der Weiterleitung um eine kurze Zeitspanne erreicht werden. Falls die Verbindung in diesem Zeitraum nicht abgeschlossen wurde, wird diese durch die Beendigung der Applikation unterbrochen. Listing 8.11 zeigt exemplarisch die Ausführung der Protokollierung mithilfe der Serverkommunkationsklasse und einen zeitverzögerten Aufruf des App Stores. 1 // Serverseitige Prokollierung des Aufrufs initiieren 2 [[[[WTServerConnection alloc] initwithobserver:nil] autorelease] 3 // Nach zwei Sekunden die Applikation beenden und die Verkaufsseite innerhalb des App Store darstellen 4 NSString * ituneslink 5 [[UIApplication sharedapplication] withobject:[nsurl URLWithString:iTunesLink] afterdelay:2]; Listing 8.11: Zeitverzögerte Ausführung eines App-Store-Aufrufes und Protokollierung dessen. Die auf diese Art und Weise gesammelten statistischen Daten können beispielsweise unter Verwendung der in Kapitel 7 genannten geografischen Datenbank aufbereitet und visualisiert werden. Dies erlaubt die Lokalisierung der Herkunftsländer bzw. Herkunftsstädte der Besucher und die Berücksichtigung dieser bei der Erzeugung von Statistiken. Betrachtet man diese statistischen Daten im Kontrast zur Anzahl der Applikationsdownloads, können weiträumige Rückschlüsse auf mögliche Probleme innerhalb des Konzepts der Lite-Version gezogen werden. Abbildung 8.6 zeigt eine exemplarische Implementierung dieser Methodik unter Verwendung der Google Chart API. 154

171 8.4. Erfassung von Interessentenstatistiken Abbildung 8.6.: Exemplarische Implementierung einer Interessentenstatistik mit geografischer Zuordnung der Herkunftsländer. 155

172 8. Integration von In-App-Purchases in iphone- und Webapplikation 8.5. Fazit Autor: Dominik Wilhelm Die Erweiterung der Applikation durch In-App-Purchase-Produkte bietet eine zusätzliche Einnahmequelle. Die Integration eines Stores sowie der Kauffunktionalität kann bei konsumierbaren und dauerhaft freigeschalteten Produkten je nach Anwendung recht einfach erfolgen. Bei abonnierbaren Produkten müssen die Laufzeiten dieser jedoch manuell verwaltet und sichergestellt werden. Für die Bereitstellung von abonnierbaren Onlinefeatures müssen die Zahlungstransaktionen über den App Store abgewickelt werden. Dies bedeutet, dass sowohl iphone als auch Webserver für den Kauf miteinander kommunizieren müssen. Dieser Prozess birgt viele mögliche Fehlersituationen, die sowohl aufseiten des Webservice als auch aufseiten der iphone-applikation berücksichtigt und abgedeckt werden müssen. In-App-Purchase-Produkte sind nicht auf kostenpflichtige Applikationen begrenzt, sondern können auch in kostenlose Programme integriert werden. Somit kann ein gewisser Kundenkreis durch die Bereitstellung einer kostenlosen Applikation aufgebaut und das Geld letztendlich über die kostenpflichtigen Zusatzprodukte verdient werden. Durch Integration eines App-Store-Links in die Lite-Version können potenzielle Interessenten zum Kauf der kostenpflichtigen Version animiert werden. Bei Benachrichtigung eines Statistikservers über den Aufruf dieses Hyperlinks kann recht einfach eine Statistik über mögliche Interessenten erstellt und aufbereitet werden. Diese gibt Aufschluss über das Interesse an der kostenpflichtigen Version und wurde in Abschnitt 8.4 weiter erläutert. 156

173 KAPITEL 9 Schlussbetrachtung Die Entwicklung von iphone-applikationen ist, wie sich im Verlaufe der vorliegenden Arbeit gezeigt hat, mit vielen Herausforderungen verbunden und vor der Umsetzung einer Applikation müssen viele verschiedene Technologien bei der Planung sowie innerhalb der Entwicklungsprozesse berücksichtigt werden. So muss die Programmiersprache Objective-C studiert und die dynamischen Elemente möglichst geschickt in die Umsetzung von Applikationen mit einbezogen werden. Auch wenn diese zusammen mit dem Foundation-Framework eine sehr solide Grundlage für die Entwicklung bietet, ist die Meisterung der Entwicklungsprozesse keine einfache Angelegenheit und setzt hohe Ansprüche an Entwickler respektive Softwaretechniker. Das vorgestellte Framework UIKit und sämtliche für die iphone-entwicklung bereitgestellten Bibliotheken legen großen Wert auf die Nutzung von softwaretechnischen Entwurfsmustern und verlangen deren prinzipientreue Adaptierung. Auch wenn die Lernkurve hierbei zunächst sehr langsam ansteigt, zahlt sich das Ergebnis letztendlich durch eine wartbare und gut erweiterbare Softwarearchitektur aus. Dies trifft besonders dann zu, wenn die vorgestellten Entwurfsmuster in den eigens entwickelten Klassen berücksichtigt werden. Die für die Entwicklung bereitgestellten Frameworks und Werkzeuge haben sich als sehr Autoren: Benjamin Glatzel Dominik Wilhelm 157

174 9. Schlussbetrachtung mächtig erwiesen und konnten stets zu sehr guten und meist sehr einfachen Lösungen bei der Entwicklung von komplexen Problemen verwendet werden. Dennoch hat sich sowohl bei der Erstellung des Datenmodells sowie der Entwicklung eines angepassten Benutzerinterfaces gezeigt, dass die Ressourcen des iphone keineswegs unbegrenzt sind. Je nach gesetzten Zielen und Komplexität der Software müssen Umwege bei der Entwicklung eingeschlagen werden, um die Darstellungseffizienz jederzeit zu gewährleisten und den Endbenutzer einen möglichst reibungslosen Programmablauf zu präsentieren. Das für die Webentwicklung vorgestellte Web-2.0-Framework Ruby on Rails hat sich sowohl für die Entwicklung einer Webapplikation als auch für die Bereitstellung einer Webserviceschnittstelle für die iphone-applikation geeignet, die auf beiden Seiten durch Einsatz leichtgewichtiger Technologien (nach dem Web-2.0-Konzept) integriert und genutzt werden kann. Durch die Beherzigung des vorgestellten Web-2.0-Konzepts sowie der von Ruby on Rails vorgestellten Paradigmen, können Applikationen entwickelt werden, die selbst nach langer Zeit noch gut verständlich und ergänzbar sind. Dennoch haben die vorgestellten Techniken und Ergebnisse ihre Grenzen aufgezeigt. Während die iphone-applikation beispielsweise in vielerlei Hinsicht weiter optimiert und erweitert werden könnte, sind vor allem die entwickelte Webserviceschnittstelle und die bereitgestellte Funktionalität der Webapplikation verbesserungswürdig. Die von der iphone-applikation übertragenen Daten können aufseiten der Webapplikation lediglich angesehen und gelöscht werden. Eine Bearbeitung oder Modifikation einzelner Elemente ist aufgrund des Konzepts der Übertragung zunächst nur schwer zu implementieren. An dieser Stelle wäre eine beidseitige Synchronisation von iphone- und Webapplikation wünschenswert. Innerhalb der Arbeit wurden hierzu erste Ansätze genannt und die Nutzung des REST-Konzepts als Webserviceschnittstelle vorgeschlagen. Für die Bereitstellung einer beidseitigen Synchronisation des Datenbestands sind derzeit, zumindest bei der Verwendung von Core Data als Persistenzmanager, keine Frameworks bekannt, die diese Problematik ohne manuelle Implementierung eines entsprechenden Synchronisationsmechanismus übernehmen. Die Entwicklung von iphone-applikation konnte innerhalb dieser Arbeit lediglich anhand von Themenschwerpunkten skizziert werden und die Thematik birgt viele weitere interessante Aspekte. Mit der Veröffentlichung des iphone 4 und des neuen Betriebssystems ios 4 steht bereits die nächste Epoche der iphone-app-entwicklung in den Startlöchern, mit der über neue Programmierschnittstellen sowie neue 158

175 Technologien innerhalb des Endgeräts bereitgestellt werden (vgl. zu diesem Abschnitt [App10b]). Neben der Möglichkeit zwischen aktiven Programmen umzuschalten, wurde unter anderem ein 3-Achsen-Gyrosensor in das Gerät integriert, der die genaue Ausrichtung und Beschleunigung des Geräts über die neue Core-Motion-API erkennen lässt. In Zukunft können somit wiederum neue Wege bei der Entwicklung eingeschlagen und die neuen Technologien beispielsweise für die Bereitstellung hoch interaktiver Spiele und Benutzeroberflächen genutzt werden. 159

176

177 Appendices 161

178

179 ANHANG A Bildschirmfotos von wetravel und wetravel online (a) Das Hauptmenü (b) Die Teilnehmerübersicht Abbildung A.1.: Bildschirmfotos der iphone-applikation wetravel. 163

180 A. Bildschirmfotos von wetravel und wetravel online (a) Die Kontostandsübersicht (b) Die Geldwechselübersicht Abbildung A.2.: Weitere Bildschirmfotos der iphone-applikation wetravel. (a) Die Buchungsliste (b) Die Kartenansicht Abbildung A.3.: Weitere Bildschirmfotos der iphone-applikation wetravel. 164

181 (a) Erzeugung einer Buchung (b) Individuelle Verteilung von Buchungsbeträgen Abbildung A.4.: Weitere Bildschirmfotos der iphone-applikation wetravel. 165

Programmieren für iphone und ipad

Programmieren für iphone und ipad Markus Stäuble Programmieren für iphone und ipad Einstieg in die App-Entwicklung für das ios 4 3., aktualisierte und erweiterte Auflage dpunkt.verlag 1 Einleitung 1 1.1 Begriffe 2 1.2 Was behandelt dieses

Mehr

Glossar. Launching auf.

Glossar. Launching auf. 243 Ad Hoc Distribution Die Ad Hoc Distribution ist eine Möglichkeit, um Ihre entwickelte Anwendung auf anderen Endgeräten zu verteilen. Diese Art der Verteilung erfolgt ohne den App Store. Die Anzahl

Mehr

Willkommen zur Vorlesung. Objektorientierte Programmierung Vertiefung - Java

Willkommen zur Vorlesung. Objektorientierte Programmierung Vertiefung - Java Willkommen zur Vorlesung Objektorientierte Programmierung Vertiefung - Java Zum Dozenten Mein Name: Andreas Berndt Diplom-Informatiker (TU Darmstadt) Derzeit Software-Entwickler für Web- Applikationen

Mehr

iphone developer conference Die Entwickler- und Buiness- Konferenz für iphone, ipad und ipod touch

iphone developer conference Die Entwickler- und Buiness- Konferenz für iphone, ipad und ipod touch iphone developer conference Die Entwickler- und Buiness- Konferenz für iphone, ipad und ipod touch ios - Wo steht es, wie geht es? Markus Stäuble MRM Worldwide GmbH 1 Feedback #ipdc10 #as 2 Agenda 3 Heute:

Mehr

3.9 Grundelemente einer Benutzeroberfläche

3.9 Grundelemente einer Benutzeroberfläche 92 3 Grundlagen einer ios-anwendung 3.8.4 Target-Actions Einer der häufigsten Anwendungsfälle bei einer Oberfläche ist das Betätigen einer Schaltfläche durch einen Anwender, woraufhin eine bestimmte Aktion

Mehr

Ruby on Rails. Florian Ferrano Ralf Heller Markus Nagel

Ruby on Rails. Florian Ferrano Ralf Heller Markus Nagel Ruby on Rails Florian Ferrano Ralf Heller Markus Nagel Überblick Ruby on Rails Ruby Rails Geschichte MVC allgemein MVC in Rails Scaffolding Webserver Installation Beispiele Wo wird Rails verwendet? Ausblick

Mehr

Sachwortverzeichnis... 251

Sachwortverzeichnis... 251 Inhalt Vorwort... V 1 WWW World Wide Web... 1 1.1 Das Internet Infrastruktur und Administration... 2 1.2 Datenübertragung... 4 1.3 Sprachen im Web... 6 1.4 Webseiten... 7 1.4.1 Clientseitige Dynamik...

Mehr

1. Software-Plattform Android Android. Was ist Android? Bibliotheken, Laufzeitumgebung, Application Framework

1. Software-Plattform Android Android. Was ist Android? Bibliotheken, Laufzeitumgebung, Application Framework 1. Software-Plattform Android Android Was ist Android? Plattform und Betriebssystem für mobile Geräte (Smartphones, Mobiltelefone, Netbooks), Open-Source Linux-Kernel 2.6 Managed Code, Angepasste Java

Mehr

Cross-Platform Apps mit HTML5/JS/CSS/PhoneGap

Cross-Platform Apps mit HTML5/JS/CSS/PhoneGap Cross-Platform Apps mit HTML5/JS/CSS/PhoneGap Proseminar Objektorientiertes Programmieren mit.net und C# Florian Schulz Institut für Informatik Software & Systems Engineering Einführung Was hat Cross-Plattform

Mehr

Dataport IT Bildungs- und Beratungszentrum. HTML- Grundlagen und CSS... 2. XML Programmierung - Grundlagen... 3. PHP Programmierung - Grundlagen...

Dataport IT Bildungs- und Beratungszentrum. HTML- Grundlagen und CSS... 2. XML Programmierung - Grundlagen... 3. PHP Programmierung - Grundlagen... Inhalt HTML- Grundlagen und CSS... 2 XML Programmierung - Grundlagen... 3 PHP Programmierung - Grundlagen... 4 Java - Grundlagen... 5 Java Aufbau... 6 ASP.NET Programmierung - Grundlagen... 7 1 HTML- Grundlagen

Mehr

3. Konzepte der objektorientierten Programmierung

3. Konzepte der objektorientierten Programmierung 3. Konzepte der objektorientierten Programmierung 3.1 Basiskonzepte 3.2 Generalisierung / Spezialisierung 3.3 Aggregation 3.4 Assoziation 3.5 Nachrichten 3.6 Polymorphismus 3. Konzepte der Objektorientierung

Mehr

Hochschule Darmstadt Fachbereich Informatik

Hochschule Darmstadt Fachbereich Informatik Hochschule Darmstadt Fachbereich Informatik 6.3 Systemarchitektur 430 6.3 Systemarchitektur Drei Schichten Architektur Die "Standardtechniken" des Software-Engineering sind auch auf die Architektur einer

Mehr

Entwicklung und Integration mobiler Anwendungen. Oracle Deutschland B.V. & Co. KG

Entwicklung und Integration mobiler Anwendungen. <Speaker> Oracle Deutschland B.V. & Co. KG Entwicklung und Integration mobiler Anwendungen Oracle Deutschland B.V. & Co. KG Global Users (Millions) Der Trend ist eindeutig. Trend zu mobilen Endgeräten Wachstum des mobilen Datenverkehrs

Mehr

1. Software-Plattform Android Android. Was ist Android? Managed Code, Angepasste Java Virtual Machine

1. Software-Plattform Android Android. Was ist Android? Managed Code, Angepasste Java Virtual Machine 1. Software-Plattform Android Android Was ist Android? Plattform und Betriebssystem für mobile Geräte (Smartphones, Mobiltelefone, Netbooks), Open-Source Linux-Kernel ab 2.6, aktuell 3.8 Managed Code,

Mehr

Created by Angelo Maron

Created by Angelo Maron Domain Driven Design in Ruby on Rails Created by Angelo Maron Wer bin ich? Angelo Maron Sofware-Entwickler seit ca. 7 Jahren (Ruby on Rails) bei AKRA seit 2,5 Jahren Xing: https://www.xing.com/profile/angelo_maron

Mehr

Client/Server-Systeme

Client/Server-Systeme Fachbereich Informatik Projektgruppe KOSI Kooperative Spiele im Internet Client/Server-Systeme Vortragender Jan-Ole Janssen 26. November 2000 Übersicht Teil 1 Das Client/Server-Konzept Teil 2 Client/Server-Architekturen

Mehr

VDLUFA-Schriftenreihe 1

VDLUFA-Schriftenreihe 1 VDLUFA-Schriftenreihe 1 Wie viele Apps sind ein LIMS? J. Flekna Pragmatis GmbH, Neufahrn 1. Einleitung Seitdem mobile Endgeräte massentauglich sind, ist die Bezeichnung App fester Bestandteil unseres zeitgeistigen

Mehr

Softwaretechnik (Medieninformatik) Überblick: 6. Objektorientiertes Design

Softwaretechnik (Medieninformatik) Überblick: 6. Objektorientiertes Design Softwaretechnik (Medieninformatik) Überblick: 6.1 Einleitung 6.2 Verfeinerung des Klassenmodells 6.3 Sequenzdiagramme 6.4 Umsetzung der Analysekonstrukte in das Design 6.5 Fallstudie 6.6 Software Kontrakte

Mehr

Architekturen mobiler Multi Plattform Apps

Architekturen mobiler Multi Plattform Apps Architekturen mobiler Multi Plattform Apps Wolfgang Maison & Felix Willnecker 06. Dezember 2011 1 Warum Multi- Plattform- Architekturen? Markt. Apps für Smartphones gehören zum Standardinventar jeder guten

Mehr

Rechnernetze Projekt SS 2015

Rechnernetze Projekt SS 2015 30/03/15 Seite 1 Aspektorientierte Programmierung logische Aspekte (Concerns) im Programm separieren Crosscutting Concerns (Ziel: generische Funktionalitäten über mehrere Klassen hinweg zu verwenden -

Mehr

09.06.2003 André Maurer andre@maurer.name www.andre.maurer.name Wirtschaftsinformatik FH 3.5 Fachhochschule Solothurn, Olten

09.06.2003 André Maurer andre@maurer.name www.andre.maurer.name Wirtschaftsinformatik FH 3.5 Fachhochschule Solothurn, Olten Aktuelle Themen der Wirtschaftsinformatik Zusammenfassung 09.06.2003 André Maurer andre@maurer.name www.andre.maurer.name Wirtschaftsinformatik FH 3.5 Fachhochschule Solothurn, Olten 1 Serverseitige Webprogrammierung

Mehr

App-Entwicklung mit Titanium

App-Entwicklung mit Titanium Masterstudienarbeit Betreuung Prof. Dr. M. von Schwerin 1 Gliederung 1.Motivation 2.Aufgabenstellung 3.Projektbeschreibung 4.Projektstatusbericht 5.Fazit und Ausblick 2 1.Motivation Verbreitung von Smartphones

Mehr

So#ware- Engineering für mobile Systeme. paluno

So#ware- Engineering für mobile Systeme. paluno So#ware- Engineering für mobile Systeme Gliederung 1 Grundlagen 2 Grundlagen der Anwendungsentwicklung für Android 3 Grundlagen der Anwendungsentwicklung für ios 4 KommunikaBon mit Netzwerken 5 MulBthreading

Mehr

Programmieren im Web 2.x

Programmieren im Web 2.x Programmieren im Web 2.x Ein Überblick über die Webentwicklung im Jahre 2011 Johannes Leers 26. März 2012 1 Motivation 2 Web-Frameworks 3 Mobile Computing 4 WebGL 5 Cloud Computing 6 Fazit Native Programme

Mehr

Mobile: Die Königsfrage

Mobile: Die Königsfrage Mobile: Die Königsfrage - Native App,Mobile Website oder doch Responsive Design? - Native App oder Mobile Website? Wer am Boom der mobilen Anwendungen teilhaben möchte, hat im Prinzip zwei Möglichkeiten:

Mehr

App-Entwicklung für Android

App-Entwicklung für Android App-Entwicklung für Android Einleitung - Systemarchitektur Hochschule Darmstadt WS15/16 1 Inhalt Historie Systemarchitektur Sandbox 2 Motivation Kontra Pro Limitierte Größe Begrenzte Ressourcen Kein Standardgerät

Mehr

GIS mit Ruby on Rails

GIS mit Ruby on Rails FOSSGIS 2010 Pirmin Kalberer Sourcepole AG, Bad Ragaz www.sourcepole.ch ./configure && make && make install apt-get install postgis XML, SOAP Http, REST CVS git Linux? Linux! RUP Agile Software- Entwicklung

Mehr

Präsentation Von Laura Baake und Janina Schwemer

Präsentation Von Laura Baake und Janina Schwemer Präsentation Von Laura Baake und Janina Schwemer Gliederung Einleitung Verschiedene Betriebssysteme Was ist ein Framework? App-Entwicklung App-Arten Möglichkeiten und Einschränkungen der App-Entwicklung

Mehr

Smartphone - Betriebssysteme. Smartphone - Betriebssysteme

Smartphone - Betriebssysteme. Smartphone - Betriebssysteme Smartphone - Betriebssysteme Peter Rami - Graz, 28.04.2009 Inhalt Smartphone Symbian OS Windows Mobile BlackBerry OS iphone OS Android Marktanteile & Ausblick Smartphone - Betriebssysteme Peter Rami -

Mehr

Mac OS X Programmierung

Mac OS X Programmierung Mac OS X Programmierung Eine Einführung in Cocoa, Objective-C und Xcode Christina Zeeh Mac User Group Stuttgart 17.08.2004 Überblick Erster Teil Softwareentwicklung für Mac OS X - ein Überblick Objektorientierung

Mehr

Web und Mobile Apps Programmieren mit Dart

Web und Mobile Apps Programmieren mit Dart Web und Mobile Apps Programmieren mit Dart Marco Jakob Kalaidos Fachhochschule Schweiz majakob@gmx.ch Abstract: Bisher war es kaum realistisch, im Anfängerunterricht mobile oder webbasierte Applikationen

Mehr

Einführung in die Cross-Plattform Entwicklung Das Intel App Framework

Einführung in die Cross-Plattform Entwicklung Das Intel App Framework Einführung in die Cross-Plattform Entwicklung Das Intel App Framework Einführung Dieses Hands-on-Lab (HOL) macht den Leser mit dem Intel App Framework vom Intel XDK vertraut. Es wird Schritt für Schritt

Mehr

Programmieren in Java

Programmieren in Java Programmieren in Java objektorientierte Programmierung 2 2 Zusammenhang Klasse-Datei In jeder *.java Datei kann es genau eine public-klasse geben wobei Klassen- und Dateiname übereinstimmen. Es können

Mehr

Inhaltsverzeichnis. Teil 1 Node.js... 1

Inhaltsverzeichnis. Teil 1 Node.js... 1 xiii Teil 1 Node.js... 1 1 Was ist Node.js? 3 1.1 Die Zeitalter des Webs................................... 3 1.1.1 1990 bis 2000: Das Web 1.0....................... 3 1.1.2 2000 bis 2010: Das Web 2.0.......................

Mehr

Internettechnologien

Internettechnologien Internettechnologien Vorlesung für Master-Studierende Geoinformation und -management Sommersemester 2012 Prof. Dr.-Ing. habil. Peter Sobe Fakultät Informatik / Mathematik Dieser Foliensatz basiert z.t.

Mehr

Geschäftsbereich Mobile Services Was ist Android?

Geschäftsbereich Mobile Services Was ist Android? Geschäftsbereich Mobile Services Was ist Android? Hinter Hoben 149 53129 Bonn www.visionera.de Ansprechpartner: Arno Becker arno.becker@visionera.de +49 228 555 1111 +49 160 98965856 Einleitung Android

Mehr

NEXT GENERATION MOBILE PHONE PLATFORMS

NEXT GENERATION MOBILE PHONE PLATFORMS Stephan Zeisberg NEXT GENERATION MOBILE PHONE PLATFORMS Ein Einblick in die Systemarchitekturen aktueller Smartphones 1 Motivation Technologischer Stillstand in der Entwicklung mobiler Betriebssysteme

Mehr

Vorwort... 11 Azure Cloud Computing mit Microsoft... 12 Danksagungen... 13 Kontakt zum Autor... 13

Vorwort... 11 Azure Cloud Computing mit Microsoft... 12 Danksagungen... 13 Kontakt zum Autor... 13 Inhaltsverzeichnis Vorwort... 11 Azure Cloud Computing mit Microsoft... 12 Danksagungen... 13 Kontakt zum Autor... 13 Einleitung... 15 Zielgruppe... 16 Aufbau... 16 Inhalt der einzelnen Kapitel... 17 Systemanforderungen...

Mehr

Groovy on Grails. Informatik-Seminar WS06/07. Alexander Treptow. Groovy on Grails Alexander Treptow (minf2622) 1

Groovy on Grails. Informatik-Seminar WS06/07. Alexander Treptow. Groovy on Grails Alexander Treptow (minf2622) 1 Groovy on Grails Informatik-Seminar WS06/07 Alexander Treptow Groovy on Grails Alexander Treptow (minf2622) 1 Übersicht Groovy on Grails Projektstruktur Controllers Views & Layout Dynamic Tag Libraries

Mehr

JavaScript Frameworks für Mobile

JavaScript Frameworks für Mobile JavaScript Frameworks für Mobile MoBI Expertenrunde Usability, 1. März 2012 doctima GmbH JavaScript Frameworks für Mobile MoBI 1.3.2012 Edgar Hellfritsch Inhalt Native App-Entwicklung Klassische Web-Entwicklung

Mehr

Design Patterns. 5. Juni 2013

Design Patterns. 5. Juni 2013 Design Patterns 5. Juni 2013 Überblick Was sind Design Patterns? Welche Design Patterns gibt es? Wann sollte man Design Patterns einsetzen? Refactoring und Design Patterns: Welchen Zusammenhang gibt es

Mehr

E-Books produzieren und publizieren

E-Books produzieren und publizieren E-Books produzieren und publizieren Bruno Wenk Hochschule für Technik und Wirtschaft HTW Chur Leipzig, 24. Oktober 2012 Seite 1 Ziel Mit kostenlosen Programmen ein E-Book im Format EPUB (2.01) realisieren

Mehr

Smartphone Entwicklung mit Android und Java

Smartphone Entwicklung mit Android und Java Smartphone Entwicklung mit Android und Java predic8 GmbH Moltkestr. 40 53173 Bonn Tel: (0228)5552576-0 www.predic8.de info@predic8.de Was ist Android Offene Plattform für mobile Geräte Software Kompletter

Mehr

AJAX SSL- Wizard Referenz

AJAX SSL- Wizard Referenz AJAX SSL- Wizard Referenz Version 1.0.2+ - 04.04.2011 Präambel Die vorliegende Dokumentation beschreibt den AJAX basierten SSL- Wizard der CertCenter AG. Der SSL- Wizard kann mit wenigen Handgriffen nahtlos

Mehr

7 Plugins einbinden. 7.1 Beispiel»Die Taschenlampe«

7 Plugins einbinden. 7.1 Beispiel»Die Taschenlampe« 201 PhoneGap bringt einen standardisierten Hardwarezugriff für Smartphones mit. Aber was passiert, wenn Sie mehr wollen: Wenn Sie eine Hardware per Bluetooth ansprechen wollen oder Features der jeweiligen

Mehr

HERZLICH WILLKOMMEN SHAREPOINT 2013 DEEP DIVE - APPS 11.09.2012 IOZ AG 1

HERZLICH WILLKOMMEN SHAREPOINT 2013 DEEP DIVE - APPS 11.09.2012 IOZ AG 1 HERZLICH WILLKOMMEN SHAREPOINT 2013 DEEP DIVE - APPS 11.09.2012 IOZ AG 1 AGENDA Einführung Apps - Einführung Apps Architektur SharePoint-Hosted Apps Cloud-Hosted Apps Ausblick 11.09.2012 IOZ AG 2 ÜBER

Mehr

Modellgetriebene Entwicklungsprozesse in der Praxis - eine Bestandsaufnahme. Tillmann Schall, anaptecs GmbH

Modellgetriebene Entwicklungsprozesse in der Praxis - eine Bestandsaufnahme. Tillmann Schall, anaptecs GmbH Modellgetriebene Entwicklungsprozesse in der Praxis - eine Bestandsaufnahme Tillmann Schall, anaptecs GmbH : Agenda Grundlagen modellgetriebener Entwicklungsprozesse Schritte zur Einführung Erfahrungen

Mehr

Agenda. Ingo Ebel (ie007) Benjamin Müller (bm032) Was ist AJAX? Sicherheit Vor- und Nachteile. AJAX Frameworks. Wozu benötigt Client/Server

Agenda. Ingo Ebel (ie007) Benjamin Müller (bm032) Was ist AJAX? Sicherheit Vor- und Nachteile. AJAX Frameworks. Wozu benötigt Client/Server AJAX Agenda Ingo Ebel (ie007) Was ist AJAX? Wozu benötigt Client/Server Sicherheit Vor- und Nachteile Benjamin Müller (bm032) AJAX Frameworks GWT ATF Ingo Ebel - ie007 2 Web 2.0 Ingo Ebel - ie007 3 Ingo

Mehr

Technische Beschreibung: EPOD Server

Technische Beschreibung: EPOD Server EPOD Encrypted Private Online Disc Technische Beschreibung: EPOD Server Fördergeber Förderprogramm Fördernehmer Projektleitung Projekt Metadaten Internet Foundation Austria netidee JKU Linz Institut für

Mehr

MOBILE ENTERPRISE APPLICATION PLATFORM (MEAP)

MOBILE ENTERPRISE APPLICATION PLATFORM (MEAP) MOBILE ENTERPRISE APPLICATION PLATFORM (MEAP) Oliver Steinhauer.mobile PROFI Mobile Business Agenda MOBILE ENTERPRISE APPLICATION PLATFORM AGENDA 01 Mobile Enterprise Application Platform 02 PROFI News

Mehr

Remote Communications

Remote Communications HELP.BCFESDEI Release 4.6C SAP AG Copyright Copyright 2001 SAP AG. Alle Rechte vorbehalten. Weitergabe und Vervielfältigung dieser Publikation oder von Teilen daraus sind, zu welchem Zweck und in welcher

Mehr

ANDROID. Analyse der Android Plattform. Andre Rein, Johannes Florian Tietje. 28. Oktober 2010. FH-Gieÿen-Friedberg Android Praktikum

ANDROID. Analyse der Android Plattform. Andre Rein, Johannes Florian Tietje. 28. Oktober 2010. FH-Gieÿen-Friedberg Android Praktikum Analyse der Android Plattform Andre Rein, Johannes Florian Tietje FH-Gieÿen-Friedberg Android Praktikum 28. Oktober 2010 Topics 1 Übersicht Android Plattform Application Framework Activities und Services

Mehr

Web 2.0 Architekturen und Frameworks

Web 2.0 Architekturen und Frameworks Web 2.0 Architekturen und Frameworks codecentric GmbH Mirko Novakovic codecentric GmbH Quality Technische Qualitätssicherung in Software-Projekten mit Fokus auf Performance, Verfügbarkeit und Wartbarkeit

Mehr

Holger Hinzberg. iphone Apps programmieren. Praxiseinstieg. mitp

Holger Hinzberg. iphone Apps programmieren. Praxiseinstieg. mitp Holger Hinzberg iphone Apps programmieren Praxiseinstieg mitp View Controller Einleitung 13 1 Grlagen von ObjectiveC 21 1.1 Stilmittel in den Listings 21 1.2 Kommentare 22 1.3 ObjectiveC kann C 23 1.4

Mehr

Java Einführung Programmcode

Java Einführung Programmcode Java Einführung Programmcode Inhalt dieser Einheit Programmelemente Der erste Programmcode Die Entwicklungsumgebung: Sun's Java Software Development Kit (SDK) Vom Code zum Ausführen des Programms 2 Wiederholung:

Mehr

Datenbank-basierte Webserver

Datenbank-basierte Webserver Datenbank-basierte Webserver Datenbank-Funktion steht im Vordergrund Web-Schnittstelle für Eingabe, Wartung oder Ausgabe von Daten Datenbank läuft im Hintergrund und liefert Daten für bestimmte Seiten

Mehr

LDAP verstehen, OpenLDAP einsetzen

LDAP verstehen, OpenLDAP einsetzen Dieter Klünter Jochen Laser LDAP verstehen, OpenLDAP einsetzen Grundlagen, Praxiseinsatz und Single-sign-on-Mechanismen Technische Universität Darmstadt FACHBEREICH INFORMATIK Invanter-Nr, J Standort:

Mehr

ARCHIBUS IWMS Lösung vom Weltmarktführer

ARCHIBUS IWMS Lösung vom Weltmarktführer ARCHIBUS IWMS Lösung vom Weltmarktführer ARCHIBUS User Meeting 12.+13.5.2015 in München 2009 ARCHIBUS, Inc. All rights reserved. Was machen mobile App s so Interessant? Vorteil Mobile Platform & Apps 3

Mehr

Modul 2.4.1: Möglichkeiten zur Erweiterung des Internet-Auftritts der Schule zu einem umfassenden Auftritt als Bildungsnetzwerk

Modul 2.4.1: Möglichkeiten zur Erweiterung des Internet-Auftritts der Schule zu einem umfassenden Auftritt als Bildungsnetzwerk Informationsmaterial zum Modul-Nr. 2.4: Bildungsnetzwerke planen (Schwerpunkt: IT-Unterstützung in Bildungsnetzwerken) Modul 2.4.1: Möglichkeiten zur Erweiterung des Internet-Auftritts der Schule zu einem

Mehr

MOBILE ENTERPRISE APPLICATION PLATFORM (MEAP)

MOBILE ENTERPRISE APPLICATION PLATFORM (MEAP) MOBILE ENTERPRISE APPLICATION PLATFORM (MEAP) Oliver Steinhauer Markus Urban.mobile PROFI Mobile Business Agenda MOBILE ENTERPRISE APPLICATION PLATFORM AGENDA 01 Mobile Enterprise Application Platform

Mehr

Eine Taxonomie und Bewertung von Cloud Computing Diensten aus Entwicklersicht

Eine Taxonomie und Bewertung von Cloud Computing Diensten aus Entwicklersicht Eine Taxonomie und Bewertung von Cloud Computing Diensten aus Entwicklersicht Universität der Bundeswehr München Mario Golling und Michael Kretzschmar Fakultät für Informatik E-Mail: mario.golling@unibw.de

Mehr

Liste der Handbücher. Liste der Benutzerhandbücher von MEGA

Liste der Handbücher. Liste der Benutzerhandbücher von MEGA Liste der Handbücher Liste der Benutzerhandbücher von MEGA MEGA 2009 SP4 1. Ausgabe (Juni 2010) Die in diesem Dokument enthaltenen Informationen können jederzeit ohne vorherige Ankündigung geändert werden

Mehr

TECHNISCHE PRODUKTINFORMATION CARUSO

TECHNISCHE PRODUKTINFORMATION CARUSO 1111 TECHNISCHE PRODUKTINFORMATION CARUSO TECHNISCHE PRODUKTINFORMATION Seite 0/7 Inhalt 1 Systemdefinition............2 2 Technische Details für den Betrieb von CARUSO......2 2.1 Webserver... 2 2.2 Java

Mehr

App Entwicklung mit Hilfe von Phonegap. Web Advanced II - SS 2012 Jennifer Beckmann

App Entwicklung mit Hilfe von Phonegap. Web Advanced II - SS 2012 Jennifer Beckmann App Entwicklung mit Hilfe von Phonegap Web Advanced II - SS 2012 Jennifer Beckmann http://www.focus.de/digital/internet/netzoekonomie-blog/smartphone-googles-android-laeuft-konkurrenz-in-deutschland-davon_aid_723544.html

Mehr

Integration Services - Dienstarchitektur

Integration Services - Dienstarchitektur Integration Services - Dienstarchitektur Integration Services - Dienstarchitektur Dieser Artikel solle dabei unterstützen, Integration Services in Microsoft SQL Server be sser zu verstehen und damit die

Mehr

1. Java ist... 2. Stammbaum der Programmiersprachen 3. Die "Softwarekrise"

1. Java ist... 2. Stammbaum der Programmiersprachen 3. Die Softwarekrise im Überblick im Überblick Inhalt 1. Java ist... 2. Stammbaum der Programmiersprachen 3. Die Softwarekrise 1. Merkmale von Software 2. Fortlaufende Veränderungen 3. Erschwerte Rahmenbedingungen bei der

Mehr

Inhaltsverzeichnis. Hinweise zum Gebrauch des Buches... XIII. Teil I Grundlagen der Web-Programmierung

Inhaltsverzeichnis. Hinweise zum Gebrauch des Buches... XIII. Teil I Grundlagen der Web-Programmierung Hinweise zum Gebrauch des Buches... XIII Teil I Grundlagen der Web-Programmierung 1 Entwicklung der Web-Programmierung... 3 1.1 DerWegzumWorldWideWeb... 3 1.2 Komponenten der frühen Technik..... 5 1.3

Mehr

RUBY ON RAILS. Markus Knofe. Informatik-Seminar WS 06/07 Ruby on Rails - Markus Knofe (minf2434)

RUBY ON RAILS. Markus Knofe. Informatik-Seminar WS 06/07 Ruby on Rails - Markus Knofe (minf2434) RUBY ON RAILS Markus Knofe 1 Gliederung a) Was ist Rails b) MVC in Rails c) Rails praktisch d) Fazit 2 Rails ist innovativ! 3 Rails ist innovativ! Rails ist elegant! 4 Rails ist innovativ! Rails ist elegant!

Mehr

Grundsätzliche Struktur und Entwurfsprinzipien des Gesamtsystems. Grundsätzliche Struktur und Entwurfsprinzipien der einzelnen Pakete

Grundsätzliche Struktur und Entwurfsprinzipien des Gesamtsystems. Grundsätzliche Struktur und Entwurfsprinzipien der einzelnen Pakete Allgemeines 2 Produktübersicht 2 Grundsätzliche Struktur und Entwurfsprinzipien des Gesamtsystems 3 Grundsätzliche Struktur und Entwurfsprinzipien der einzelnen Pakete Account-Verwaltung 5 Freund-Funktionen

Mehr

Moderne Benutzeroberflächen für SAP Anwendungen

Moderne Benutzeroberflächen für SAP Anwendungen Seite 1 objective partner für SAP Erfahrungen mit dem UI-Development Kit für HTML5 (SAPUI5) - 19.06.2012 Seite 2 Quick Facts objective partner AG Die objective partner AG 1995 gegründet mit Hauptsitz in

Mehr

Praktikum ios-entwicklung im Sommersemester 2015 Übungsblatt 3

Praktikum ios-entwicklung im Sommersemester 2015 Übungsblatt 3 Ludwig-Maximilians-Universität München Institut für Informatik Lehrstuhl für Mobile und Verteilte Systeme Prof. Dr. Claudia Linnhoff-Popien Praktikum ios-entwicklung im Sommersemester 2015 Übungsblatt

Mehr

Kapitel 6,»Objektorientierte Programmierung«, widmet sich der objektorientierten Programmierung mit Python.

Kapitel 6,»Objektorientierte Programmierung«, widmet sich der objektorientierten Programmierung mit Python. 1.3 Aufbau des Buchs lichkeiten offen. Auf die Unterschiede der beiden Versionen gehe ich besonders ein, sodass ein späterer Umstieg von der einen zur anderen Version leichtfällt. Erste Zusammenhänge werden

Mehr

Bin ich fit für myconvento?

Bin ich fit für myconvento? Bin ich fit für myconvento? Sie planen den Einsatz unserer innovativen Kommunikationslösung myconvento und fragen sich gerade, ob Ihr Rechner die Anforderungen erfüllt? Hier erfahren Sie mehr. Inhalt Was

Mehr

Antwortzeitverhalten von Online Storage Services im Vergleich

Antwortzeitverhalten von Online Storage Services im Vergleich EPOD Encrypted Private Online Disc Antwortzeitverhalten von Online Storage Services im Vergleich Fördergeber Förderprogramm Fördernehmer Projektleitung Projekt Metadaten Internet Foundation Austria netidee

Mehr

Ajax & GWT. Kurs: User Interfaces und ihre Evaluierung Dozent: Manfred Thaller WS 2012/2013 Referent: Rafael Kalina

Ajax & GWT. Kurs: User Interfaces und ihre Evaluierung Dozent: Manfred Thaller WS 2012/2013 Referent: Rafael Kalina Ajax & GWT Kurs: User Interfaces und ihre Evaluierung Dozent: Manfred Thaller WS 2012/2013 Referent: Rafael Kalina Ajax Technisches Verfahren, bei dem Browser aktualisierte Inhalte nicht mehr synchron

Mehr

User Forum 2014. FAMOS 4.1 FAMOS Web Portal. 13. FAMOS User Treffen Nino Turianskyj

User Forum 2014. FAMOS 4.1 FAMOS Web Portal. 13. FAMOS User Treffen Nino Turianskyj User Forum 2014 FAMOS 4.1 FAMOS Web Portal Nino Turianskyj ks Agenda FAMOS 4.1 FAMOS Web-Portal sonstiges ks Entwicklungsstrategie FAMOS FAMOS 4.x Full Client FAMOS Web Portal FAMOS mobil Release-Planung

Mehr

Diplomarbeit. Entwurf eines generischen Prozessleitstandes für Change Request Systeme

Diplomarbeit. Entwurf eines generischen Prozessleitstandes für Change Request Systeme Fakultät für Mathematik, Informatik und Naturwissenschaften Forschungsgruppe Softwarekonstruktion Diplomarbeit Entwurf eines generischen Prozessleitstandes für Change Request Systeme Development of a Generic

Mehr

3 Anwendungsarchitektur und Entwicklungsumgebung

3 Anwendungsarchitektur und Entwicklungsumgebung 21 3 Anwendungsarchitektur und Bei den Entwicklern von Web-basierten Dialogsystemen hat sich im Laufe der Zeit eine Vorgehensweise im Design von Anwendungen entwickelt, dies es ermöglicht, flexible Web-Dialoge

Mehr

Proseminar Website-Management-Systeme im Wintersemester 2003/2004 AG Softwaretechnik. PHP-Nuke. PHP-Nuke. von Andreas Emrich

Proseminar Website-Management-Systeme im Wintersemester 2003/2004 AG Softwaretechnik. PHP-Nuke. PHP-Nuke. von Andreas Emrich AG Softwaretechnik 1 Übersicht 1. Grundlagen und Konzepte 2. Komponenten von 3. Erweiterungsmöglichkeiten und Personalisierung 4. Abschließende Bewertung 5. Literaturangaben 2 1. : Grundlagen und Konzepte

Mehr

Um asynchrone Aufrufe zwischen Browser und Web Anwendung zu ermöglichen, die Ajax Hilfsmittel DWR ist gebraucht.

Um asynchrone Aufrufe zwischen Browser und Web Anwendung zu ermöglichen, die Ajax Hilfsmittel DWR ist gebraucht. Technisches Design Inhalt Design Übersicht Menü und DispatcherServlet DWR Servlet Viewer Servlets Controllers Managers Sicherheit Anwendung Architektur Component Diagram Deployment Diagram Komponente Sequence

Mehr

Inhaltsverzeichnis VII

Inhaltsverzeichnis VII Inhaltsverzeichnis 1 Einleitung & Grundlagen 1 1.1 Was behandeln wir in dem einleitenden Kapitel? 1 1.2 Die Welt von Java und JavaFX 2 1.2.1 Was ist Java? 2 1.2.2 Etwas zur Historie von Java 3 1.2.3 Wo

Mehr

Einführung in Android. 9. Dezember 2014

Einführung in Android. 9. Dezember 2014 Einführung in Android 9. Dezember 2014 Was ist Android? Software für mobile Geräte: Betriebssystem Middleware Kernanwendungen Android SDK: Tools und APIs zur Entwicklung von Anwendungen auf der Android-Plattform

Mehr

Eine App, viele Plattformen

Eine App, viele Plattformen Eine App, viele Plattformen Anwendungsentwicklung für Mobile Heiko Lewandowski 23.04.2013 EINLEITUNG Festlegung App-Strategie: Welche Ziele möchte ich erreichen? Die Vielzahl der Plattformen und Geräte(hersteller)

Mehr

TM1 mobile intelligence

TM1 mobile intelligence TM1 mobile intelligence TM1mobile ist eine hochportable, mobile Plattform State of the Art, realisiert als Mobile BI-Plug-In für IBM Cognos TM1 und konzipiert als Framework für die Realisierung anspruchsvoller

Mehr

ZenQuery - Enterprise Backend as a Service Single Page Applications mit AngularJS und Spring MVC. - Björn Wilmsmann -

ZenQuery - Enterprise Backend as a Service Single Page Applications mit AngularJS und Spring MVC. - Björn Wilmsmann - ZenQuery - Enterprise Backend as a Service Single Page Applications mit AngularJS und Spring MVC - Björn Wilmsmann - ZenQuery Enterprise Backend as a Service Unternehmen horten Daten in Silos ZenQuery

Mehr

Erstellung eines Frameworks für Shop Systeme im Internet auf Basis von Java

Erstellung eines Frameworks für Shop Systeme im Internet auf Basis von Java Erstellung eines Frameworks für Shop Systeme im Internet auf Basis von Java Präsentation zur Diplomarbeit von Übersicht Java 2 Enterprise Edition Java Servlets JavaServer Pages Enterprise JavaBeans Framework

Mehr

Plattformen mobiler Endgeräte Windows Phone, ios, Android

Plattformen mobiler Endgeräte Windows Phone, ios, Android Plattformen mobiler Endgeräte Windows Phone, ios, Android 13.12.2012 Inhaltsverzeichnis 1. Einführung 2. Ecosystem Smartphone OS 3. Mobile Software Platform 4. Android App Entwicklung 5. Zusammenfassung

Mehr

LINQ to SQL. Proseminar Objektorientiertes Programmieren mit.net und C# Christoph Knüttel. Institut für Informatik Software & Systems Engineering

LINQ to SQL. Proseminar Objektorientiertes Programmieren mit.net und C# Christoph Knüttel. Institut für Informatik Software & Systems Engineering LINQ to SQL Proseminar Objektorientiertes Programmieren mit.net und C# Christoph Knüttel Institut für Informatik Software & Systems Engineering Agenda 1. LINQ allgemein Vorteile Bausteine und Varianten

Mehr

Programmieren für mobile Endgeräte SS 2013/2014. Dozenten: Patrick Förster, Michael Hasseler

Programmieren für mobile Endgeräte SS 2013/2014. Dozenten: Patrick Förster, Michael Hasseler Programmieren für mobile Endgeräte SS 2013/2014 Programmieren für mobile Endgeräte 2 Besprechung der Aufgaben 1) Legen Sie das Android-Projekt HelloWorldApp an so wie es in den vorherigen Folien beschrieben

Mehr

Design Pattern - Strukturmuster. CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi

Design Pattern - Strukturmuster. CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi Design Pattern - Strukturmuster CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi Agenda Einleitung Strukturmuster Fassade Model View Controller Vergleich 2 Einleitung Strukturmuster

Mehr

APPS FÜR ANDROID ENTWICKELN

APPS FÜR ANDROID ENTWICKELN jan TITTEL jochen BAUMANN ELL N H C S IEG T S N I E APPS FÜR ANDROID ENTWICKELN AM BEISPIEL EINER REALEN APP Inhalt 1 Einführung.............................................. 1 1.1 Die Android-Plattform.................................................

Mehr

Web 2.0 Software-Architekturen

Web 2.0 Software-Architekturen Web 2.0 Software-Architekturen Servlets als Controller einer MVC Web Architektur Prof. Dr. Nikolaus Wulff HTTP und HTML Das HyperText TransferProtokoll (HTTP) beschreibt eine einfache verbindungslose Kommunikation,

Mehr

Ein mobiler Electronic Program Guide für Android

Ein mobiler Electronic Program Guide für Android Whitepaper Telekommunikation Ein mobiler Electronic Program Guide für Android Prototyp für Android Apps 2011 SYRACOM AG 1 Einleitung Apps Anwendungen für mobile Geräte sind derzeit in aller Munde. Durch

Mehr

CREATIVE PROGRAMMING TOOLKITS

CREATIVE PROGRAMMING TOOLKITS CREATIVE PROGRAMMING TOOLKITS Unter Creative Programming Toolkits verstehen wir Software-Teile welche uns helfen vielfältige Medien-kunst zu erstellen. Viele dieser Werkzeuge wurden durch Künstler für

Mehr

Integration mobiler Endgeräte in Medizinprodukte und Medizintechnik-nahe Produkte

Integration mobiler Endgeräte in Medizinprodukte und Medizintechnik-nahe Produkte Integration mobiler Endgeräte in Medizinprodukte und Medizintechnik-nahe Produkte Agenda Problemstellung Medizinprodukt App Grundlagen Szenarien (Problemstellungen und Lösungsansätze) 03.06.2013 2 Innovationen

Mehr

VLADISLAVA ARABADZHIEVA

VLADISLAVA ARABADZHIEVA VLADISLAVA ARABADZHIEVA Bachelor of Science Informatik Geburtsjahr 1987 Profil-Stand August 2015 Triona Information und Technologie GmbH Wilhelm-Theodor-Römheld-Str. 14 55130 Mainz Fon +49 (0) 61 31 9

Mehr

White Paper. Embedded Treiberframework. Einführung

White Paper. Embedded Treiberframework. Einführung Embedded Treiberframework Einführung White Paper Dieses White Paper beschreibt die Architektur einer Laufzeitumgebung für Gerätetreiber im embedded Umfeld. Dieses Treiberframework ist dabei auf jede embedded

Mehr

- Entwurfsphase: Entwurfsbeschreibung Gesamtsystem - Version: 1.0

- Entwurfsphase: Entwurfsbeschreibung Gesamtsystem - Version: 1.0 Projektbezeichnung Projektleiter Verantwortlich - Entwurfsphase: Entwurfsbeschreibung Gesamtsystem - Version: 1.0 MSP-13 - Integration eines Semantischen Tagging Systems in Microsoft Sharepoint Martin

Mehr

Software-Architektur Design Patterns

Software-Architektur Design Patterns Design Patterns Prof. Dr. Oliver Braun Fakultät für Informatik und Mathematik Hochschule München SS 2015 Standardwerk Gang of Four: Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides: Design Patterns:

Mehr

Android Kurs Online Kurs Entwicklung auf Android-Handys

Android Kurs Online Kurs Entwicklung auf Android-Handys Android Kurs Online Kurs Entwicklung auf Android-Handys Akademie Domani info@akademiedomani.de Allgemeines Programm des Kurses Modul Eins - Programmierung J2ee 1) Grundlegende Java - Programmierung : Grundlegende

Mehr