Top 10 Core Data Tools and Libraries

We’ve compiled a list of the top 10 core data tools and libraries, making it even easier to work with Core Data. By Matthew Morey.

Leave a rating/review
Save for later
Share

Core Data is a great choice for persisting and querying data in your iOS and OSX apps. Not only can it reduce memory usage and improve performance, but it can also save you from writing a lot of unnecessary boilerplate code.

In addition, the Core Data API is extremely flexible, which allows it to be used in a myriad of apps, all with different data storage requirements.

However, this flexibility means that sometimes Core Data can be slightly difficult to work with. Even if you’re a Core Data guru, there’s still a lot of mundane tasks required, and a lot of room to make silly errors.

Luckily, there are a lot of great tools that can help you out and make Core Data significantly easier to work with. Here are our top 10 picks that you should know and love!

Also note this article has an Objective-C focus since most Core Data libraries are written in Objective-C at the moment. If you want to learn how to use Core Data with Swift, check out our upcoming book Core Data by Tutorials, which is fully updated for iOS 8 and Swift!

Note: Even with these great tools and libraries, you’ll still need a good understanding of Core Data to reap their benefits. If you need a some more experience with Core Data, check out our beginner tutorial.

Also note this article has an Objective-C focus since most Core Data libraries are written in Objective-C at the moment. If you want to learn how to use Core Data with Swift, check out our upcoming book Core Data by Tutorials, which is fully updated for iOS 8 and Swift!

10. RestKit

RestKit is an Objective-C framework for interacting with RESTful web services. It provides a Core Data entity mapping engine that maps serialized response objects directly to managed objects.

The code example below shows you how to set up RestKit to access the OpenWeatherMap API and map the JSON response of the /weather endpoint into a WFWeather managed object:

- (void)loadForecastData {
  RKManagedObjectStore *store = self.managedObjectStore;
  
  // 1
  RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"WFWeather"
                                                 inManagedObjectStore:store];
  [mapping addAttributeMappingsFromArray:@[@"temp", @"pressure", @"humidity"]];
  
  // 2
  NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
  RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor
                                              responseDescriptorWithMapping:mapping
                                              method:RKRequestMethodGET
                                              pathPattern:@"/data/2.5/weather"
                                              keyPath:@"main"
                                              statusCodes:statusCodeSet];

  // 3
  NSURL *url = [NSURL URLWithString:
                [NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?q=Orlando"]];
  NSURLRequest *request = [NSURLRequest requestWithURL:url];
  RKManagedObjectRequestOperation *operation = [[RKManagedObjectRequestOperation alloc]
                                                initWithRequest:request
                                                responseDescriptors:@[responseDescriptor]];
  operation.managedObjectCache = store.managedObjectCache;
  operation.managedObjectContext = store.mainQueueManagedObjectContext;
  
  // 4
  [operation setCompletionBlockWithSuccess:
   ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult){
     NSLog(@"%@",mappingResult.array);
     [self.tableView reloadData];
   } failure:^(RKObjectRequestOperation *operation, NSError *error) {
     NSLog(@"ERROR: %@", [error localizedDescription]);
   }];
  
  [operation start];
}

Here’s what’s going on in the code above:

  1. First, you create a RKEntityMapping object that tells RestKit how to map API responses to attributes of WFWeather.
  2. Here, RKResponseDescriptor ties responses from /data/2.5/weather to the RKEntityMapping instance above.
  3. RKManagedObjectRequestOperation defines which operation to execute. In this example, you request the weather in Orlando from the OpenWeatherMap API and point the response to the instance of RKResponseDescriptor noted above.
  4. Finally, you execute the operation with the requisite success and failure blocks. When RestKit sees a response coming back that matches the defined RKResponseDescriptor it will map the data directly into your instance of WFWeather.

In the code above there’s no need for manual JSON parsing, checking for [NSNull null], manual creation of Core Data entities, or any of the other routine things that one must do when connecting to an API. RestKit turns API responses into Core Data model objects via a simple mapping dictionary. It doesn’t get much easier than that.

To learn how to install and use RestKit, check out our Introduction to RestKit tutorial.

9. MMRecord

MMRecord is a block-based integration library that uses the Core Data model configuration to automatically create and populate complete object graphs from API responses. It makes generating native objects from web service requests as simple as possible as it creates, fetches, and populates NSManagedObjects instances for you in the background.

The code block below shows how to use MMRecord to perform the same Orlando weather call and data mapping that you did in the above in the RestKit example:

NSManagedObjectContext *context = [[MMDataManager sharedDataManager] managedObjectContext];

[WFWeather 
  startPagedRequestWithURN:@"data/2.5/weather?q=Orlando"
                      data:nil
                   context:context
                    domain:self
  resultBlock:^(NSArray *weather, ADNPageManager *pageManager, BOOL *requestNextPage) {
    NSLog(@"Weather: %@", weather);
  }
  failureBlock:^(NSError *error) {
    NSLog(@"%@", [error localizedDescription]);
}];

Without writing any complicated networking code or manually parsing the JSON response, you’ve called an API and populated your Core Data managed objects with the response data in only a few lines of code.

How does MMRecord know how to locate your objects in the API response? Your managed objects must be subclasses of MMRecord and override keyPathForResponseObject as shown below:

@interface WFWeather : MMRecord
@property (nonatomic) float temp;
@property (nonatomic) float pressure;
@property (nonatomic) float humidity;
@end

@implementation WFWeather
@dynamic temp;
@dynamic pressure;
@dynamic humidity;

+ (NSString *)keyPathForResponseObject {
    return @"main";
}

@end

keyPathForResponseObject returns a key path that specifies the location of this object relative to the root of the response object from the API. In this case the key path is main for the data/2.5/weather call.

It’s not all magic — MMRecord does require that you create a server class that knows how to make requests against the API you’re integrating against. Thankfully, MMRecord comes with sample AFNetworking-based server classes.

For complete information on setting up and using MMRecord, the readme on the MMRecord Github repository is the best place to start.

8. Magical Record

Modeled after Ruby on Rails’ ActiveRecord system, MagicalRecord provides a set of classes and categories that enable one-line entity fetch, insertion and deletion operations.

Here’s a view of MagicalRecord in operations:

// Fetching
NSArray *people = [Person MR_findAll];

// Creating
Person *myPerson = [Person MR_createEntity];

// Deleting
[myPerson MR_deleteEntity];

MagicalRecord makes it easy to set up your Core Data stack. Instead of having many lines of boilerplate code, you can set up a full Core Data stack with only one method call in your AppDelegate file as follows:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // 1
  [MagicalRecord setupCoreDataStackWithStoreNamed:@"ExampleDatabase.sqlite"];
    
  return YES;
}

You call setupCoreDataStackWithStoreNamed in application:didFinishLaunchingWithOptions: with the name of your SQLite file. This sets up your instances of NSPersistentStoreCoordinator, NSManagedObjectModel and NSManagedObjectContext so that you’re all ready to work with Core Data.

Have a look at our MagicalRecord tutorial for further information on how to install and use MagicalRecord.