Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using Realm for data persistence: a comparison with Core Data

Using Realm for data persistence: a comparison with Core Data

joshuadutton

April 16, 2015
Tweet

More Decks by joshuadutton

Other Decks in Programming

Transcript

  1. U S I N G R E A L M

    F O R D ATA P E R S I S T E N C E : A C O M PA R I S O N W I T H C O R E D ATA J O S H U A D U T T O N : M O B I L E D E V E L O P E R A N D C . T. O . A T H I T L A B S Cactus Charro by Daniel Garrido A P R I L 1 6 , 2 0 1 5
  2. W H Y I S TA R T E D

    U S I N G R E A L M , E N D E D U P U S I N G C O R E D ATA , B U T WA N T T O M O V E B A C K T O R E A L M J O S H U A D U T T O N : M O B I L E D E V E L O P E R A N D C . T. O . A T H I T L A B S Cactus Charro by Daniel Garrido A P R I L 1 6 , 2 0 1 5
  3. W H AT I S C O R E D

    ATA ? • Object graph • XML, Binary, or SQLite data stores • Change management, serializing to disk, and queries • Extremely flexible, but somewhat confusing API X-Ray Bukethead by Daniel Garrido
  4. A N O T E O N L E A

    R N I N G C O R E D ATA • DON’T: • Use a 3rd party library to try to simplify your code (like Magical Record) • Use a singleton (global state can cause problems) • Rely only on Apple’s Core Data Programming Guide X-Ray Bukethead by Daniel Garrido
  5. A N O T E O N L E A

    R N I N G C O R E D ATA • DO: • Read these tuts+ tutorials (Core Data From Scratch): 
 http://code.tutsplus.com/series/core-data-from-scratch--cms-653 • Write your own categories/helpers for boiler plate code. You can use Robert Brown’s code to learn from:
 https://github.com/rob-brown/RBCoreDataStack • Explicitly state which Managed Object Context you are using (for example, don’t have helper methods that assume you are using your main context) • Read this blog post about a good core data setup:
 http://martiancraft.com/blog/2015/03/core-data-stack/ X-Ray Bukethead by Daniel Garrido
  6. X-Ray Bukethead by Daniel Garrido W H AT I S

    R E A L M ? • A NO-SQL database written specifically for mobile • Cross platform (written in C++ with Cocoa and Java interfaces) • Simple API
  7. W R I T I N G : C O

    R E D ATA • All objects (NSManagedObjects) belong to a Managed Object Context. • The Managed Object Context keeps track of changes. Some people call Managed Object Contexts “scratch pads”. • All changes are persisted to disk when the Managed Object Context is saved to the Persistent Store. Flying Taco by Daniel Garrido
  8. W R I T I N G : C O

    R E D ATA // Skipping over lots of boiler plate code to setup the main context // and the persistent store coordinator Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.mainContext]; person.name = @"Joshua"; // Sometime later save the Managed Object Context to the Persistent Store // Many do this when the app quits or goes to the background NSError *error; BOOL success = [self.mainContext save:&error]; Flying Taco by Daniel Garrido
  9. W R I T I N G : R E

    A L M Flying Taco by Daniel Garrido • All objects belong to a Realm (think of a Realm as it’s own database file). • All changes to an object (addition, modification and deletion) have to be done within a write transaction. • Write transactions are atomic and thread safe. This also means that they can block the thread, particularly if several write transactions are queued. • Changes are persisted immediately and available on all threads.
  10. Flying Taco by Daniel Garrido W R I T I

    N G : R E A L M // Adding a new object Person *person = [Person new]; person.name = @"Joshua"; // Get the default Realm RLMRealm *realm = [RLMRealm defaultRealm]; // You only need to do this once (per thread) [realm beginWriteTransaction]; [realm addObject:person]; [realm commitWriteTransaction]; // Or [realm transactionWithBlock:^{ [realm addObject:person]; }];
  11. Flying Taco by Daniel Garrido W R I T I

    N G : R E A L M // Update an object with a transaction [realm beginWriteTransaction]; person.name = @"Joshua"; [realm commitWriteTransaction]; // Delete an object with a transaction [realm beginWriteTransaction]; [realm deleteObject:person]; [realm commitWriteTransaction];
  12. F E T C H I N G : C

    O R E D ATA NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@“Person"]; fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH[c] %@", prefix]; fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]; NSError *error; NSArray *results = [self.mainContext executeFetchRequest:fetchRequest error:&error]; Nestereo by Daniel Garrido
  13. Nestereo by Daniel Garrido F E T C H I

    N G : C O R E D ATA • Two ways to conserve memory: 1. Array with NSManagedObjects that are faults (persistent variables are not yet initialized) 2. NSFetchResultsController: optimized for displaying fetch results in a table view or collection view.
  14. Nestereo by Daniel Garrido F E T C H I

    N G : R E A L M RLMResults *results = [[Person objectsWhere:@"name BEGINSWITH[c] %@", prefix] sortedResultsUsingProperty:@"name" ascending:YES];
  15. Nestereo by Daniel Garrido RLMResults • Kind of like a

    NSFetchRequest with a simple array interface to access the results • Lazy loads • Able to chain queries • Gotcha: results aren’t cached and objects can change (though in the future, results will be frozen during fast enumeration: 
 https://github.com/realm/realm-cocoa/issues/1179)
  16. Nestereo by Daniel Garrido RLMResults: iteration for (Person *person in

    [Person allObjects]) { // do something with the person }
  17. Nestereo by Daniel Garrido RLMResults: chaining queries RLMResults *peopleWithNamePrefix =

    [[Person objectsWhere:@"name BEGINSWITH[c] %@", prefix] sortedResultsUsingProperty:@"name" ascending:YES]; RLMResults *femalesWithNamePrefix = [peopleWithNamePrefix objectsWhere:@"gender == 'female'"];
  18. Hippy Happy Duck by Daniel Garrido C O N C

    U R R E N C Y: C O R E D ATA • You can’t pass a Managed Object Context across multiple threads • You can’t pass a Managed Object across multiple threads (you need to query for it or access it by objectId) • Since Managed Object Contexts don’t usually persist to the store immediately, you need a way to sync changes from a context on one thread to a context on another: • Change notifications • Parent/child contexts
  19. Hippy Happy Duck by Daniel Garrido C O N C

    U R R E N C Y: R E A L M • You can use the same Realm on multiple threads, but you need to access it separately on each thread • You can’t pass a Realm Object across multiple threads (you need to query for it or access it by primary key) • Since write transactions are atomic, you don’t need to sync changes
  20. Hippy Happy Duck by Daniel Garrido C O N C

    U R R E N C Y: R E A L M dispatch_async(backgroundQueue, ^{ // Get realm for this thread RLMRealm *realm = [RLMRealm defaultRealm]; Person *person = [Person objectForPrimaryKey:key]; [realm beginWriteTransaction]; person.name = @"William"; // Commit the write transaction // to make this data available to other threads [realm commitWriteTransaction]; });
  21. Hippy Happy Duck by Daniel Garrido C O N C

    U R R E N C Y: R E A L M // Observe Realm notifications for changes on other threads self.token = [realm addNotificationBlock:^(NSString *note, RLMRealm * realm) { [myViewController updateUI]; }]; // Notifications are currently very limited // You are notified that a realm has changed, but not what the changes are // Fine-grained notifications are "coming soon"
  22. R E A L M : O T H E

    R F E AT U R E S • Encryption • In memory realms • Cross-platform Realm files • Migrations • Realm Browser • Sharing Realms between processes (Apple Watch and Extensions) Sombrero Bip-Bop by Daniel Garrido
  23. Sombrero Bip-Bop by Daniel Garrido R E A L M

    : A D VA N TA G E S • Fast • Simple API • Follows the fail fast principle • Easy to manage concurrency • Active and helpful development team (Github, Stack Overflow, Twitter, Google Group) • Cross platform
  24. Sombrero Bip-Bop by Daniel Garrido R E A L M

    : C U R R E N T L I M I TAT I O N S • Still in beta • No fine-tuned notifications (duplicating NSFetchedResultsController is hard)
 - fix coming soon • Does not support KVO
 - fix coming soon • NSDate is truncated to second (use NSTimeInterval instead) 
 - fix coming soon • Does not support nil properties (NSString, NSData, NSNumber, etc.)
 - fix coming soon • Doesn’t support as many types of queries as Core Data or SQLite
 - they plan on supporting more in the future