Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort
Vorwort
1 Hello iPhone
2 Die Reise nach iOS
3 Sehen und anfassen
4 Alles unter Kontrolle
5 Daten, Tabellen und Controller
6 Models, Layer, Animationen
7 Programmieren, aber sicher
8 Datenserialisierung und Internetzugriff
9 Multimedia
10 Jahrmarkt der Nützlichkeiten
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
Apps programmieren für iPhone und iPad von Klaus M. Rodewig, Clemens Wagner
Das umfassende Handbuch
Buch: Apps programmieren für iPhone und iPad

Apps programmieren für iPhone und iPad
Rheinwerk Computing
1172 S., geb., mit DVD
49,90 Euro, ISBN 978-3-8362-2734-6
Pfeil 5 Daten, Tabellen und Controller
Pfeil 5.1 Benachrichtigungen
Pfeil 5.1.1 Benachrichtigungen empfangen
Pfeil 5.1.2 Eigene Benachrichtigungen verschicken
Pfeil 5.2 Layoutanpassungen und Viewrotationen
Pfeil 5.2.1 Lang lebe das Rotationsprinzip!
Pfeil 5.2.2 Anpassung des Layouts
Pfeil 5.3 Core Data
Pfeil 5.3.1 Datenmodellierung
Pfeil 5.3.2 Implementierung von Entitätstypen
Pfeil 5.3.3 Dokumentenordner und Application-Support-Verzeichnis
Pfeil 5.3.4 Einbindung von Core Data
Pfeil 5.3.5 Der Objektkontext
Pfeil 5.3.6 Die Nachrichten des Objektkontexts
Pfeil 5.3.7 Anlegen und Ändern von Entitäten in der Praxis
Pfeil 5.4 Texte, Bilder und Töne verwalten
Pfeil 5.4.1 Viewanpassungen für die Systemleisten
Pfeil 5.4.2 Die Tastatur betritt die Bühne
Pfeil 5.4.3 Fotos aufnehmen
Pfeil 5.4.4 Töne aufnehmen und abspielen
Pfeil 5.5 Tableviews und Core Data
Pfeil 5.5.1 Tableviews
Pfeil 5.5.2 Tabellenzellen gestalten
Pfeil 5.5.3 Zellprototypen über das Storyboard definieren
Pfeil 5.5.4 Zellprototypen per Programmcode bereitstellen
Pfeil 5.5.5 Der Target-Action-Mechanismus und Tabellenzellen
Pfeil 5.5.6 Zellen löschen
Pfeil 5.6 Core Data II: Die Rückkehr der Objekte
Pfeil 5.6.1 Prädikate
Pfeil 5.6.2 Aktualisierung des Tableviews
Pfeil 5.6.3 Das Delegate des Fetched-Results-Controllers
Pfeil 5.6.4 Tabelleneinträge suchen
Pfeil 5.7 Inhalte teilen
Pfeil 5.7.1 Integration in das Fototagebuch
Pfeil 5.7.2 Eigene Aktivitäten bereitstellen
Pfeil 5.8 Collectionviews
Pfeil 5.8.1 Der Collectionviewcontroller
Pfeil 5.8.2 Gitterdarstellung
Pfeil 5.8.3 Zellen und die Datenquelle
Pfeil 5.8.4 Ergänzende Views
Pfeil 5.8.5 Freie Layouts
Pfeil 5.8.6 Freie Layouts und ergänzende Views
Pfeil 5.8.7 Decorationviews

5Daten, Tabellen und ControllerZur nächsten Überschrift

»Ich hoffe, mein Schaden hat kein Gehirn genommen.«
– Homer Simpson

Als Beispielprojekt für dieses Kapitel legen wir ein Fototagebuch an. Das ist ein Notizbuch, in dem Sie Texte, Bilder und Töne chronologisch geordnet ablegen können. Dieses Projekt ist wesentlich umfangreicher als der analoge Wecker aus Kapitel 3, »Sehen und anfassen«, und es ist deshalb nicht möglich, die einzelnen Schritte zum Erstellen dieser App zu beschreiben, da dies den Umfang unseres Buches sprengen würde. Das komplette Projekt finden Sie natürlich auf der DVD oder im Git-Repository. Die Beschreibungen in diesem Kapitel konzentrieren sich auf die neuen und spannenderen Themen.

Projektinformation

Den Quellcode des folgenden Beispiels finden Sie auf der DVD unter Code/Apps/iOS6/PhotoDiary oder im Github-Repository zum Buch im Unterverzeichnis https://github.com/Cocoaneheads/iPhone/tree/Auflage_3/Apps/iOS6/PhotoDiary.


Rheinwerk Computing - Zum Seitenanfang

5.1BenachrichtigungenZur nächsten ÜberschriftZur vorigen Überschrift

Delegation ist sehr praktisch, wenn ein Objekt bestimmte Aufgaben oder Informationen an ein anderes Objekt weiterreichen soll, ohne dabei eine Abhängigkeit vom Ausgangsobjekt zum Zielobjekt zu erzeugen. Häufig gibt es jedoch Situationen, in denen mehrere Objekte eine Information verarbeiten sollen.

Sie haben bereits das Application-Delegate und seine Methoden kennengelernt. Es bietet Ihnen beispielsweise eine Methode an, mit der Sie Operationen ausführen können, bevor das iOS die App in den Hintergrund schickt. Sie können diese Methode beispielsweise benutzen, um den aktuellen Applikationszustand zu sichern. Das ist sicherlich für kleine Applikationen ausreichend, wenn sie diese Zustandsdaten zentral – vorzugsweise im Application-Delegate selbst – lagern. Wenn sich diese Daten hingegen über viele unterschiedliche Objekte verteilen, stößt dieses Vorgehen sehr schnell an seine Grenzen.


Rheinwerk Computing - Zum Seitenanfang

5.1.1Benachrichtigungen empfangenZur nächsten ÜberschriftZur vorigen Überschrift

Cocoa Touch bietet dafür indes ein weiteres Vorgehen an, das sich für solche Aufgabenstellungen besser eignet. Dabei nutzen Sie Notifications oder Benachrichtigungen – das sind Objekte der Klasse NSNotification, die Sie innerhalb einer Applikation verschicken können. Jede Benachrichtigung hat einen Typ, den eine Zeichenkettenkonstante repräsentiert. Apple vereinbart in seinen Frameworks bereits mehrere Typen. Sie können allerdings auch eigene Typen definieren.

Jedes Objekt kann beliebige Benachrichtigungen empfangen. Sie müssen es dazu nur bei einem zentralen Objekt für die Verwaltung der Benachrichtigungen anmelden. Dieses Objekt hat die Klasse NSNotificationCenter. Sie können einen Empfänger über die Methode addObserver:selector:name:object des Notificationcenters registrieren.

Der Empfänger muss sich immer bei dem Center anmelden, über das der Nachrichtensender seine Benachrichtigungen schickt. Auf das Standardcenter von Cocoa Touch greifen Sie über die Klassenmethode defaultCenter zu.

Mehrere Notificationcenter

In Cocoa Touch gibt es im Gegensatz zu Mac OS X zurzeit nur ein Center des Systems. Die Klasse ist jedoch kein Singleton, und Sie können beliebig viele weitere Objekte dieser Klasse anlegen. Sie können indes Nachrichten immer nur über das Center empfangen, über das der Absender sie verschickt hat. Systemnachrichten bekommen Sie also immer über das Standardcenter.

Wenn das iOS eine Applikation in den Hintergrund schickt, verschickt die Applikation eine Benachrichtigung mit dem Typ UIApplicationWillResignActiveNotification. Sie können ein Objekt für den Empfang dieser Benachrichtigung wie folgt anmelden:

NSNotificationCenter *theCenter = 
[NSNotificationCenter defaultCenter];

[theCenter addObserver:theObject
selector:@selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];

Listing 5.1 Anmelden eines Benachrichtigungsempfängers

Mit dem Parameter object der Registrierungsmethode können Sie die Benachrichtigungen nach dem Absender filtern. Wenn Sie bei der Registrierung hier einen Absender angeben, erhält der Empfänger nur Benachrichtigungen dieses Senders. Geben Sie hingegen nil (wie in Listing 5.1) an, erhält er alle Nachrichten.

Nach der Registrierung ruft das Notificationcenter immer die Methode applicationWillResignActive: [Anm.: Dieser Methodenname kollidiert mit der gleichnamigen Methode des Application-Delegates. Sie dürfen diese Methode also nicht dort deklarieren, da Objective-C Methoden nicht anhand der Parametertypen unterscheidet.] des Objekts theObject auf, sobald die Applikation die entsprechende Benachrichtigung verschickt. Die Methode hat einen Parameter mit der Klasse NSNotification. Über die Property object dieses Objekts können Sie den Absender der Benachrichtigung ermitteln. Außerdem kann der Absender ein Dictionary mitschicken, das nachrichtenspezifische Werte enthält und auf das Sie über die Property userInfo zugreifen können.

Der kleine Unterschied

Achten Sie bei der Angabe des Selektors auf die richtige Schreibweise des Methodennamens. Gerade bei Methoden mit einem Parameter vergisst man schon mal leicht den Doppelpunkt am Ende. Der Selektor @selector(applicationWillResignActive:) beschreibt eine andere Nachricht als @selector(applicationWillResignActive).

Listing 5.2 enthält ein Beispiel für eine Methode zum Nachrichtenempfang, die den Absender aus der Benachrichtigung ausliest.

- (void)applicationWillResignActive: 
(NSNotification *)inNotification {
UIApplication *theApplication = inNotification.object;
...
}

Listing 5.2 Methode zum Empfangen von Benachrichtigungen

Alternativ können Sie Blöcke verwenden, um Benachrichtigungen zu verarbeiten. Dann benutzen Sie die Methode addObserverForName:object:queue:usingBlock: für die Registrierung. Die analoge Registrierung zu Listing 5.1 und die Verarbeitung aus Listing 5.2 sehen damit folgendermaßen aus:

[theCenter addObserverForName: 
UIApplicationWillResignActiveNotification
object:nil queue:nil
usingBlock:^(NSNotification *inNotification) {
UIApplication *theApplication = inNotification.object;
...
}];

Listing 5.3 Registrierung eines Blocks für den Benachrichtigungsempfang

Die Variante mit Blöcken hat einen weiteren Vorteil gegenüber der Registrierung einer Methode: Durch die Angabe einer Operationqueue können Sie die Benachrichtigungen asynchron verarbeiten; d. h., der Thread, der die Benachrichtigung verschickt, muss nicht auf die Beendigung des Blocks warten. Außerdem können Sie darüber die Ausführung des Blocks im Haupt- oder Main-Thread erzwingen. Das ist sehr hilfreich, um Operationen des UIKits (z. B. Änderungen an Views) auszuführen, die immer in diesem Thread erfolgen sollen.

NSOperationQueue *theMainQueue = [NSOperationQueue mainQueue];

[theCenter addObserverForName:
UIApplicationWillResignActiveNotification
object:nil queue:theMainQueue
usingBlock:^(NSNotification *inNotification) {
UIApplication *theApplication = inNotification.object;
...
}];

Listing 5.4 Ausführung des Blocks im Hauptthread

Über die Methoden removeObserver:name:object: und removeObserver: können Sie einen Nachrichtenempfänger wieder beim Notificationcenter abmelden. Während Sie mit der ersten Methode einzelne Benachrichtigungen abschalten, unterbinden Sie über die zweite alle Benachrichtigungen eines Empfängers auf einmal. Das ist häufig sehr praktisch, da man in den meisten Fällen ein Objekt für alle Benachrichtigungen auf einmal abmelden will. Möchten Sie das Objekt aus Listing 5.1 nur von den Benachrichtigungen des Typs UIApplicationWillResignActiveNotification abmelden, erreichen Sie das über die folgende Zeile

[theCenter removeObserver:theObject name: 
UIApplicationWillResignActiveNotification object:nil];

und über

[theCenter removeObserver:theObject];

melden Sie das Objekt von allen Benachrichtigungen ab.

Abmelden ist notwendig

Sie müssen jeden Nachrichtenempfänger vor seiner Zerstörung beim Notificationcenter abmelden. Andernfalls erzeugen Sie einen Dangling Pointer, was zu einem Programmabsturz führen kann.


Rheinwerk Computing - Zum Seitenanfang

5.1.2Eigene Benachrichtigungen verschickenZur vorigen Überschrift

Cocoa Touch stellt eine Vielzahl von Benachrichtigungen bereit, die Sie für die Entwicklung Ihrer Apps verwenden können. Sie können allerdings auch aus Ihren Klassen eigene Benachrichtigungen versenden. Beispielsweise könnte das Wecker-Beispielprogramm eine Benachrichtigung bei Alarmauslösung verschicken. Dazu sollten Sie sich zunächst einen Namen ausdenken, der das Ereignis möglichst gut beschreibt, z. B. kAlarmClockHasFiredAlarmNotification. Da jedes beliebige Objekt diese Benachrichtigungen empfangen können soll, deklarieren Sie in der Headerdatei AlarmClockAppDelegate.h folgende Konstante:

extern NSString * const kAlarmClockHasFiredAlarmNotification;

Diese Deklaration sollten Sie in der Headerdatei vor der Klassendeklaration platzieren. Dabei gibt das Schlüsselwort extern an, dass diese Anweisung die Variable nur deklariert und nicht implementiert; andernfalls würde Ihnen der Linker Fehler melden. In die Implementierungsdatei AlarmClockAppDelegate.m müssen Sie dann noch die entsprechende Definition einfügen:

NSString * const kAlarmClockHasFiredAlarmNotification = 
@"kAlarmClockHasFiredAlarmNotification";

Tipp

Sie sollten für den Namen der Benachrichtigung immer eine Konstante verwenden. Zum einen vermeiden Sie dadurch Fehler aufgrund falsch geschriebener Benachrichtigungsnamen, zum anderen können Sie eventuelle Namenskonflikte sehr einfach beheben.

Aus der Methode application:didReceiveLocalNotification: können Sie jetzt die Benachrichtigung über eine der Methoden postNotification:, postNotificationName:object: oder postNotificationName:object:userInfo: verschicken. Bei der ersten Variante müssen Sie das Benachrichtigungsobjekt selbst erzeugen, während das bei den beiden anderen Varianten jeweils die Methode übernimmt. Im einfachsten Fall verwenden Sie die zweite Methode.

NSNotificationCenter *theCenter = 
[NSNotificationCenter defaultCenter];
[theCenter postNotificationName:
kAlarmClockHasFiredAlarmNotification object:self];

Listing 5.5 Verschicken einer einfachen Benachrichtigung

Wenn Sie dagegen auch den Nachrichtentext mit der Benachrichtigung verschicken wollen, sollten Sie die dritte Variante verwenden. Sie können bei ihr über den Parameter userInfo beispielsweise den Nachrichtentext übergeben, den Sie aus der lokalen Benachrichtigung erhalten.

NSNotificationCenter *theCenter = 
[NSNotificationCenter defaultCenter];
NSDictionary *theInfo = @{
@"alertBody": inNotification.alertBody };
[theCenter postNotificationName:
kAlarmClockHasFiredAlarmNotification
object:self userInfo:theInfo];

Listing 5.6 Verschicken einer Benachrichtigung mit Parametern

»NSNotification« versus »UILocalNotification«

Die Benachrichtigungen der Klasse NSNotification aus diesem Kapitel haben bis auf den ähnlichen Namen relativ wenig mit den lokalen Benachrichtigungen der Klasse UILocalNotification aus Kapitel 3, »Sehen und anfassen«, gemeinsam. Die wichtigsten Unterschiede sind folgende:

  • Eine lokale Benachrichtigung versendet das System zu einem festgelegten Zeitpunkt an die initiierende Applikation. Wenn die Applikation zum Benachrichtigungszeitpunkt nicht läuft, muss sie die Nachricht auch nicht empfangen. Beliebige Objekte innerhalb einer Applikation können Benachrichtigungen versenden, und alle registrierten Empfänger empfangen sie.
  • Lokale Benachrichtigungen kann nur das Application-Delegate über die dafür vorgesehene Methode empfangen. Im Gegensatz dazu kann jede Klasse eigene Methoden für den Nachrichtenempfang bereitstellen.
  • Lokale Benachrichtigungen haben keine Typen und können nur eingeschränkte Informationen enthalten. Bei Benachrichtigungen dienen Typen zur Unterscheidung, und sie dürfen nahezu jedes beliebige Objekt mitschicken.
  • Lokale Benachrichtigungen sind persistent. Sie bleiben bis zu ihrer Auslieferung erhalten, also auch über einen Neustart der App oder des Gerätes hinaus. Noch nicht ausgelieferte Benachrichtigungen gehen hingegen in diesen Situationen verloren.

Benachrichtigungen können Sie also nur applikationsintern verwenden; dort sind sie jedoch eine gute Möglichkeit, um mehrere andere Objekte zu informieren. Diese Technik ist eine einfache und sehr elegante Methode, beliebige Empfänger lose an den Nachrichtensender zu koppeln. Da im MVC-Muster das Modell weder den Controller und schon gar nicht den View kennen sollte, eignen sich Benachrichtigungen hervorragend für die Kommunikation vom Modell zum Controller. In diesem und im nächsten Kapitel zeigen wir Ihnen dafür noch einige Beispiele.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück




Copyright © Rheinwerk Verlag GmbH, Bonn 2014
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern


  Zum Rheinwerk-Shop
Zum Katalog: Apps programmieren für iPhone und iPad






Neuauflage: Apps programmieren für iPhone und iPad
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Einstieg in Objective-C 2.0 und Cocoa






Einstieg in Objective-C 2.0 und Cocoa


Zum Katalog: Spieleprogrammierung mit Android Studio






Spieleprogrammierung mit Android Studio


Zum Katalog: Android 5






Android 5


Zum Katalog: iPhone und iPad-Apps entwickeln






iPhone und iPad-Apps entwickeln


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo