Core Data iz iPhone vidika Matej Bukovinski www.bukovinski.com sreda, 16. december 2009
Nov 18, 2014
Core Dataiz iPhone vidika
Matej Bukovinskiwww.bukovinski.com
sreda, 16. december 2009
Agenda
• Malo teorije (z kodo)
• Malo prakse (preprost Xcode demo)
• Q&A
sreda, 16. december 2009
Core Data1. del, Teorija
sreda, 16. december 2009
Core data
• Mehanizmi za upravljaje z objektnim grafom in življenjskim ciklom objektov
• Zagotavlja trajnost podatkov (presistence)
• Enostavnejši način za ravnanje z MVC Model objekti
• Framework (CoreData.framework)
• Sestavni del Cocoa API-ja od Mac OS X 10.4
• Sestavni del Cocoa-touch od iPhone OS 3.0
sreda, 16. december 2009
Prednosti
• Model objekte preprosto narišemo (z relacijami!) v entitetnem modelu (včasih popolnoma brez kode)
• Znebimo se ogromno kode za zagotavljanje trajnosti podatkov (nalaganje, shranjevanje,...)
• Učinkovitost (hitrejše in pogosto manj pomnilniško zahtevno kot direktni SQL pristop)
• Priročne metode za poizvedovanje in optimizacijo
• Faulting (povezani objekt se po potrebi samodejno naloži)
• Undo manager
sreda, 16. december 2009
Slabosti
• Nekateri (Aaron) imajo rajši popolni nadzor nad tem kaj se dogaja z objekti v ozadju
sreda, 16. december 2009
Core Data sklad
NSPresistentStore
NSPresistentStoreCoordinator
NSManagedObjectContext
Entitetni model
Podatkovna shramba (npr. SQLite)
NSManagedObjectNSManagedObject
NSManagedObjectNSManagedObject
sreda, 16. december 2009
Core Data sklad
NSPresistentStore
NSPresistentStoreCoordinator
NSManagedObjectContext
Entitetni model
Podatkovna shramba (SQL, ...)
NSManagedObjectNSManagedObject
NSManagedObjectNSManagedObject
sreda, 16. december 2009
Core Data, uporaba v praksi
NSManagedObjectContext
Entitetni model
NSManagedObjectNSManagedObject
NSManagedObjectNSManagedObject
1 2
• Narišemo (ali spišemo) entitetni model, ki predstavlja naše poslovne objekte
• Tu določimo entitete, razmerja med njimi entitetami, atibute, omejitve...
• Po potrebi generiramo izvorno kodo v kateri lahko dodajamo dodatno logiko modelnim objektov
• Nad NSManagedObjectContext izvajamo splošne operacije (shranjevanje, nalaganje, dodajanje modelnih objektov)
• Poizvedbe oblikujemo z NSFechRequest (podobno kot SQL)
• Entitete so predstavljene z objekti, ki dedujejo od NSManagedObject, z njimi ravnamo kot z običajnimi Objective-C objekti
NSFetchRequest
+
sreda, 16. december 2009
Inicializacija
1. Naložimo entitetni model (NSManagedObjectModel)
2. Ustvarimo koordinatorja (NSPresistentStore-Coordinator) in ga povežemo z modelom
3. Dodamo shrambo (NSPresistentStore)
4. Ustvarimo kontekst (NSManagedObjectContext) in ga povežemo s koordinatorjem
sreda, 16. december 2009
Inicializacija
1. Naložimo entitetni model (NSManagedObjectModel)
2. Ustvarimo koordinatorja (NSPresistentStore-Coordinator) in ga povežemo z modelom
3. Dodamo shrambo (NSPresistentStore)
4. Ustvarimo kontekst (NSManagedObjectContext) in ga povežemo s koordinatorjem
Če izberemo pravi Xcode template je to za nas že poskrbljeno!
sreda, 16. december 2009
Nalaganje iz shrambe
// Ustvarimo fetch request (poizvedba)NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];// Povemo katera entiteta nas zanimaNSEntityDescription *entity = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.managedObjectContext];[fetchRequest setEntity:entity];// Povemo kako želimo sortirati (opcijsko)NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES] autorelease];NSArray *sortDescriptors = [[NSArray arraytWithObjects:sortDescriptor, nil];[fetchRequest setSortDescriptors:sortDescriptors];// Naredimo poizvedbo in s tem ustvarimo naše objekteNSError *error;NSArray *songs = [managedObjectContext executeFetchRequest:request error:&error];
sreda, 16. december 2009
Nalaganje iz shrambe
// Ustvarimo fetch request (poizvedba)NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];// Povemo katera entiteta nas zanimaNSEntityDescription *entity = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.managedObjectContext];[fetchRequest setEntity:entity];// Povemo kako želimo sortirati (opcijsko)NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES] autorelease];NSArray *sortDescriptors = [[NSArray arraytWithObjects:sortDescriptor, nil];[fetchRequest setSortDescriptors:sortDescriptors];// Naredimo poizvedbo in s tem ustvarimo naše objekteNSError *error;NSArray *songs = [managedObjectContext executeFetchRequest:request error:&error];
sreda, 16. december 2009
Nalaganje iz shrambe
// Ustvarimo fetch request (poizvedba)NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];// Povemo katera entiteta nas zanimaNSEntityDescription *entity = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.managedObjectContext];[fetchRequest setEntity:entity];// Povemo kako želimo sortirati (opcijsko)NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES] autorelease];NSArray *sortDescriptors = [[NSArray arraytWithObjects:sortDescriptor, nil];[fetchRequest setSortDescriptors:sortDescriptors];// Naredimo poizvedbo in s tem ustvarimo naše objekteNSError *error;NSArray *songs = [managedObjectContext executeFetchRequest:request error:&error];
sreda, 16. december 2009
Nalaganje iz shrambe
// Ustvarimo fetch request (poizvedba)NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];// Povemo katera entiteta nas zanimaNSEntityDescription *entity = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.managedObjectContext];[fetchRequest setEntity:entity];// Povemo kako želimo sortirati (opcijsko)NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES] autorelease];NSArray *sortDescriptors = [[NSArray arraytWithObjects:sortDescriptor, nil];[fetchRequest setSortDescriptors:sortDescriptors];// Naredimo poizvedbo in s tem ustvarimo naše objekteNSError *error;NSArray *songs = [managedObjectContext executeFetchRequest:request error:&error];
sreda, 16. december 2009
Shranjevanje sprememb
NSError *error;// Če ni sprememb ni potrebno shranjevatiif ([managedObjectContext hasChanges]) {$ // Shranjevanje vseh sprememb - 1 vrstica kode!$ if (![managedObjectContext save:&error]) {$ $ // Poskrbi za napako$ }}
sreda, 16. december 2009
Shranjevanje sprememb
NSError *error;// Če ni sprememb ni potrebno shranjevatiif ([managedObjectContext hasChanges]) {$ // Shranjevanje vseh sprememb - 1 vrstica kode!$ if (![managedObjectContext save:&error]) {$ $ // Poskrbi za napako$ }}
sreda, 16. december 2009
Dodajanje novih objektov
// Ponavadi uporabljamo NSEntityDescription za ustvarjanje novih entitetSong *newSong = [NSEntityDescription$ $ $ $ $ insertNewObjectForEntityForName:@"Song"$ $ $ $ $ inManagedObjectContext:self.managedObjectContext];// Sedaj imamo Objective-C objekt, ki je umeščen v kontekst // Z njim ravnamo kot z vsemi drugimi objektinewSong.title = @"Yellow Submarine";
sreda, 16. december 2009
Dodajanje novih objektov
// Ponavadi uporabljamo NSEntityDescription za ustvarjanje novih entitetSong *newSong = [NSEntityDescription$ $ $ $ $ insertNewObjectForEntityForName:@"Song"$ $ $ $ $ inManagedObjectContext:self.managedObjectContext];// Sedaj imamo Objective-C objekt, ki je umeščen v kontekst // Z njim ravnamo kot z vsemi drugimi objektinewSong.title = @"Yellow Submarine";
sreda, 16. december 2009
Brisanje objektov
// Samo podamo konkretno “Song” instanco[self.managedObjectContext deleteObject:song];
sreda, 16. december 2009
NSFetchedResultsController
• Poenostavlja delo z UITableView pri uporabi Core Data
• Podamo NSFetchRequest, način sortiranja in grupiranja
• V UITableViewDataSource metodah kličemo metode na NSFetchedResultsContoller-ju in dobimo potrebne podatke za populacijo tabele
• Učinkovito (nalaganje v skupinah, sprostitev nevidnih objektov, uporaba predpomnjenja)
sreda, 16. december 2009
NSFetchedResultsController inicializacija// Pred tem ustrezno pripravimo fetchRequestself.fetchController = [[[NSFetchedResultsController alloc]$ $ $ $ $ $ initWithFetchRequest:fetchRequest$ $ $ $ $ $ managedObjectContext:self.managedObjectContext$ $ $ $ $ $ sectionNameKeyPath:@"artist"$ $ $ $ $ $ cacheName:@"songsCache"] autorelease];
NSError *error;BOOL success = [self.fetchController performFetch:&error];
if (!success) {$ // Napaka..}
sreda, 16. december 2009
NSFetchedResultsController inicializacija// Pred tem ustrezno pripravimo fetchRequestself.fetchController = [[[NSFetchedResultsController alloc]$ $ $ $ $ $ initWithFetchRequest:fetchRequest$ $ $ $ $ $ managedObjectContext:self.managedObjectContext$ $ $ $ $ $ sectionNameKeyPath:@"artist"$ $ $ $ $ $ cacheName:@"songsCache"] autorelease];
NSError *error;BOOL success = [self.fetchController performFetch:&error];
if (!success) {$ // Napaka..}
sreda, 16. december 2009
NSFetchedResultsController uporaba (1 od 2)- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {$ // Hrošč pri 3.0, glej NSFetchedResultsController dokumentacijo, 3.1 OK$ return [[self.fetchController sections] count];}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {$ id <NSFetchedResultsSectionInfo> sectionInfo = $ $ $ [[fetchController sections] objectAtIndex:section];$ return [sectionInfo numberOfObjects];}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {$ $ id <NSFetchedResultsSectionInfo> sectionInfo = $ $ $ [[fetchController sections] objectAtIndex:section]; return [sectionInfo name];}
sreda, 16. december 2009
NSFetchedResultsController uporaba (1 od 2)- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {$ // Hrošč pri 3.0, glej NSFetchedResultsController dokumentacijo, 3.1 OK$ return [[self.fetchController sections] count];}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {$ id <NSFetchedResultsSectionInfo> sectionInfo = $ $ $ [[fetchController sections] objectAtIndex:section];$ return [sectionInfo numberOfObjects];}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {$ $ id <NSFetchedResultsSectionInfo> sectionInfo = $ $ $ [[fetchController sections] objectAtIndex:section]; return [sectionInfo name];}
sreda, 16. december 2009
NSFetchedResultsController uporaba (1 od 2)- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {$ // Hrošč pri 3.0, glej NSFetchedResultsController dokumentacijo, 3.1 OK$ return [[self.fetchController sections] count];}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {$ id <NSFetchedResultsSectionInfo> sectionInfo = $ $ $ [[fetchController sections] objectAtIndex:section];$ return [sectionInfo numberOfObjects];}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {$ $ id <NSFetchedResultsSectionInfo> sectionInfo = $ $ $ [[fetchController sections] objectAtIndex:section]; return [sectionInfo name];}
sreda, 16. december 2009
NSFetchedResultsController uporaba (2 od 2)- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
$ static NSString *CellIdentifier = @"SongCell";$ UITableViewCell *cell = [tableView $ $ $ dequeueReusableCellWithIdentifier:CellIdentifier];
$ if (cell == nil) {$ $ cell = [[[UITableViewCell alloc] $ $ $ $ initWithStyle:UITableViewCellStyleSubtitle $ $ $ $ reuseIdentifier:CellIdentifier] autorelease];$ }$ Song *song = (Song *)[fetchController objectAtIndexPath:indexPath];$ cell.textLabel.text = song.title;$ cell.detailTextLabel.text = song.genre;$ return cell;}
sreda, 16. december 2009
Core Data2. del, Praksa - demo time
sreda, 16. december 2009
Core Data3. del, Q&A
sreda, 16. december 2009