Core Data not returning a custom concrete class

Ever had a problem when you’re fetching something from an NSManagedObjectContext, and you’ve set a concrete class in your model, only to find that it is an NSManagedObject? Me too.

I read this post at StackOverflow, which suggested that you have to create the subclass using Xcode, from within the modeler. OK, I thought. I’ll try that.

I deleted my old .h and .m files. I went into the modeler. I created a new Managed Object class. And put my custom code back in.

And it didn’t work!

But never fear. I did a Clean, and it worked.

Temporary NSManagedObjectIDs

I’ve run into a problem where I insert a managed object into a managed object context, in a separate thread, and then return the object ID to the main thread and then retrieve the object from the main thread’s context using that ID.

It didn’t always work. It is because I saved the first managed object context after I took the object ID. And the object ID was temporary because the object hadn’t been persisted. And the temporary object ID became invalid after the context was saved.

It didn’t always happen because my code will either insert or update when doing the JSON deserialisation. So if the object already existed in my persistent store, it would retrieve a proper object ID.

So the moral of the story is that you should always save your managed object context before getting the newly inserted object’s ID.

binding not implemented for this SQLType 7: Core Data and iPhone OS 3

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'binding not implemented for this SQLType 7'

That’s not something you want to read. And it doesn’t make much sense. And there’s not a lot out there on that problem, either.

I am adding Core Data to Zoopcast (the people-powered local search app). The first few releases just took data from the JSON web service, and put it into unmanaged objects. (As it turns out, I probably should have gone with Core Data from day one. Despite what the docs say, it’s not that difficult. In fact, probably easier than what I was doing.)

I read that SQLType 7 is the REAL storage class in SQLite. And that storage class can handle different types of data. And I thought to myself… perhaps I am putting floats instead of doubles, somewhere in my code (which is permitted in C, and my managed objects have NSNumber properties anyway) and it’s that mapping that is getting the Core Data/SQLite layer confused.

So I had a look.

The NSDictionaries that were being decoded from JSON with JSON Framework had NSNumber objects that were NSDecimal (one of the private subclasses of NSNumber). I’m not sure if they were all NSDecimal, but they probably were: they’re stored as double precision floating point numbers in the service, and obviously have to be rounded for JSON transport, so decimal makes the most sense.

So I thought… why not force these to all be doubles, like so:

double doubleValue = [(NSNumber *)value doubleValue];
value = [NSNumber numberWithDouble:doubleValue];

And guess what? It fixed it.

This wasn’t a problem on iOS 4. It was only a problem on an iPod touch first generation running iPhone OS 3.1.3. But it’s not longer a problem for me.

It was this post on Stack Overflow that lead me on the right track, and Brian King’s answer actually makes perfect sense to me now that I’ve re-read it after figuring it for myself and explaining it in long form.

Images showing on iPhone Simulator but not device?

If you’re working on an app (Zoopcast, say) and you’re finding that images that you’ve got in your application bundle are showing up when you’re running in the simulator, but not on the device, check the case of your filenames.

I thought there might have been some sort of image format problem that [UIImage imageNamed:] uses, but I was wrong. It was simple case sensitivity.

I’m guessing that my computer has a case-insensitive filesystem whereas the iPhone and iPod I am testing on presumably have a case-sensitive one. And that is where the problem arose.

CLLocationCoordinate2DMake is new in iOS 4

I hadn’t done any Core Location work before iOS 4 came out. But now I am. And I ran into a very odd EXC_BAD_ACCESS bug when running on an iPod touch that’s running iPhone OS 3.1.3. I pinpointed the problem (actually, I think it was only a problem, because I did a lot of other refactoring to get to this point) was with CLLocationCoordinate2DMake. And I finally realised when looking in the header that it’s new for iOS 4. Which is why it fails under iPhone OS.

My fault for being a CL newbie.

In any case, I figure I should share this with others because my searches were fruitless. Enjoy!

UPDATE: The static inline function described by Cocoanetics was immensely helpful and also helped with the next problem I encountered – distanceFromLocation being introduced.

To Three20 or not to Three20…

My answer, and one I wish I came to a bit earlier, is not to Three20.

And the reason is this. It is a completely different architecture to the native UIKit framework. Which is fine, it’s supposed to be. But because of this, making what should be minor changes to the appearance of a table view cell, for example, can become troublesome.

Some of the problems I had were because of the lack of documentation. I’m not complaining about that, because the open source project grew out of an internal one which, if it’s like almost ever internal project I’ve worked on, everyone on the team knew pretty intimately. Documentation will improve. And that’s a good thing.

The one thing that I do like about Three20 is the whole request model thing. If you wire up a TTTableViewController, TTDataSource and TTModel, all the UI around loading and reloading data is pretty much taken care of for you.

But the other UI stuff is more trouble for me than it’s worth. I was initially attracted by the URL navigation feature, but really, I’m just adding another layer of complexity, especially when it comes to passing objects rather than scalar strings and numbers as parameters. And even then, there is unnecessary conversion to and from strings to create the URL and then extract the parameters that will get passed to the init method.

So I will be migrating away from Three20 in subsequent builds of Zoopcast. Yes, this is the first time I am blogging about Zoopcast, the startup I founded in July. We’re nearly ready… stay tuned (by following @zoopcast, who is eerily silent at the moment).

But that’s not to say that it’s not a good library. It is. And will be better after the bug crushing week that is happening now as well. But it’s just not appropriate for this case. It obviously has its uses – it is what one of the most popular iOS apps, Facebook, is based on.

Fruits of the iPhone posts

An avid reader of this blog (i.e. no one) will have noticed that lately there have been quite a few posts about iPhone development.

Well, I am pleased to announce (on behalf of Zemobo) that Zemobo Rugby has now launched on the iTunes App Store. It ties in with Zemobo’s Rugby Picks app on Facebook.

You can download it from http://bit.ly/98xEo3. It’s free!

Modal view controllers and recursion causing stack overflow

Ironically, it was this post at Stack Overflow that helped me solve this problem!

There appears to be a bug (either in the iPhone SDK or my understanding of it) that if you dismiss a modal view controller with animation using UINavigationController’s dismissModalViewControllerAnimated, it will cause some sort of weird recursion that causes a stack overflow (over 4000 frames were in the stack when it crashed, and it took a split second for it to fill up in the Simulator) if you then want to display the modal view controller again using presentModalViewController.

It turns out it’s the animation on dismissal that’s causing the problem. If I have dismissModalViewControllerAnimated:NO instead of YES, the subsequent redisplay of the view works fine.

OpenID and iPhone apps

I am trying to find an OpenID implementation that is similar to the way that Facebook Connect’s login mechanism works on the iPhone. I can’t find anything, which is very surprising.

Does anybody know of an open source OpenID consumer implementation for iPhone OS? And if you don’t know of one, are you looking for one?

If I can’t find one, I am going to have to write my own, and it’s something that I think would do well to be open sourced, so if you are interested, please post a comment.

Width of grouped UITableViewCell

I am working on some iPhone development at the moment. I have built a cell for a UITableView in Interface Builder. The cell was a bit too wide for the cell in my table view, and I realised it was because the cell in the NIB is full width but I am loading it into a grouped table view.

I didn’t want to have to measure it myself so I searched for the width. Couldn’t find it. So I measured it myself. And put it here. So maybe I will start getting a few more visits to this page from now on!

The magic number is…

300

The width of a grouped UITableViewCell is 300 pixels.