ActiveRecord vs. Core Data
With the release of ArrGeeBee and the development of my first iPad application*, I recently found myself delving into a number of Objective-C technologies, including Core Data. Given that I'm coming from a Ruby / Rails background, I found this really, really interesting since both Rails's ActiveRecord and CoreData are oriented around Object Relational Mappers (ORMs). Let's consider a simple model in Ruby called Event that is backed by ActiveRecord:
class Event < ActiveRecord::Base
end
Here's a simple example of using the an ActiveRecord finder to return all entries, sorted by creation date descending (using the newer style syntax):
events = Event.all(:order => "created_at DESC")
When you're learning a new platform, one of the first things you do is look at the new platform from the context of the old so my concern was how to write this in Objective C using its native ORM.
The basic structure of retrieving data from Core Data is bundled in a fetch request which specifies an entity from the Core Data stack (the Event), a predicate to limit the number of results returned (similar to the :conditions => {...} hash in ActiveRecord), and a sort descriptor to place them into some sort of order. Since my example above omitted any conditions, I'll do the same here and leave out the predicate for this request.
// Create the Fetch request and scope it to the entity we're retrieving (in this case, an event).
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
// Create a sort descriptor to order these events by their creation date in descending order.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
// Set up a pointer to hold an error, in case the fetch request fails.
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Some amount of error handling here.
}
// Finally, assign the result set into a controller variable called eventsArray, then clean up the last of the objects we were holding in memory.
[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];
That's about a 1:20 ratio of lines of code and while its never all about lines of code, this one example very dramatically spelled out to me a key difference between Objective C and Ruby and pointed out to me just how easy Ruby makes things. I think, all too often, we overlook the important role that metaprogramming has played in the Ruby language, and in Ruby's most popular frameworks. Things like object introspection have freed us from worrying about a lot of the little details around everyday tasks, such as retrieving records from a data store.
Now, that said, I've got my first app in the App Store, I've bought my first iPad and I'm barreling down this path. Onward!
* Coming real soon now. Interested? Drop an email to info@alloycode.com and I'll drop you on a mailing list. All I can tell you about it for now is that ... (Actually skip it -- just sign up for the mailing list.)
Comments
-
Not really a fair comparison since you’re programming at two different levels of abstraction. ActiveRecord does essentially the same thing your CoreData code is doing for you under the covers. What you need is an abstraction over CoreData.
