Slide 1

Slide 1 text

Mit Core Data Karl Bode - @karl_in 1 von der Idee zum ersten Update

Slide 2

Slide 2 text

Karl Bode • Software-Entwickler - mobile • hot coffee apps, Bremen • Digital Media - Master Student • Twitter: @karl_in • kpbode@hotcoffeeapps.com 2

Slide 3

Slide 3 text

Inhalt • Core Data 101 • App-Design • Nested ManagedObjectContexts • Datenmigration • Zusammenfassung 3

Slide 4

Slide 4 text

Inhalt • Core Data 101 • App-Design • Nested ManagedObjectContexts • Datenmigration • Zusammenfassung 4

Slide 5

Slide 5 text

Core Data 101 • in OS X seit 10.4 (Tiger), in iOS seit 3.0 • schema-driven object graph management and persistence framework • SQLite ist eine Option • fest verankert in Xcode-Templates • grafische Datenmodellierung -> Schema 5

Slide 6

Slide 6 text

Core Data 101 • versionierte Datenmodelle + Migration • Undo + Redo - Unterstützung • iCloud-Synchronisation • zahlreiche Optimierungen • eine Technologie für komplexe Aufgaben 6

Slide 7

Slide 7 text

NSPersistentStoreCoordinator Core Data 101 7 NSManagedObjectContext NSManagedObject NSPersistentStore SQLite NSManagedObjectModel NSEntityDescription ...

Slide 8

Slide 8 text

Inhalt • Core Data 101 • App-Design • Nested ManagedObjectContexts • Datenmigration • Zusammenfassung 8

Slide 9

Slide 9 text

• Personen anlegen und in einer Tabelle anzeigen • eBay-Query hinterlegen • Auktionen abrufen, anzeigen, speichern • später auf github.com/kpbode 9 Die Sample-App

Slide 10

Slide 10 text

Daten modellieren KPBPerson - name : String (required) - query : String (required) KPBAuction - title : String (required) - subtitle : String (optional) - image : Image (optional) - url : String (required) 10 0..1 0..*

Slide 11

Slide 11 text

Daten modellieren • Tabellen -> Entitäten • Spalten -> Attribute • Standard-Typen ( String, Integer, Bool, ... ) • Binäre Attribute (z.B. für Images) Achtung! • Eigene Serialisierung (z.B. für Arrays) -> Transformables Achtung! 11

Slide 12

Slide 12 text

Daten modellieren • Anwendungsorientiert denken • Performanceorientiert denken ‣ nur teilweise normalisieren 12

Slide 13

Slide 13 text

13 [self showCode];

Slide 14

Slide 14 text

14

Slide 15

Slide 15 text

15 Core Data initialisieren NSPersistentStoreCoordinator 7 NSManagedObjectContext NSManagedObject NSPersistentStore SQLite NSManagedObjectModel NSEntityDescription ...

Slide 16

Slide 16 text

Core Data initialisieren 16 // The model is compiled to a binary momd-File NSURL *modelURL = [mainBundle URLForResource:@"GiftIdeas" withExtension:@"momd"]; // initialized an instance of NSManagedObjectModel with this URL NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

Slide 17

Slide 17 text

Core Data initialisieren 17 // Initialize an instance of NSPersistentStoreCoordinator with the model NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel]; // URL to the location of the sqlite NSURL *documentsDirectory = [self applicationDocumentsDirectory]; NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"GiftIdeas.sqlite"]; // Add a store with the specified URL to the StoreCoordinator NSError *error = nil; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { NSLog(@"Failed to add PersistentStore: %@", [error userInfo]); }

Slide 18

Slide 18 text

Core Data initialisieren 18 //setup the managedObjectContext with the persistentStoreCoordinator NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init]; moc.persistentStoreCoordinator = persistentStoreCoordinator; // start using your managedObjectContext ...

Slide 19

Slide 19 text

Core Data initialisieren • Initialisierung in eigene Klasse auslagern • Inilialisierung als Klassenmethode für NSManagedObjectContext: • KPB_createManagedObjectContextWithS toryType: modelName: storeFileURL: • Konstanten verwenden! 19

Slide 20

Slide 20 text

Architektur KPBAppDelegate NSManagedObjectContext @property / ManagedObject KPBEditPersonViewController KPBPersonsListViewController @property [UIApplication sharedApplication].delegate 20

Slide 21

Slide 21 text

Objekte laden 21 NSManagedObjectContext NSManagedObject NSManagedObject NSManagedObject NSManagedObject ? • SELECT * FROM `persons`; • NSFetchRequest • NSFetchedResultsController

Slide 22

Slide 22 text

Objekte laden 22 // setup the basic NSFetchRequest NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; // specify how to sort the fetched data fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]; // initialize a NSFetchedResultsController to handle fetched data NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]; // register as a delegate to react to changes to the fetched data fetchedResultsController.delegate = self;

Slide 23

Slide 23 text

Objekte anzeigen 23 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [[self.fetchedResultsController sections] count]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; return [sectionInfo numberOfObjects]; }

Slide 24

Slide 24 text

Objekte anzeigen 24 - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { KPBPerson *person = [self.fetchedResultsController objectAtIndexPath:indexPath]; cell.textLabel.text = person.name; cell.detailTextLabel.text = person.query; }

Slide 25

Slide 25 text

Objekte erstellen 25 NSManagedObjectContext NSManagedObject // create and insert a new instance with the entity name into context KPBPerson *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext]; NSManagedObjectModel NSEntityDescription ...

Slide 26

Slide 26 text

26 Objekte verwalten KPBPersonsListViewController @property ... *managedObjectContext KPBEditPersonViewController @property ... *managedObjectContext @property ... KPBPerson *person Hinzufügen • neues Person-Objekt • managedObjectContext KPBPersonsListViewControllerDelegate Gespeichert Abgebrochen KPBEditPersonViewController @property ... *managedObjectContext @property ... KPBPerson *person Bearbeiten • ausgewähltes Person- Objekt • managedObjectContext

Slide 27

Slide 27 text

27

Slide 28

Slide 28 text

Lösungsansätze • Objekt als temporär markieren • ViewController-Outlets auslesen • Transferobjekte / NSDictionaries • NSUndoManager ‣ ManagedObjectContext-Snapshot erstellen und nach Bedarf verwerfen 28

Slide 29

Slide 29 text

Inhalt • Core Data 101 • App-Design • Nested ManagedObjectContexts • Datenmigration • Zusammenfassung 29

Slide 30

Slide 30 text

Nested MOCs • moc.parentContext • Child: Snapshot von Parent • ConfinementTypes • Verwendung von Queues / Threads 30 Neu

Slide 31

Slide 31 text

Core Data & Threading • ein Thread pro ManagedObjectContext • Zugriff nur mit Objekten aus dem selben ManagedObjectContext oder per objectID ‣ Probleme bei längeren Operationen, Disk-IO 31

Slide 32

Slide 32 text

Confinement-Types • NSConfinementConcurrencyType • Standard-Type / Default • NSMainQueueConcurrencyType • Main- /UI-Queue • NSPrivateQueueConcurrencyType • private Queue / Background 32

Slide 33

Slide 33 text

Nested MOCs 33 [moc performBlock:^{ // do something on this context on this queue }]; [moc performBlockAndWait:^{ // do something on this context on this queue and wait }];

Slide 34

Slide 34 text

KPBPersonListViewController KPBEditPersonViewController presents Nested MOCs NSManagedObjectContext NSManagedObjectContext parent KPBPerson Displayed in List KPBPerson Editing-Target 34 Snapshot delegate: save / cancel

Slide 35

Slide 35 text

Nested MOCs 35 // create a new managedObjectContext which is a child of the current NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; moc.parentContext = masterManagedObjectContext; ... // save if needed NSError *saveError = nil; if (![moc save:&saveError]) { NSLog(@"failed to save context: %@", saveError); } else { // persist to disk if needed by saving the root context // use a block to save the context on its own queue [masterManagedObjectContext performBlock:^{ NSError *masterSaveError = nil; if (![masterManagedObjectContext save:&masterSaveError]) { NSLog(@"failed to save master: %@", masterSaveError); } }]; }

Slide 36

Slide 36 text

36 [self showCode];

Slide 37

Slide 37 text

37

Slide 38

Slide 38 text

38 Netzwerk-Zugriff

Slide 39

Slide 39 text

39

Slide 40

Slide 40 text

40 MOC für Daten-Import

Slide 41

Slide 41 text

41

Slide 42

Slide 42 text

42 Objekte richtig übergeben

Slide 43

Slide 43 text

43

Slide 44

Slide 44 text

Performant Persistieren 44 MainContext NSMainQueueConcurrencyType NSPersistentStoreCoordinator MyDatabase.sqlite Documents-Dir ViewController

Slide 45

Slide 45 text

Performant Persistieren MasterContext NSPrivateQueueConcurrencyType MainContext NSMainQueueConcurrencyType ImportContext NSConfinementConcurrencyType NSPersistentStoreCoordinator d Änderungen werden hoch geschoben, nicht runter 45 MyDatabase.sqlite Documents-Dir

Slide 46

Slide 46 text

Hintergrund-Operationen • UI-Thread nicht blockieren! ‣ Nested ManagedObjectContexts verwenden • Objekte über objectID austauschen • Manager-Singleton? 46

Slide 47

Slide 47 text

Inhalt • Core Data 101 • App-Design • Nested ManagedObjectContexts • Datenmigration • Zusammenfassung 47

Slide 48

Slide 48 text

Datenmigration • 1.0 - Hurra! • Neue Features -> Datenmodell anpassen • Was passiert mit bestehenden Daten? ‣ Core Data to the rescue 48

Slide 49

Slide 49 text

Datenmigration 1. Automatisch / Inferred (magic) 2. Beschreibung der Migration als Modell 3. Custom Code (MigrationPolicy) 49

Slide 50

Slide 50 text

Inferred-Migration • Migration innerhalb der Datenbank mit Boardmitteln • Annahmen über die durchzuführenden Änderungen werden getroffen • alle Änderungen müssen aus dem neuen Datenmodell hervorgehen 50

Slide 51

Slide 51 text

Inferred-Migration 51 KPBPerson - name : String (required) - query : String (required) KPBAuction - title : String (required) - subtitle : String (optional) - image : Image (optional) - url : String (required) - serverId : String (optional) 0..1 0..*

Slide 52

Slide 52 text

Inferred-Migration 52 @{ NSMigratePersistentStoresAutomaticallyOption : @YES, NSInferMappingModelAutomaticallyOption : @YES };

Slide 53

Slide 53 text

53 [self showCode];

Slide 54

Slide 54 text

54

Slide 55

Slide 55 text

Mapping-Model • Anlegen per Xcode-Assistant • Mappings für Entitäten, Attribute und Beziehungen werden erstellt • Value-Expression für simples Kopieren, Rechnungen, Bedingungen • MOCs werden für die Migration erstellt -> Achtung! Speicher 55

Slide 56

Slide 56 text

Custom Code • Mapping-Model erstellen • Policy / Klassennamen für Entitätenmapping ausweisen • Migration erfolgt durch Methodenaufrufe der Subklasse 56

Slide 57

Slide 57 text

Custom Code 57 beginEntityMapping: manager: error: endEntityMapping: entityMapping: manager: error createDestinationInstancesForSourceInstance: entityMapping: manager: error endInstanceCreationForEntityMapping: entityMapping: manager: error pro Object performCustomValidationForEntityMapping: entityMapping: manager: error createRelationshipsForDestinationInstance: entityMapping: manager: error endRelationshipCreationForEntityMapping: entityMapping: manager: error pro Object

Slide 58

Slide 58 text

58 Custom Code KPBPerson - name : String (required) - query : String (required) KPBAuction - title : String (required) - subtitle : String (optional) - image : Image (optional) - url : String (required) - serverId : String (optional) 1 0..* KPBSearchKeyword - term : String (required) 1 0..* Query in Keywords umwandeln

Slide 59

Slide 59 text

59 [self showCode];

Slide 60

Slide 60 text

60

Slide 61

Slide 61 text

Datenmigration • Core Data sucht sich den kürzesten Weg -> testen, testen, testen • Inferred-Migration verwenden (wenn möglich) 61

Slide 62

Slide 62 text

Inhalt • Core Data 101 • App-Design • Nested ManagedObjectContexts • Datenmigration • Zusammenfassung 62

Slide 63

Slide 63 text

Zusammenfassung • Core Data? Trau dich! (wenn du die Kanone brauchst) • Nested Contexts? Aber ja! (möglichst ab iOS 6) • Migration? Keep it simple! 63

Slide 64

Slide 64 text

Vielen Dank die Aufmerksamkeit! 64

Slide 65

Slide 65 text

Noch Fragen? Karl Bode @karl_in kpbode@hotcoffeeapps.com 65

Slide 66

Slide 66 text

Quellen • “Core Data Programming Guide”, Apple • “Core Data for iOS”, Tim Isted und Tom Harrington • “Core Data”, Marcus S. Zarra 66