As someone coming to iOS development from a .NET background, one of the things that annoys me the most is the sheer amount of code it takes to do things that should be simple. Core Data is a perfect example of this.
Let’s say I want to retrieve the 5 most recently created widgets that have a certain type. The typical solution in Core Data looks something like this.
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription* entity = [NSEntityDescription entityForName:@"Widget" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; NSPredicate* predicate = [NSPredicate predicateWithFormat: @"type == %@", someType]; [fetchRequest setPredicate:predicate]; NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createddate" ascending:YES]; NSArray* sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; [fetchRequest setFetchLimit:5]; NSError* error; NSArray* widgets = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
Aside from being obnoxiously long, this code also has zero type safety, zero refactorability, and three hardcoded strings that are only error-checked at runtime.
The equivalent code using Entity Framework and Linq would be something like this:
var widgets = context.Widgets.Where(w => w.Type == someType) .OrderBy(w => w.CreatedDate) .Take(5);
… with an optional call to ToList() at the end depending on whether or not you want to immediately materialize the query.
Code like this gives you type safety, refactorability, and proper intellisense support. I know which one I would rather write, read, debug, and support.
So, what’s the solution? Are there any better ways of doing this with Core Data? I’m not sure. Maybe something like Matt Gallagher’s One Line Fetch would make a good starting point. It certainly reduces the amount of code required, but it still suffers from many of the same flaws.
How about an IQueryable-like set of categories for Objective-C collections? Or some sort of magical wrapper around Core Data?
Things like that are far beyond my meager iOS development skills, but surely someone out there has done something to improve the situation, right? This can’t be as good as it gets.