cocoaheads toulouse - getting to the core of core data

75
Introduction à CoreData Partie 1 Jérome Alves Romain Briche Michel Moreau

Upload: cocoaheads-france

Post on 06-Jul-2015

2.432 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CocoaHeads Toulouse - Getting to the core of Core Data

Introduction à CoreData

Partie 1

Jérome AlvesRomain BricheMichel Moreau

Page 2: CocoaHeads Toulouse - Getting to the core of Core Data

Partie 1

• Présentation des concepts

• Intégration

• Modélisation

• Utilisation basique

Page 3: CocoaHeads Toulouse - Getting to the core of Core Data

Partie 11

• Concepts avancés

• Contextes multi-thread

• Migrations

• Performance

Page 4: CocoaHeads Toulouse - Getting to the core of Core Data

Introduction

Page 5: CocoaHeads Toulouse - Getting to the core of Core Data

Introduction

• Qu’est-ce que CoreData

• Framework de gestion de persistance

Page 6: CocoaHeads Toulouse - Getting to the core of Core Data

Introduction

• Qu’est-ce que CoreData

• Framework de gestion de persistance

• Techniques de gestion de persistance

• Fichiers

• Property List

• SQL

Page 7: CocoaHeads Toulouse - Getting to the core of Core Data

Eléments fondamentaux

Page 8: CocoaHeads Toulouse - Getting to the core of Core Data

Eléments fondamentaux

Entités

Page 9: CocoaHeads Toulouse - Getting to the core of Core Data

Eléments fondamentaux

EntitésAttributs

Page 10: CocoaHeads Toulouse - Getting to the core of Core Data

Eléments fondamentaux

Entités

Relations

Attributs

Page 11: CocoaHeads Toulouse - Getting to the core of Core Data

Types de données

non-persistant persistant

Type de base NSObject NSManagedObject

Attributs * * (mais c’est compliqué)

Méthodes * *

Page 12: CocoaHeads Toulouse - Getting to the core of Core Data

La pile CoreData

Page 13: CocoaHeads Toulouse - Getting to the core of Core Data

La pile CoreData

Managed Object Model

A collection of entity descriptions

Page 14: CocoaHeads Toulouse - Getting to the core of Core Data

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

Page 15: CocoaHeads Toulouse - Getting to the core of Core Data

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

Persistent Store Coordinator

A collection of stores

Page 16: CocoaHeads Toulouse - Getting to the core of Core Data

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

Persistent Store Coordinator

A collection of stores

Persistent Object Store

A collection of object data

Page 17: CocoaHeads Toulouse - Getting to the core of Core Data

La pile CoreDataManaged Object Context

A collection of managed objects

Managed Object Model

A collection of entity descriptions

Persistent Store Coordinator

A collection of stores

Persistent Object Store

A collection of object data

Store File

Page 18: CocoaHeads Toulouse - Getting to the core of Core Data

La pile CoreData

Page 19: CocoaHeads Toulouse - Getting to the core of Core Data

Core Data vs MVC

Model

Controller View

Page 20: CocoaHeads Toulouse - Getting to the core of Core Data

CoreData

Core Data vs MVC

Model

Controller View

Page 21: CocoaHeads Toulouse - Getting to the core of Core Data

Mo

de

l

CoreData

Core Data vs MVC

Model

Controller View

Page 22: CocoaHeads Toulouse - Getting to the core of Core Data

Mo

de

l

CoreData

Core Data vs MVC

Model

Controller View

Cloud

Page 23: CocoaHeads Toulouse - Getting to the core of Core Data

Création du modèle

Page 24: CocoaHeads Toulouse - Getting to the core of Core Data

Fichier .xcdatamodel

Page 25: CocoaHeads Toulouse - Getting to the core of Core Data

Le Model Editor

Page 26: CocoaHeads Toulouse - Getting to the core of Core Data

Création d’entités

Page 27: CocoaHeads Toulouse - Getting to the core of Core Data

Créations d’attributs

Page 28: CocoaHeads Toulouse - Getting to the core of Core Data

Types d’attributs

‣Non défini‣Entiers‣Décimal- plus précis‣Double‣Flottant

‣Chaîne de caractères‣Booléen‣Date‣Binaire‣Transformable

Page 29: CocoaHeads Toulouse - Getting to the core of Core Data

Propriétés‣Optionnel‣Transcient- non persisté- requiert accesseurs- mofications observables- migration facile‣Indexé- performance

Page 30: CocoaHeads Toulouse - Getting to the core of Core Data

Relations

Page 31: CocoaHeads Toulouse - Getting to the core of Core Data

Relations inverses

Page 32: CocoaHeads Toulouse - Getting to the core of Core Data

Règles de suppression

‣Pas d’action‣Nullité‣Cascade‣Déni- impossible de supprimé si la relation existe encore

Page 33: CocoaHeads Toulouse - Getting to the core of Core Data

Propriétés avancées

‣Fetched properties‣Fetch requets

Page 34: CocoaHeads Toulouse - Getting to the core of Core Data

Et maintenant?

Page 35: CocoaHeads Toulouse - Getting to the core of Core Data

Exemple d’utilisation// Créer de la requêteNSManagedObjectContext *moc = [self managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];[request setEntity:[NSEntityDescription entityForName:@"Enfant" inManagedObjectContext:moc]];

// Récupération d’un objetNSError *error = nil;NSManagedObject *enfant = [[moc executeFetchRequest:request error:&error] lastObject];[request release];

// Création d’un objet if (!enfant) { enfant = [NSEntityDescription insertNewObjectForEntityForName:@"Enfant" inManagedObjectContext:moc];}

// Passage de valeur[enfant setValue:@"Harry" forKey:@"prenom"];[enfant setValue:@"Potter" forKey:@"nom"];

Page 36: CocoaHeads Toulouse - Getting to the core of Core Data

KVC‣Accès “générique” à un attribut d’un objet- exemple: attribut “prenom” de l’objet “enfant”‣Binding pendant le Runtime- nom de l’attribut non connu au moment de la compilation- Erreur “Unknown value for key ...”‣Logique- Cherche pour un accesseur- Cherche pour une variable- Cherche valueForUndefinedKey:/setValueForUndefinedKey:‣Compatibilité- OBJ-C 2.0 @property/@synthesize

Page 37: CocoaHeads Toulouse - Getting to the core of Core Data

KVO

‣Notifications- exemple: changement de la valeur d’un attribut‣Méthodes- willAccessValueForKey: / didAccessValueForKey:- willChangeValueForKey: / didChangeValueForKey:- ...

Page 38: CocoaHeads Toulouse - Getting to the core of Core Data

KVO/KVC

‣NSObject -> OK‣NSManagedObject -> !OK

Page 39: CocoaHeads Toulouse - Getting to the core of Core Data

Intérêt Sous-Classe

‣Compatible KVC- prenom- setPrenom:- ...‣Création de classes personnalisées- nomComplet- ...

Page 40: CocoaHeads Toulouse - Getting to the core of Core Data

Sous-classes

Page 41: CocoaHeads Toulouse - Getting to the core of Core Data

Sous-classes

Page 42: CocoaHeads Toulouse - Getting to the core of Core Data

Header

@class Parent;

@interface Enfant : NSManagedObject {@private// Pas de variables}@property (nonatomic, retain) NSString * nom;@property (nonatomic, retain) NSString * prenom;@property (nonatomic, retain) NSDate * dateNaissance;@property (nonatomic, retain) NSSet* parents;

@end

Page 43: CocoaHeads Toulouse - Getting to the core of Core Data

Implementation#import "Enfant.h"#import "Parent.h"

@implementation Enfant@dynamic nom, prenom, dateNaissance, parents;

- (void)addParentsObject:(Parent *)value { NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; [self willChangeValueForKey:@"parents" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [[self primitiveValueForKey:@"parents"] addObject:value]; [self didChangeValueForKey:@"parents" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [changedObjects release];}

- (void)removeParentsObject:(Parent *)value {...}- (void)addParents:(NSSet *)value {...}- (void)removeParents:(NSSet *)value {...}

@end

Page 44: CocoaHeads Toulouse - Getting to the core of Core Data

Sous-classes

Page 45: CocoaHeads Toulouse - Getting to the core of Core Data

Exemple d’utilisation// Créer de la requêteNSManagedObjectContext *moc = [self managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];[request setEntity:[NSEntityDescription entityForName:@"Enfant" inManagedObjectContext:moc]];

// Récupération d’un objetNSError *error = nil;Enfant *enfant = [[moc executeFetchRequest:request error:&error] lastObject];[request release];

// Création d’un objet if (!enfant) { enfant = [NSEntityDescription insertNewObjectForEntityForName:@"Enfant" inManagedObjectContext:moc];}

// Passage de valeur[enfant setPrenom:@"Harry"];[enfant setNom:@"Potter"];

Page 46: CocoaHeads Toulouse - Getting to the core of Core Data

NE PAS “OVERRIDER”

‣-init- ne fonctionne pas comme -init de NSObject- modifie la structure mais les données sont absentes‣-dealloc- Ne se produit pas quand espéré- Core Data “gère la gestion mémoire” au sein de la classe

Page 47: CocoaHeads Toulouse - Getting to the core of Core Data

ALTERNATIVES

‣-awakeFromInsert- lors de la création- appelée 1 seule et unique fois‣-awakeFromFetch- appelée à chaque fois que l’objet est retourné (non créé)‣-willTurnIntoFault- appelée lors que l’objet est réellement détruit‣...- voir la documentation

Page 48: CocoaHeads Toulouse - Getting to the core of Core Data

Attention à la modification du modèle

Page 49: CocoaHeads Toulouse - Getting to the core of Core Data

Démo

Page 50: CocoaHeads Toulouse - Getting to the core of Core Data

Opérations de base

• Ajouter un élément

• Supprimer un élément

• Créer une requête

• Prédicat

• Sort Descriptor

• Sauvegarde

Page 51: CocoaHeads Toulouse - Getting to the core of Core Data

Insertion d’élément

// Demande de création d’un managedObject au contexte, dans une entité précise

Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext];

Page 52: CocoaHeads Toulouse - Getting to the core of Core Data

Suppression d’élément// Obtenir l’objet a supprimerNSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];

// Demande de suppresion au contexte[managedObjectContext deleteObject:eventToDelete];

Page 53: CocoaHeads Toulouse - Getting to the core of Core Data

Les requêtes

• Une requête :

• Un prédicat

• Un sortDescriptor

• Execution

Page 54: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Page 55: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Prédicat

Page 56: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Prédicat

Page 57: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Prédicat

SortDescriptor

Page 58: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Page 59: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Page 60: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Entité

Page 61: CocoaHeads Toulouse - Getting to the core of Core Data

Requête

Les requêtes

Prédicat

SortDescriptorSortDescriptorSortDescriptorSortDescriptorSortDescriptor

Entité

Page 62: CocoaHeads Toulouse - Getting to the core of Core Data

Les requêtes

// Créer de la requêteNSFetchRequest *request = [[NSFetchRequest alloc] init];

// Obtenir l’entitéNSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];

[request setEntity:entity];

// Créer un prédicatNSPredicate *predicate = [NSPredicate predicateWithFormat:    @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];

[request setPredicate:predicate];

Page 63: CocoaHeads Toulouse - Getting to the core of Core Data

Les requêtes// Créer un sortDescriptorNSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey: @"creationDate" ascending:NO];

NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

[request setSortDescriptors:sortDescriptors];

[sortDescriptors release];[sortDescriptor release];

// Exécuter la requêteNSError *error = nil;NSArray *array = [moc executeFetchRequest:request error:&error];

if (array == nil){    // Deal with error...}

Page 64: CocoaHeads Toulouse - Getting to the core of Core Data

Sauvegarde du contexte

Managed Object Context

Managed Object ModelPersistent Store Coordinator

Persistent Object Store

MOMO

MOMO

MO

Store File

Page 65: CocoaHeads Toulouse - Getting to the core of Core Data

Sauvegarde du contexte

Managed Object Context

Managed Object ModelPersistent Store Coordinator

Persistent Object Store

MOMOMOMOMO

Store File

Page 66: CocoaHeads Toulouse - Getting to the core of Core Data

Sauvegarde du contexte

// NSError *error = nil;

if (![managedObjectContext save:&error]) {

// Handle the error.

}

Page 67: CocoaHeads Toulouse - Getting to the core of Core Data

Démo

Page 68: CocoaHeads Toulouse - Getting to the core of Core Data

NSFetchedResultsController‣Seulement pour iOS- Pas (encore) sur Mac‣Observations des changements- Notifie le contrôleur qu’il doit rafraîchir l’UI- Notifications sélectives => meilleure performance- Objets/propriétés‣-willTurnIntoFault- appelée lors que l’objet est réellement détruit‣...- voir la documentation

Page 69: CocoaHeads Toulouse - Getting to the core of Core Data

Trève de blabla

@interface ViewController : UITableViewController <NSFetchedResultsControllerDelegate> {" NSFetchedResultsController *fetchedResultsController;" NSManagedObjectContext *moc;}

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;@property (nonatomic, retain) NSManagedObjectContext *moc;

Page 70: CocoaHeads Toulouse - Getting to the core of Core Data

- (NSFetchedResultsController*)fetchedResultsController { if (_fetchedResultsController) return _fetchedResultsController; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Enfant" inManagedObjectContext:[self moc]]; [fetchRequest setEntity:entity]; [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"nom==%@",@"Potter"]]; [fetchRequest setFetchBatchSize:20]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"prenom" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; NSFetchedResultsController *frc = nil; frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self moc] sectionNameKeyPath:nil cacheName:@"Potter"]; [frc setDelegate:self]; [self setFetchedResultsController:frc]; [frc release], frc = nil; [fetchRequest release], fetchRequest = nil; [sortDescriptor release], sortDescriptor = nil; [sortDescriptors release], sortDescriptors = nil; return _fetchedResultsController;}

Page 71: CocoaHeads Toulouse - Getting to the core of Core Data

NSFetchedResultsControllerDelegate

‣ -controllerWillChangeContent: ‣ -controller:didChangeSection:atIndex:forChangeType:‣ -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:‣ -controllerDidChangeContent:

Page 72: CocoaHeads Toulouse - Getting to the core of Core Data

NSFetchedResultsControllerDelegate

Page 73: CocoaHeads Toulouse - Getting to the core of Core Data

Pour aller plus loin

‣Les opérations- @sum, @distincUnionOfSets, etc...‣Les migrations- automatique, mapping model, manuelle‣Notions avancées- multi-threading, données binaire, faulting, synchronisation‣Performance‣Nouveautés iOS5- iCloud, concurrence, protection, …

Page 74: CocoaHeads Toulouse - Getting to the core of Core Data

Suggestions de ressources

Nouveautés iOS5iCloud, concurrence, protection, …

Page 75: CocoaHeads Toulouse - Getting to the core of Core Data

Merci