Querying Data – Core Data vs. Entity Framework

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.

iOS Quick Tip – Viewing Core Data’s Generated SQL

If you are using Core Data – or any ORM or persistence framework, for that matter – it’s often handy to be able to view the generated SQL for your queries. Fortunately, Core Data makes this incredibly easy, and unlike some other ORMs, it doesn’t require crazy hacks or third party tools.

Click your project’s name in the Xcode toolbar:

Select ‘Edit Scheme’:

Go to the ‘Arguments’ tab and click the + button under ‘Arguments passed on launch’:

Enter ‘-com.apple.CoreData.SQLDebug 1’ as the argument:

Press OK, and run your app.

Notice all of the SQL statements that appear in Xcode’s output window.

Xcode 4.4 and Objective-C

Apple recently released Xcode 4.4. The list of new features is quite intriguing.

      • The compiler automatically calls @synthesize by default for unimplemented @properties.
      • For the NSArray and NSDictionary classes, support is provided for Objective-C literals.
      • Subscripting using '[ ]' syntax is supported for Objective-C container objects.
      • Compatibility with the C++11 standard is improved.
      • New static analyzer checks for common security mistakes in API and malloc usages.
      • The caller and callee for selected methods can be displayed in the Assistant Editor.
      • Code completion is enhanced with QuickHelp.
      • Scene Kit is supported with a viewer-editor for 3D document files.
      • Improved localization workflow uses base language .xib files.
      • Git supports staging of individual changes.

Leave it to Apple to introduce core language features in a point release of their IDE!

Anyway, it got me thinking about Objective-C, productivity, and John Siracusa’s comments from a few years back:

 A framework with methods like this:

NSInteger myCount = [[myDict objectForKey:@"count"] integerValue];
NSArray *myArray = [myString componentsSeparatedByString:@","];
myItem = [myArray objectAtIndex:i];

is just not going to fly in a language that (hypothetically) supports this:

myCount = myDict["count"];
myArray = myString.split(",");
myItem  = myArray[i];

Looks like John finally got his wish! And quite frankly, it’s about time. It doesn’t get much more basic than strings and arrays, and it boggles my mind that it took Apple this long to give us a non-eye-gouging syntax. Don’t get me wrong; I’m glad to have these improvements. It’s just that in my opinion, ObjC still lags far, far behind the rest of the civilized world when it comes to programmer productivity.

Over the next little while I will be taking a closer look at some of Objective-C’s productivity failures in comparison with languages like C#, Ruby, Python, and F#.

Stylish looking glossy buttons with UIButton+Glossy

You’ve all seen the standard, iOS buttons. Although functional, they are, well, plain, to put it mildly.

Perhaps you’ve even tried to make some prettier buttons in photoshop. But if you’re like me, and you have no artistic skills, this can be a challenge. Fortunately, Michael Heyeck has put together a slick little piece of code for generating stylish, glossy buttons.

It’s ridiculously easy to use, and the results look great.

Step 1 – download UIButton+Glossy.h and UIButton+Glossy.m and stick them in your project.

Step 2 – #import “UIButton+Glossy.h” in the view controller that holds your buttons.

Step 3 – style the buttons! This is done by calling the setBackgroundToGlossyRectOfColor:withhBorder:forState method. The color parameter specifies the button’s color. The withBorder parameter specifies whether or not the button should have a border, and the forState parameter is the UIControlState that the style should be applied to.

You can put this code in your view controller’s viewDidLoad method. So, given a UIButton* named button, we can style it like so:

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [button setBackgroundToGlossyRectOfColor:[UIColor colorWithRed:.05 green:.65 blue:.05 alpha:1] withBorder:NO forState:UIControlStateNormal];
}

And with that, you have a stylish looking button!
A little style can go a long way into helping your app stand out from the crowd.

Download the Sample Project