Episode #132

Realm

12 minutes
Published on August 14, 2014

This video is only available to subscribers. Get access to this video and 573 others.

Realm is a new project that aims to replace Core Data and even SQLite for mobile app persistent storage needs. While an ambitious goal, I like seeing alternatives in this area, as Core Data is not always my favorite framework. In this episode we'll add Realm to a project and store a few rudimentary objects. We'll also see a quick way to query the data in the "realm".

Episode Links

Integrating Realm in a Project

Using CocoaPods is the easiest way to add it to your project. Just add the pod "Realm" to your Podfile:

pod "Realm"

Then run pod install to install it.

Define Your Persisted Classes

Instead of inheriting from NSObject, you inherit from RLMObject. Realm automatically infers the properties to persist.

#import <Realm/Realm.h>
#import "OilChange.h"

@interface Car : RLMObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *color;
@property (nonatomic) NSInteger year;

@end

@implementation Car
@end

We can add relationships as well. Say we want our cars to have a list of oil changes. We'll start with the OilChange class.

#import <Realm/Realm.h>

@interface OilChange : RLMObject

@property (nonatomic, strong) NSDate *date;
@property (nonatomic) NSInteger mileage;

@end

@implementation OilChange

Next we need to add a property to contain these. Realm has a special type called RLMArray which needs to know what type of objects to store. We can use a built-in macro to generate a protocol for our car class, giving the collection the type information it needs.

#import <Realm/Realm.h>
#import "OilChange.h"

RLM_ARRAY_TYPE(OilChange)

@interface Car : RLMObject

// ...

@property (nonatomic, strong) RLMArray<OilChange> *oilChanges;

@end

Persisting the objects

First you need to get a reference to the realm. There is a default realm you can use, or you can name your own.

RLMRealm *realm = [RLMRealm defaultRealm];

Saving objects is done inside of a transaction:

  [realm beginWriteTransaction];

  // start with a clean slate
  [realm deleteObjects:[Car allObjects]];
  [realm deleteObjects:[OilChange allObjects]];

  Car *car = [Car new];
  car.name = @"Honda Civic";
  car.year = 1998;
  car.color = @"Black";
  [realm addObject:car];

  const NSInteger SecondsInAMonth = 60 * 60 * 24 * 30;
  NSDate *lastDate = [NSDate date];
  int mileage = 0;
  for (int d = 48; d >= 0; d--) {
    NSDate *date = [lastDate dateByAddingTimeInterval:- d * SecondsInAMonth];
    lastDate = date;
    mileage += 3000;
    OilChange *change = [OilChange new];
    change.date = date;
    change.mileage = mileage;
    [car.oilChanges addObject:change];
  }

  [realm commitWriteTransaction];

Querying for objects

Getting all objects is simple:

  RLMArray *cars = [Car allObjectsInRealm:realm];
  NSLog(@"Found: %@", cars);

You can use simple predicates as to narrow down results:

  NSLog(@"Cars staring with B: %@",
        [Car objectsWhere:@"name beginswith 'B'"]
        );

  NSLog(@"Oil changes since 100k miles: %@",
        [OilChange objectsWhere:@"mileage > 100000"]
        );