title | author | category | excerpt | status | ||||
---|---|---|---|---|---|---|---|---|
Core Data Libraries & Utilities |
Mattt Thompson |
Open Source |
We were a bit hard on Core Data last week, so for this issue of NSHipster, we bring you a guided tour of the best open source libraries for working with Core Data. Read on to see how you might make the most from your Core Data experience. |
|
So let's say that, having determined your particular needs and compared all of the alternatives, you've chosen Core Data for your next app.
Nothing wrong with that! Core Data is a great choice for apps that model, persist, and query large object graphs.
Sure it's complicated, cumbersome, and yes, at times, a real pain in the ass—but gosh darn it, some of the best and most popular apps ever built use Core Data. And if it's good enough for them, it's probably good enough for you, too.
...but that's not to say that Core Data can't be improved.
And while there have been many libraries attempting to replace Core Data, there are many more that attempt to make it better. These libraries range from the much-needed dose of syntactic sugar to comprehensive, full-stack frameworks.
This week on NSHipster: a guided tour of the best open source libraries for working with Core Data. Read on to see how you might make the most from your Core Data experience.
For your convenience, the following table is provided. Contained within are the most significant open source libraries and utilities for working with Core Data. This list is by no means comprehensive, so if you think something is missing or out of place, please tweet @NSHipster—or better yet, submit a pull request.
Wrapper libraries provide some much needed syntactic sugar and convenience methods to Core Data's verbose and complicated APIs.
For example, to insert a new managed object into a managed object context, it's a class method on, not NSManagedObject
or NSManagedObjectContext
as one might reasonably expect, but NSEntityDescription
. NSEntityDescription +insertNewObjectForEntityForName:inManagedObjectContext:
. What?
There are a number of open source libraries that collectively identify and correct for the roughest patches of the Core Data APIs. Managing a main and private context outside of AppDelegate
, convenience method for manipulating and querying managed objects, and so on.
There is a lot of boilerplate code required to write a Core Data application. This is annoying. In pretty much everything I've written since Core Data came to iOS, I have used the following class.
Inspired by Active Record
It should be no surprise that programmers, having learned how to do things a certain way, will bring those ideas and conventions to other technologies. For the large influx of Ruby developers coming over to iOS, that familiar paradigm was Active Record.
Contrary to popular belief, Core Data is not an Object-Relational Mapper, but rather an object graph and persistence framework, capable of much more than the Active Record pattern alone is capable of. Using Core Data as an ORM necessarily limits the capabilities of Core Data and muddies its conceptual purity. But for many developers longing for the familiarity of an ORM, this trade-off is a deal at twice the price!
MagicalRecord was inspired by the ease of Ruby on Rails' Active Record fetching. The goals of this code are to clean up Core Data related code, allow for clear, simple, one-line fetches, and still allow the modification of the
NSFetchRequest
when request optimizations are needed.
This is a lightweight ActiveRecord way of managing Core Data objects. The syntax is borrowed from Ruby on Rails. And yeah, no AppDelegate code. It's fully tested with Kiwi.
Inspired by LINQ
Here's a fun game: the next time you meet a developer coming over from the .NET world, set a timer to see how long it takes them to start raving about LINQ. Seriously, people love LINQ.
For the uninitiated, LINQ is like SQL, but integrated as a language feature. Think NSPredicate
, NSSortDescriptor
, and Key-Value Coding
with a much nicer syntax:
from c in SomeCollection
where c.SomeProperty < 10
select new {c.SomeProperty, c.OtherProperty};
ios-queryable supports LINQ-style query composition and deferred execution, and implements a subset of IEnumerable's methods, including
where
,take
,skip
,orderBy
,first/firstOrDefault
,single/singleOrDefault
,count
,any
, andall
.
Inspired by ReactiveCocoa
ReactiveCocoa, which itself brings the functional reactive paradigm to Objective-C, is now being used to bring some functional sanity and order to Core Data. This is still uncharted territory, but the initial results are indeed promising.
ReactiveCoreData (RCD) is an attempt to bring Core Data into the ReactiveCocoa (RAC) world.
Most iOS apps communicate with a webservice in some capacity. For apps using Core Data, it's common for records to be fetched, updated, and deleted from a REST or RPC-style webservice. Maintaining consistency between a local cache and the server is a deceptively tricky enterprise.
Keeping objects up-to-date, removing duplicate records, mapping entities to API endpoints, reconciling conflicts, managing network reachability... these are just some of the challenges a developer faces when creating a robust client-server application.
Fortunately, there are a wealth of open-source libraries that can help alleviate some of this pain.
RestKit is a modern Objective-C framework for implementing RESTful web services clients on iOS and OS X. It provides a powerful object mapping engine that seamlessly integrates with Core Data and a simple set of networking primitives for mapping HTTP requests and responses built on top of AFNetworking. It has an elegant, carefully designed set of APIs that make accessing and modeling RESTful resources feel almost magical.
AFIncrementalStore is an NSIncrementalStore subclass that uses AFNetworking to automatically request resources as properties and relationships are needed.
MMRecord is a block-based seamless web service integration library for iOS and OS X. It leverages the Core Data model configuration to automatically create and populate a complete object graph from an API response. It works with any networking library, is simple to setup, and includes many popular features that make working with web services even easier.
SLRESTfulCoreData
builds on top of AFNetworking and SLCoreDataStack and let's you map your JSON REST API to your CoreData model in minutes.
Overcoat is an AFNetworking extension that makes it super simple for developers to use Mantle model objects with a REST client.
Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application.
Whereas adapters synchronize information through an existing, general purpose interface such as REST, synchronizers use a more direct protocol, offering better integration and performance at the expense of portability and generality.
Automatic synchronization for Core Data Apps, between any combination of OS X and iOS: Mac to iPhone to iPad to iPod touch and back again
UbiquityStoreManager is a controller that implements iCloud integration with Core Data for you.
We would be remiss to survey the open source Core Data ecosystem without mentioning Mogenerator. Among one of the surviving projects from the pre-iPhone era, Mogenerator has become indispensable to developers over the years. Although much has changed about Core Data over the years, the one constant has been Apple's characteristic lack of comprehensive tooling. Fortunately, Mr. Wolf Rentzsch has us covered.
mogenerator
is a command-line tool that, given an.xcdatamodel
file, will generate two classes per entity. The first class,_MyEntity
, is intended solely for machine consumption and will be continuously overwritten to stay in sync with your data model. The second class,MyEntity
, subclasses_MyEntity
, won't ever be overwritten and is a great place to put your custom logic.
Remember: there is no silver bullet. There is no one-size-fits-all solution. Just as Core Data may only be advisable in particular circumstances, so too are the aforementioned Core Data libraries.
Dividing the ecosystem up into broad categories is informative if only to help identify the relative strengths and trade-offs of each library. Only you can determine (yes, sometimes through trial and error) which solution is the best for you.