Neues in iOS 6

Mobiler Apfel, die Sechste
Kommentare

Gemeinsam mit dem neuen iPhone ist auch Apples mobiles Betriebssystem in die nächste Runde gegangen. Mit der Version iOS 6 bekommt der Endanwender gleich eine ganz Reihe neuer Features an die Hand: Apples Maps, Facebook-Integration, Passbook und Reminders sind nur einige der vielen, vielen neuen Möglichkeiten. Was aber bedeutet das für den Entwickler? Ein Blick hinter die Kulissen – also in das SDK – bringt Aufklärung.

Apple ist bekannt dafür, dass der Entwicklergemeinde mit jedem neuen iOS-Release auch einige neue Frameworks und Hunderte neuer/verbesserter APIs zur Verfügung gestellt werden. So geschehen auch beim aktuellen iOS 6. Dank eigener Maps Tiles und entsprechend erweitertem MapKit Framework wird das Einbinden von Kartenmaterial und Points of Interest in eigene Apps vereinfacht. Das neue Social Framework macht das erst in iOS 5 eingeführte Twitter-Framework obsolet und hebt die Anbindung sozialer Netzwerke auf eine höhere Abstraktionsebene. Mit PassKit wurde ein Framework zur On-Device-Ticketverwaltung geschaffen. Reminders erweitert das EventKit Framework um die Möglichkeit, Erinnerungen und Alarme anzulegen und zu verwalten. Das GameKit Framework bietet jetzt … STOP! Da steigt ja keiner mehr durch. Also noch einmal von vorne.

Map Kit

Wie dank der initialen Probleme mittlerweile sicherlich jeder iOS-Nutzer weiß, hat Apple in der aktuellen iOS-Version das von Google entliehene Kartenmaterial durch eigenes ersetzt und auch die zugehörige Maps-App entsprechend umgestellt. So weit, so gut. Was aber bedeutet das für die eigene Anwendungen, die das bereits seit iOS 3 existierende MapKit Framework verwenden? Zunächst einmal ändert sich eigentlich nichts. Bestehende Anwendungen laufen weiter wie bisher. Allerdings weist Apple explizit darauf hin, dass man vorhandene Screenschots seiner App mit dem alten Kartenmaterial im App Store durch aktualisierte Varianten austauschen sollte.

Natürlich hat Apple dem MapKit Framework auch einige neue Features spendiert, die vor allem die Interaktion zwischen der eigenen App und der Maps-App verbessern sollen. Anwendungen, die selbst keine Kartendarstellung beinhalten, können dank der neuen Funktionen deutlich einfacher auf die Maps-App zugreifen und dort zum Beispiel Points of Interest darstellen lassen. Anwendungen, die Wegbeschreibungen und Routing-Dienste anbieten, können sich als Routing-App registrieren und diese Dienste auch anderen zur Verfügung stellen. In beiden Fällen kommt die neue Klasse MKMapItem zum Einsatz, deren jeweilige Instanz spezifische Informationen eines auf einer Karte darzustellenden Punktes kapselt und so als Austauschobjekt zwischen der eigenen App und der Maps-App dient. Dies kann zum einen ein Point of Interest der eigenen Anwendung sein, der mithilfe der Methode openMapsWithLaunchOptions (ein Punkt) oder openMapsWithItems:launchOptions (mehrere Punkte) in der offiziellen Maps-App dargestellt werden soll. Oder aber die Anfangs- und Endpunkte einer Wegbeschreibung, die von der Maps-App an die eigene, als Routing-Anwendung registrierte App übergeben werden.

Zur Erinnerung: Wollte man in einer älteren iOS-Version einen PoI mithilfe der Maps-Anwendung darstellen, musste man innerhalb seiner eigenen Anwendung einen speziellen Google-Maps-URL erzeugen, um im Anschluss aus der Anwendung heraus diesen URL aufzurufen. Das war zum einen recht fehleranfällig und erlaubte zum anderen nicht das direkte Anzeigen der aktuellen User Location. Wie einfach dies dank iOS 6 geworden ist, zeigt Listing 1.

// MKMapItem erstellen
MKPlacemark* placeMark = ...;
MKMapItem* destination =  [[MKMapItem alloc] initWithPlacemark:placeMark]; 

// testen, ob iOS 6 Features vorhanden sind
if([destination respondsToSelector:@selector(openInMapsWithLaunchOptions:)]) 
{
  // iOS 6 native Maps verwenden
  [destination openInMapsWithLaunchOptions:@{MKLaunchOptionsDirectionsModeKey: 
                         MKLaunchOptionsDirectionsModeDriving}];
} else {
  // iOS 5 Google Maps verwenden.
  NSString* url = [NSString stringWithFormat: 
      @"http://maps.google.com/maps?saddr=Current+Location&daddr=%f,%f", 
      latitude, longitude];
  [[UIApplication sharedApplication] openURL: [NSURL URLWithString: url]];
}

Während das eben gezeigte Feature lediglich eine Vereinfachung darstellt, bieten sich durch die Registrierung der eigenen App als Routing-Anwendung bzw. Direction-Provider völlig neue Möglichkeiten. Möchte der User sich via Maps eine Route anzeigen lassen, wird automatisch der eigene Direction-Provider als Option mit aufgelistet. Zu abstrakt? Dann noch einmal an einem Beispiel verdeutlicht: Angenommen, die Routing-Anwendung stellt U-Bahnverbindungen innerhalb von Berlin dar. Möchte nun der Maps-Anwender eine entsprechende Verbindung angezeigt bekommen, dann kann er Start und Ziel innerhalb der Maps-Anwendung eingeben und von dort die entsprechende U-Bahn-App als Direction-Provider auswählen. Der Clou an der ganzen Sache: Die Maps-App ist in der Lage, die Routing-Anwendung – inkl. entsprechender MapItems für Start- und Zielpunkt – direkt aufzurufen. Der Aufruf landet im Application Delegate der U-Bahn-App in application:openURL:sourceApplication:annotation, wo direkt auf die übergebenen Werte zugegriffen werden kann (Listing 2).

- (BOOL)application:(UIApplication *)application 
         openURL:(NSURL *)url
         sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation
{
  // testen, ob DirectionsRequest eingegangen ist
  if ([MKDirectionsRequest isDirectionsRequestURL:url]) {

    // DirectionRequest erzeugen
    MKDirectionsRequest *request = [[MKDirectionsRequest alloc] initWithContentsOfURL:url]; 

    // Start- und Zielpunkt auslesen
    MKMapItem *startItem = request.source; 
    MKMapItem *endItem = request.destination; 
    ... ;
    return YES;
  }
  return NO;
}

Dass die eigene App direkt durch die Maps-App aufgerufen werden kann, ist schon eine nette Sache. Noch interessanter allerdings ist, dass die App noch nicht einmal auf dem Endgerät installiert sein muss, um zur Auswahl angezeigt zu werden. Da dank der Registrierung der App innerhalb des App Stores die Maps-App von deren Existenz weiß, kann Maps direkt auf den App Store und die dort liegende App verweisen. Damit dies am Ende nicht im absoluten Chaos endet, d. h. der User nicht aus einer schier unendlichen Liste von potenziellen Apps auswählen muss, gibt jeder Direction-Provider bei seiner Registrierung die exakte Region in Form einer GeoJSON-Beschreibung an, innerhalb derer er sinnvoll verwendet werden kann. In unserem Fall wären das also die GeoJSON-Daten von Berlin. Damit das Erstellen der notwendigen Regiondaten mit überschaubarem Aufwand realisierbar bleibt, stellt Apple eine Demoanwendung „RegionDefinder“ zur Verfügung, mit deren Hilfe sich eine entsprechende GeoJSON-Datei erzeugen lässt.

Bleibt noch die Frage offen, woher Maps weiß, dass die eigene App U-Bahnverbindungen und nicht zum Beispiel Flugverbindungen darstellt. Auch diese Information steckt in der App selbst und wird in Info.plist hinterlegt (Abb. 1). Gleiches gilt übrigens auch für die Tatsache, dass die Anwendung URL-Aufrufe vom Typ MKDirectionRequest und somit Wegbeschreibungen unterstützt.

MapKit-Einstellungen in der Info.plist

Pass Kit

Mit der neuen Passbook-Anwendung hat Apple eine wirkliche Innovation in iOS 6 eingebracht. Was zunächst lediglich wie eine nette App anmutet, ist eine geniale Kombination mehrerer Technologien, die in Summe den iPhone-Nutzern eine komplett neue User Experience bietet. Das PassKit Framework, die oben bereits erwähnte, mit dem iOS gebundelte Passbook-Anwendung, Apples Push-Notifications mit zeitlich garantierter Auslieferung sowie eigener serverseitiger Code, ermöglichen es beliebigen Ticket-Anbietern, virtuelle Tickets in einem genormten Format an iPhone-Nutzer auszuliefern. Das machen sich in Deutschland heute bereits einige Fluglinien, Mietwagenfirmen und Hotelbuchungsunternehmen zu nutzen. Weitere Anbieter werden mit Sicherheit folgen.

Was die Implementierung von Passes – also virtuellen Tickets – so anders macht als alles, was es bisher im iOS-Umfeld gab, ist die Tatsache, dass ein virtuelles Ticket eigentlich nichts weiter ist, als ein genormtes Austauschformat zwischen der eigenen serverseitigen Anwendung und der Passbook-App. Anders formuliert: Wie ein virtuelles Ticket erstellt wird, ob per Hand, per Java, per PHP oder wie auch immer, ist völlig egal. Wichtig ist am Ende nur, dass ein von Apple vorgegebenes, signiertes Dokumentformat vorliegt.

So unterschiedlich die Anwendungsbereiche virtueller Tickets und deren Aussehen auch sein mögen, alle haben mindestens vier fest vorgegebene Bereiche (Abb. 2):

  • Top Header
  • Content Area
  • Zusätzliche Information
  • Barcode

PassKit – virtuelles Ticket

Natürlich existieren neben diesen vier Bereichen noch viele optionale Bereiche, wie zum Beispiel der Gültigkeitszeitraum eines Tickets.

Da die oben beschriebenen Bereiche je nach Anwendungsgebiet eine unterschiedliche Gewichtung haben, gib Apple fünf Ticket-Typen vor, die sich in ihrem Grundlayout zum Teil stark unterscheiden:

  1. Coupon
  2. Boarding Pass
  3. Store Card
  4. Event Ticket
  5. Generic

Wie bereits weiter oben erwähnt, ist ein virtuelles Ticket für die Passbook-App keine eigene Anwendung sondern vielmehr ein spezielles Dokument. Genau genommen ist es eine ZIP-Datei mit der Endung .pkpass, die eine JSON-Beschreibung des Tickets, eine Signatur, eine Manifest-Datei sowie einige PNG-Dateien zur Visualisierung des Tickets beinhaltet. Listing 3 zeigt eine Minimalversion eines JSON-Passbook-Tickets inklusive Barcode und einiger Style-Informationen.

{
  "formatVersion" : 1,
  "passTypeIdentifier" : "pass.de.openknowledge.coupon",
  "serialNumber" : "002",
  "teamIdentifier" : "<YOUR TEAM IDENTIFIER>",
  "organizationName" : "open knowledge GmbH",
  "description" : "Wert-Coupon"

  "logoText" : "open knowledge GmbH",
  "foregroundColor" : "rgb(255, 255, 255)",
  "backgroundColor" : "rgb(135, 129, 189)",
  "labelColor" : "rgb(45, 54, 129)" 

  "barcode" : {
      "message" : "Super Free Coupon",
      "format" : "PKBarcodeFormatPDF417",
      "messageEncoding" : "iso-8859-1"
  }
}

Da ein Passbook-Ticket nicht automatisch auch mit einer eigenen iOS-App verbunden sein muss, hilft die Information teamIdentifier innerhalb der JSON-Datei Apple dabei, das Ticket einem Developer Account zuzuordnen. Gleichzeitig können gleichartige Tickets via passTypeIdentifier innerhalb von Passbook gruppiert werden. Mithilfe desselben Identifiers wird übrigens auch die eingebettete Signatur von Apple überprüft. Zu diesem Zweck muss der Entwickler zuvor im Apple Provisioning Portal eine entsprechende Pass Type ID sowie ein damit zusammenhängendes Zertifikat erstellt haben. Interessant ist auch die Angabe des Barcodes. Die JSON-Datei muss lediglich das Barcode-Format (QR, PDF417 oder Aztec) sowie die zu kodierende Message enthalten – alles Weitere übernimmt Passbook. Wer den nicht ganz trivialen Prozess des Ticket-Designs und der Ticket-Distribution nicht unbedingt per Hand durchführen möchte, der kann mittlerweile auch auf 3rd-Party-Support zurückgreifen. Eine gute Anlaufstelle ist der Passbook Content Designer.

Wer sich übrigens nach den ersten Gehversuchen mit dem PassKit wundert, dass referenzierte Bilder innerhalb des Tickets nicht angezeigt werden, der sollte kurz das Dateiformat überprüfen. Es scheint so zu sein, dass PNG24 problemlos funktioniert, während dagegen PNG8 – aus welchen Gründen auch immer – nicht angezeigt werden kann.

So weit, so gut. Aber wie kommt nun das virtuelle Ticket auf das iPhone bzw. in die Passbook-App? Auch hier lässt Apple dem Entwickler mehr oder minder freie Hand. Der wohl einfachste Weg ist das Zusenden als Anhang einer E-Mail. iOS erkennt automatisch die Endung .pkpass und öffnet einen entsprechenden Viewer, mit dessen Hilfe sich das Ticket zur Passbook-App hinzufügen lässt. Alternativ kann ein Ticket auch innerhalb einer Web App referenziert bzw. zum Download angeboten werden. Wer dies einmal ausprobieren möchte, sollte sich die Beispiele ansehen.

Neben den bisher angesprochenen Wegen, ein virtuelles Ticket auf das iPhone zu bekommen, gibt es noch eine weitere Möglichkeit. Ein Ticket kann direkt aus einer iOS-Anwendung heraus angeschaut und installiert werden. Hier kommt nun endlich auch das neue PassKit Framework zum Einsatz, welches übrigens nur aus drei Klassen und einem Protokoll besteht. Die Klasse PKPassLibrary repräsentiert die Library der virtuellen Tickets eines iPhones bzw. iPhone-Users. Mit ihrer Hilfe kann gezielt nach allen oder einzelnen Tickets gesucht sowie die Liste der Tickets bearbeitet werden. Ein einzelnes Ticket wird durch die Klasse PKPass abgebildet, welche sich u. a. mithilfe einer .pkpass-Datei initialisieren lässt. Last but not least existiert noch die ViewController-Klasse PKAddPassesViewController zur Anzeige eines virtuellen Tickets sowie zum Hinzufügen des Tickets zur Pass-Library und somit zur Passbook-App. Mithilfe dieser Klassen lässt sich mit wenigen Zeilen Code ein Pass-Previewer realisieren. Seit OS X 10.8.2 ist es zwar auch möglich, .pkpass-Dateien direkt auf dem Mac anzuschauen, das Rendering entspricht aber nicht zu 100 Prozent dem im iOS-Emulators bzw. auf den realen Endgeräten. Daher sollte dieses Feature lediglich für erste visuelle Checks verwendet werden, nicht aber für eine echte Qualitätskontrolle.

Wie bereits erwähnt, ermöglichen die verschiedenen von Apple vorgegebenen Ticket-Typen das zielgruppengerechte Gestalten des eigenen Tickets. Trotz diverser Layoutvorgaben bleiben dem Designer dabei – für jeden der angegebenen Typen – mehr als genug Möglichkeiten, das Ticket individuell zu gestalten und wichtige Informationen hervorzuheben. Auch unterschiedliche Währungen werden unterstützt. Sollte dies am Ende immer noch nicht ausreichen, bleibt die Möglichkeit, den Ticket-Typ Generic zu wählen.

Stellt sich am Ende nur noch die Frage was passiert, wenn Informationen auf dem Ticket veralten. Was ist zum Beispiel, wenn sich ein Flug-Gate oder ein Bahnsteig ändert? Oder aber die Adresse eines Geschäftes für den ein Gutschein vorliegt? Und was ist, wenn ein Ereignis – zum Bespiel ein Konzert – abgesagt wird? Ein virtuelles Ticket kann in seiner JSON-Beschreibung neben den bisher gezeigten Daten u. a. auch noch einen webServiceURL sowie ein authenticationToken beinhalten. Mit diesen beiden Informationen registriert Passbook das Ticket bei dem angegebenen Server für evtl. auftretende Updates. Für die Registrierung und das Update ruft Apple einen Web Service unter dem angegebenen URL – zzgl. Device- und Ticket-spezifischer Pfadbestandteile – auf. In der Regel fragt PassKit bereits bei der Installation eines Tickets nach einem Update, da das Ticket ja durchaus via E-Mail versandt worden und somit bereits veraltet sein kann. Natürlich ist neben der Registrierung auch eine Abmeldung für das Ticket vorgesehen. Damit der iPhone-User nicht permanent nach Änderungen des Tickets prüfen muss, kann auch Apples Notification-Service verwendet und so dem Nutzer proaktiv eine Änderung mitgeteilt werden (Abb. 3).

Passbook Notifications

Social Framework

Wer sich bereits in iOS 5 mit dem Twitter-API beschäftigt hat, wird sich sicherlich die Frage gestellt haben, warum Apple keinen allgemeinen Ansatz zur Anbindung von Social Networks anbietet. Genau diese Lücke füllt das neue SDK mit dem Social Framework und hebt so den in iOS 5 eingeführten, proprietären Twitter-Ansatz auf eine höhere Abstraktionsebene. Aktuell werden Twitter, Facebook und Sina Weibo – Chinas populäres Social Network – unterstützt. Das „alte“ Twitter-API gilt inzwischen als deprecated und Apple empfiehlt, in Zukunft ausschließlich das neue Social Framework zu nutzen.

Möchte man einfach nur seinen aktuellen Status aus der eigenen App heraus gezielt in eines der Social Networks posten, ist dies mit wenigen Zeilen Code getan. Wie schon zuvor beim Twitter-API, kann mit einem eigens dafür gedachten ViewController – SLComposeViewController – ein „Share Sheet“ innerhalb der App angezeigt werden. Natürlich lässt sich dieses bei Bedarf mit Statusinformationen und Bildern aus der App vorbelegen. Welchen Dienst man nutzen möchte, signalisiert man durch Angabe eines der drei Servicetypen SLServiceTypeFacebook, SLServiceTypeTwitter oder SLServiceTypeSinaWeibo. Da das Device nicht unbedingt alle drei Services unterstützen muss oder aber der Nutzer diese eventuell nicht für andere Apps freigegeben hat, lässt sich das im Vorfeld mithilfe des SLComposeViewController und der Methode isAvailableForServiceType testen (Listing 4).

...
// testen, ob Service-Type verfügbar
if (![SLComposeViewController isAvailableForServiceType:serviceType]) {
  [self showUnavailableAlertForServiceType:serviceType];
} else {

  // Share-Sheet für Service-Type erstellen
  SLComposeViewController *composeViewController =
  [SLComposeViewController composeViewControllerForServiceType:serviceType]; 
  [composeViewController addImage:self.myImageView.image]; 
  NSString *initalTextString = [NSString stringWithFormat:
           @"Status: %@", self.myTextView.text];
  [composeViewController setInitialText:initalTextString]; 

  // Share-Sheet für Service-Type anzeigen
  [self presentViewController:composeViewController
        animated:YES completion:nil];
}
...

Noch einfacher und sogar ohne Einbindung des Social Frameworks lassen sich Informationen mithilfe der Activity View sharen. Durch Aufruf der zugehörigen Klasse UIActivityViewController wird ein Popup dargestellt (Abb. 4), das alle auf dem Device durch den Nutzer freigegebenen Dienste zur Auswahl anzeigt und im Anschluss – also nach der Auswahl – direkt in die entsprechende App springt. Auch in diesem Fall lässt sich der zu teilende Text vorbelegen.

Das Social Framework bietet viele Möglichkeiten

Beide oben geschilderten Szenarien haben gemein, dass sie zum Teilen vorgefertigte Views verwenden. Was ist nun aber, wenn man seinen Status direkt – also ohne Zwischen-Screen – teilen möchte? Oder wenn zum Sharen eine eigene View verwendet werden soll? Und was ist, wenn man auch die vielen anderen Funktionen der verschiedenen Social Networks verwenden, also zum Beispiel auf die Facebook-Profile-Daten zugreifen oder einen Post eines Freundes „liken“ möchte? Natürlich ist auch das möglich. Und hier wird es erst richtig interessant.

Das API des Scocial Framework ist so aufgebaut, dass es den Zugriff auf die Web-APIs der einzelnen Social Networks kapselt und so in der Lage ist, beliebige Dienste zu unterstützen. Dabei kümmert sich Apples Social Framework um die wesentlichen Standardaufgaben wie Authentifizierung, Session Handling, dem Senden von Requests und Empfangen von Responses. Der Entwickler muss sich nur noch um die API-Calls des jeweiligen Services selbst sowie das UI der eigenen App kümmern.

Damit das Social Framework die eben beschriebenen Aufgaben ausführen kann, arbeitet es eng mit dem Accounts Framework zusammen, das die Zugriffe auf die unter Settings hinterlegten Nutzer-Konten kapselt. Soll nun die eigene Anwendung ein solches Konto (ACAccount vom passenden ACAccountType) nutzen, muss zunächst eine Anfrage an den Account Store (ACAccountStore) gestellt werden (Listing 5). Dabei sollte man im Hinterkopf behalten, dass es durchaus Dienste wie zum Beispiel Twitter gibt, die es erlauben, mehrere Accounts in den Settings zu hinterlegen.

- (void)accessFacebookAccount {

  // AccountType erzeugen
  ACAccountType *facebookAccountType = [self.accountStore
    accountTypeWithAccountTypeIdentifier: 
    ACAccountTypeIdentifierFacebook]; 

  // Zugriff zum Account erfragen
  dispatch_async(dispatch_get_global_queue(
    DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      NSDictionary *facebookOptions = @{...};
      [self.accountStore
        requestAccessToAccountsWithType:facebookAccountType
        options:facebookOptions completion:^(BOOL granted, NSError *error) {
        if (granted) { 
          ... // Facebook Stream abrufen
        } else {
          if (error) {
            ... // Fehler
          } else {
            ... // fehlende Berechtigung
          }
        }
      }];
    });
  }
}

Das Account Framework bietet übrigens auch den Zugriff auf die User Credentials der verschiedenen Konten (ACAccountCredentials), die innerhalb der eigenen App für eine direkte Authentifizierung via OAuth oder OAuth2 verwendet werden können.

Die eigentliche Kommunikation mit den Social-Network-Diensten erfolgt nach der Authentifizierung mittels SLRequest-Aufrufen, die je nach Dienst automatisch in die entsprechenden Formate überführt werden. Die Abfrage der eigenen Twitter Timeline zum würde zum Beispiel wie folgt aussehen und einen JSON-Stream zurückliefern:

SLRequest *request = [SLRequest 
  requestForServiceType:SLServiceTypeTwitter
  requestMethod:SLRequestMethodGET
  URL:[NSURL URLWithString:@"http://api.twitter.com/1/statuses/home_timeline.json"]
  parameters:@{@"count" : @"50"}];

Hat ein Nutzer einer App, die auf eines der Social-Network-Konten zugreifen möchte, noch keine Erlaubnis dafür erteilt, blendet iOS automatisch einen Dialog zur Abfrage der Erlaubnis und bei Bedarf auch zur Auswahl des zu nutzenden Kontos ein. Da die Zugangsdaten der Konten sowie die damit verbundenen Lese- und Schreibrechte jederzeit von außen geändert werden können, ist es „Best Practice“, innerhalb der eigenen Anwendung nach deren Verlassen und einem Neustart die Account-Informationen erneut abzufragen.

Collection Views

Mit den neuen Collection Views gibt Apple den Entwicklern ein mächtiges Werkzeug an die Hand, um geordnete bzw. zusammenhängende Daten innerhalb der eigenen App ansprechend zu präsentieren. Dabei werden sowohl die Präsentation selbst als auch die Transitionen zwischen verschiedenen Präsentationen deutlich vereinfacht. Was bisher nur mit viel Aufwand, etlichen Workarounds und/oder einer 3rd Party Library möglich war, ist ab iOS 6 fester Bestandteil des SDKs. So lässt sich zum Beispiel ein Look and Feel in die eigene App einbringen, wie wir es aus Apples Foto-App kennen (Abb. 5).

Collection View Look and Feel

Als Basis für die neuen Views dient ein UICollectionViewController. Dieser beinhaltet in der Regel einige wesentliche Komponenten:

  • UICollectionView: Basis-View, in der die darzustellenden Informationen angezeigt werden sollen. Vergleichbar – auch in der Verwendung – mit UITableView.
  • UICollectionViewCell: Einzelne darzustellende Information innerhalb einer UICollectionView. Vergleichbar mit UITableViewCell.
  • Supplementary Views: Zusätzliche Informationen, wie z. B. Header oder Footer, die innerhalb der Collection View dargestellt werden sollen.
  • Decoration Views: Zusätzliche Views, wie zum Beispiel Hintergrundbilder, die zur Verschönerung der Collection View dienen, aber keine weiteren Informationen beinhalten.

Zusätzlich zu den eben aufgeführten Komponenten kann eine UICollectionView noch mit einem Layout zur Positionierung der einzelnen Zellen verbunden werden.

Das neue Feature Collection Views ist eine Mischung aus API und Tool-Unterstützung. Auch wenn es theoretisch möglich ist, eine Collection View rein programmativ aufzubauen, bietet es sich in vielen Fällen an, den Interface Builder zur Unterstützung zu nutzen.

Wie bereits von der UITableView bekannt, benötigt auch die UICollectionView eine Data Source (UICollectionViewDataSource) und ein Delegate (UICollectionViewDelegate). Die Data Source liefert Informationen zur Anzahl der Datensätze sowie den Views. Das Delegate wird benachrichtigt, sobald etwas mit einer der darzustellenden Zellen passiert, d. h. eine Zelle zum Beispiel ausgewählt oder gelöscht wird. Zusätzlich muss die UICollectionView noch ein drittes Protokoll implementieren, das die Verbindung zum Layoutmanager herstellt und in seiner konkreten Ausprägung somit auch von dem jeweils gewählten Layoutmanager abhängt. Mithilfe dieses Protokolls können verschiedene Layouteinstellungen zur Laufzeit verändert werden. Abbildung 6 verdeutlicht die eben beschriebenen Zusammenhänge.

CollectionView – Zusammenspiel

Das neue Collection-View-API zeigt sich äußerst flexibel. Neben vorgefertigten Layouts können auch eigene Layouts zur Anwendung kommen. Einzelne Zellen können beliebig platziert werden und sich in Größe und Erscheinung stark voneinander unterscheiden. Auch eine Gruppierung, wie wir sie aus der Foto-App und deren Alben her kennen, ist so problemlos realisierbar. Ein guter Einstieg in das Thema Collection Views findet sich für registrierte iOS-Entwickler unter „Collection View Programming Guide for iOS“.

Noteworthy

Neben den bisher gezeigten „Main Features“ bietet iOS 6 noch eine ganze Reihe weiterer neuer Features, von denen die wichtigsten im Folgenden kurz angerissen werden sollen.

Das von Apple als „Reminder“ bezeichnete Feature ist eigentlich nichts anderes als eine Erweiterung des bereits seit iOS 4 bekannten EventKit; also dem Framework, das der eigenen App den Zugriff auf Kalender und Events der Kalender-App ermöglicht. Bisher ausgenommen war dort der Zugriff auf die in iOS 5 eingeführte Reminder-App. Das hat sich nun mit iOS 6 und dem darin enthaltenen Reminder-API geändert. Reminder ähneln zwar stark den bereits bekannten Events und werden genau wie diese in einem Kalender gespeichert, sie unterscheiden sich aber in dem Punkt, dass sie keinen Start- und Endzeitpunkt benötigen. Entsprechend einfach sieht auch der Code zum Erstellen und Speichern eines Reminders aus (Listing 6).

...
// Reminder erzeugen
EKReminder *reminder = [EKReminder reminderWithEventStore:eventStore]; 
reminder.title = @"Nicht vergessen: iOS 6 rocks!"; 
reminder.calendar = [eventStore defaultCalendarForNewReminders]; 

// Reminder speichern
NSError *err;
BOOL success = [eventStore saveReminder:reminder commit:YES error:&err];
if (!success) {
  ...
}; 

Der im Listing 6 dargestellte Code ist die einfachste Variante. Anstatt den Default-Kalender zu wählen, könnte auch ein anderer genutzt oder gar ein neuer erzeugt werden. Auch ein Fälligkeitsdatum oder ein Alarm könnte angegeben werden. Genauso einfach wie das Anlegen eines Reminders ist auch das Auslesen, Suchen und gezielte Filtern. Für all diese Funktionen liefert iOS 6 entsprechende Methoden.

In-App Purchase

Es gibt Statistiken, dass mittlerweile 3 von 4 der umsatzstärksten Apps im App Store den wesentlichen Umsatz via In-App Purchase generieren. In iOS 6 hat Apple diesen Bereich daher noch einmal deutlich ausgebaut und ermöglicht so die Umsetzung von Features, die, wenn überhaupt, bisher nur über Drittanbieter realisierbar waren.

Zum einen ist es nun möglich, kaufbaren Content direkt auf Apple-Servern kostenfrei zu hosten und von dort aus an die App auszuliefern. Dieses Vorgehen hat den Vorteil, dass man den optional kaufbaren Content nicht schon mit der Anwendung ausliefern muss, sich aber gleichzeitig auch keine Gedanken über die zur Auslieferung notwendige Serverinfrastruktur machen braucht. Das StoreKit Framework bietet für diesen Zweck eine neuen Klasse namens SKDownload, mit deren Hilfe innerhalb der App sichergestellt werden kann, dass der gekaufte Content auch vollständig geladen wurde.

Darüber hinaus kann – mittels SKStoreProductViewController – direkt auf den iTunes Store zugegriffen werden. Mit diesem neuen Feature kann der Anwender gezielt auf für die gerade genutzte App nützlichen Content hingewiesen werden, ohne sie dabei verlassen zu müssen. Das ergibt zum Beispiel für Apps Sinn, die es erlauben, Musik, Bücher oder Filme aus dem iTunes Store zu kaufen. Während der SKStoreProductViewController eine Standard-View zur Anzeige der Produkte anzeigt, ist es auch möglich, einen individuellen ViewController umzusetzen, der dann wiederum das Protokoll SKStoreProductViewControllerDelegate implementiert.

Aktuell scheint es übrigens so zu sein, dass man bei diesem Feature keine Möglichkeit hat, seinen Affiliate Identifer mitzusenden, um so die 10 % Vermittlungsprovision des iTunes-Affiliate-Programms zu erhalten – hoffentlich hat Apple das nur versehentlich vergessen und wird es umgehend nachreichen.

GameKit

Das Game Center bzw. das zugehörige GameKit Framework existiert bereits seit iOS 4.1 und bietet Multiplayer-Games u. a. die Möglichkeit, Multiplayer-Sessions zu starten oder Archievements und Trophäen zu verwalten. Gleichzeitig bietet Game Center eine Communityplattform für Gleichgesinnte und erlaubt so zum Beispiel, zu schauen, welche Spiele die eigenen Freunde noch so spielen. Genau an dieser Stelle setzt eine der Erweiterungen in iOS 6 an und zielt darauf ab, die Sichtbarkeit des eigenen Spiels zu erhöhen. Denn unter iOS 6 entwickelte Spiele erlauben es den Spielern zukünftig, Challenges an Freunde zu verschicken. Denkbar wäre zum Beispiel das Versenden eines neuen High Scores mit der Aufforderung, ihn zu schlagen. Der Clou an diesem Feature ist, dass ein Spieler solche Messages auch dann bekommen kann, wenn er das Spiel gar nicht installiert hat. Ein entsprechender Downloadlink führt ihn dann direkt zu dem Spiel. Einfacher lässt sich ein Spiel wohl kaum vermarkten. Challenges können aus dem Game Center heraus gestartet werden. Alternativ kann das auch direkt aus dem Spiel heraus erfolgen. Zu diesem Zweck bietet die GKStore-Klasse die neue Methode issueChallengeToPlayers:message an.

Ebenfalls neu ist die Möglichkeit, die verschiedenen Views des Games Centers direkt innerhalb der eigenen App zu nutzen, ohne dafür das eigene Spiel verlassen zu müssen. Dank des neuen ViewControllers GKGameCenterViewController können mit wenigen Zeilen Code aus der eigenen App heraus Leaderboards und Archievements eigesehen oder aber Spiele bewertet und via Facebook und Co geteilt werden. Natürlich wäre letzteres auch mithilfe des oben bereits kennen gelernten UIActivityViewController möglich (siehe Social Framework).

UI State

Vor iOS 6 war es zu 100 % dem Entwickler überlassen, den State einer UI beim Verlassen der App zu sichern, um ihn dann beim Wiederöffnen der App reproduzieren zu können. In der Regel wurde der dazu notwendige Code manuell in die entsprechenden Callback-Methoden der Application-Lifecycle-Events eingebaut. iOS 6 UI State Preservation des UIKit vereinfacht und normiert diesen Vorgang extrem, indem es eine entsprechende Infrastruktur zur Speicherung und Wiederherstellung von ViewController und View State zur Verfügung stellt. Während die App selbst dafür zuständig ist, dem UIKit mitzuteilen, welche Objekte bzw. Views persistiert und später wiederhergestellt werden sollen, kümmert sich das UIKit um die eigentliche Arbeit. Ausgangspunkt sind dabei die beiden UIApplicationDelegate-Methoden application:shouldSaveApplicationState und application:shouldRestoreApplicationState. An dieser Stelle sei erwähnt, dass einem das UIKit zwar eine Menge Arbeit abnimmt, die eigentliche Verantwortung aber nach wie vor beim App-Entwickler liegt. Denn nur die App selbst bzw. der Entwickler kennt die für die einzelnen Views relevanten Daten.

Auto Layout

Eine wesentliche Verbesserung im Bereich des UI-Designs stellt das neue Auto-Layout-Feature dar. Im Gegensatz zu dem bisherigen Autosizing-Layout-Modell, in dem UI-Elemente entweder feste Größen und Ankerpunkte haben oder aber sich wie eine Feder ausdehnen, erlaubt der neue Ansatz eine deutlich größere Flexibilität. Mithilfe so genannter „Constraints“ können für einzelne UI-Elemente – und natürlich auch für Gruppen davon – Regeln angegeben werden, wie sie sich innerhalb eines ViewControllers platzieren sollen. Constraints können so zum Beispiel regeln, dass verschiedene Elemente immer gleich ausgerichtet werden oder dass sich Elemente gemeinsam mit anderen verschieben. Ziel dieses neuen Layoutmodells ist eine klarere Trennung der Verantwortlichkeiten zwischen View und Controller, um so den bisher notwendigen Layoutcode innerhalb des ViewControllers zu ersparen. Fragt sich nur, wie man eine solche Constraint erstellt. Der Interface Builder ab Xcode 4.5 bietet, wie nicht anders zu erwarten, entsprechende Unterstützung an. Alternativ können sie aber auch programmativ erstellt – NSLayoutConstraint lässt grüßen – und an eine View gebunden werden. Mit dem Feature Auto Layout erleichtert Apple so vor allem das Erstellen von UIs für unterschiedliche Device-Typen (iPad/iPhone), Ausrichtungen (Landscape/Protrait) und Locales (Sprachen mit Links-Rechts-Schrift vs. Rechts-Links-Schrift).

Data Privacy

In diesem Artikel wurde an mehreren Stellen gezeigt, dass iOS immer mehr dazu über geht, Daten und Views aus verschiedensten Apps auch anderen Apps zur Verfügung zu stellen. Das hat natürlich auch direkte Auswirkungen auf die Sicherheit. Daher bringt das neue iOS neben den ganzen bereits genannten Features auch Veränderungen im Bereich Data Privacy mit sich. Zusätzlich zum Zugriff durch 3rd-Party-Apps auf Location Data fragt das System den Benutzer nun auch bei Zugriffen auf Daten aus Contacts, Calendars, Reminders und Photo Library um Erlaubnis und verhindert – oder sollte man besser sagen erschwert – deren Missbrauch. Um die Art des gewünschten Zugriffs genauer qualifizieren zu können und somit dem Nutzer die Entscheidung zu erleichtern, können entsprechende Texte innerhalb der Datei Info.plist hinterlegt werden.

Fazit

Apple hat mit der neuen iOS-Version noch einmal einen großen Schritt nach vorne getan. Dies gilt nicht nur für die Anwender sondern vor allem auch für die Entwickler.

Viele der Änderungen und Erweiterungen – wir nehmen hier einmal das neue Apple Maps aus – zielen auf eine verbesserte Ergonomie für den iPhone Nutzer ab. Auto Layouts und Collection Views erlauben die Entwicklung ergonomischer Oberflächen – und das für verschiedenste Device-Formate. Und nahezu alle Anwendungen, für die es sinnvoll erscheint, lassen sich mittlerweile untereinander aufrufen.

Und auch der App-Entwickler, der mit der Anwendung Geld verdienen will, wurde nicht vergessen. Content kann nun direkt bei Apple gehostet werden und einige neue Features erlauben die direkte Verlinkung von kaufbarem App-Store-Content aus den Anwendungen heraus.

Diese vielen kleinen Verbesserungen sind allerdings auch notwendig, sieht man sich die aktuellen Erfolgszahlen von Android an. Und als wäre das noch nicht genug, taucht am Horizont – und mittlerweile auch schon in der einen oder anderen Hosentasche – zusätzlich auch noch die große Unbekannte „Windows 8“ auf.

In einem Punkt hat Apple allerdings auf jedem Fall die Nase vorn. An Xcode und Interface Builder reicht nach wie vor kein anderes Toolset heran. Ob das auf Dauer ausreicht, um den Markt zu dominieren, muss sich zeigen. Auf jeden Fall können wir jetzt schon auf die nächste iOS-Version gespannt sein. In diesem Sinne: Stay tuned.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -