Black Boxes and Core Data

Is Core Data a black box?

Reading this post from Theocacao this morning got me thinking about using Core Data in my first Mac app that I’m currently working on.

Five years working with .NET has taught me some valuable yet tough lessons–the black box approach to writing applications can seem like a perfect shortcut, but can quickly turn into the bane of one’s software development existence.

When I use the term black box, I am referring to employing a methodology (usually with data access) that is provided by the platform vendor (namely Microsoft, Apple, etc.) that are there to make the developer’s job faster and easier.

In theory, black boxes do what they are intended to do. In fact any and all of the examples and tutorial videos you might find on the Microsoft website show how to use these tools and they make it look very quick and easy.

I’ve found this to be true in the Core Data examples I’ve seen as well. What’s interesting is the fact that the data sets the examples work with are always very small. This matters a great deal and here’s why.

In the Microsoft world, you can build data models using a model designer that maintains XML code behind the scenes for you. You simply specify the query you want to use to obtain the data through a TableAdapter and then you are able to connect the model to your application without writing a stitch of code. It is “all done for you”. The problem is that it doesn’t scale well. After you’ve accumulated a large number of objects in the designer, the first thing you notice is that the interface becomes sluggish. It’s still useable, however, I know I’ve got a lot more that I need to add to the model before the app is going to be finished. It could get pretty ugly.

What’s worse and more critical to the application, however, is the unknown problems that the black box happily obscures from the developer’s view. I had developed my application using this black box model in Microsoft and had to change the database to a new empty database with the *exact same schema* and when I went to re-run the application, it just stopped working altogether. I could no longer add records to the database using the interface I had developed.

As I looked around the Internet, I found this to be a fairly common problem. I found myself having to frantically and immediately break out of the black box and return to square one–writing my own data access code–to get the app working again. It was a nightmare that taught me that I need to avoid the black boxes.

So, here I am now embarking on developing my Mac programming skills and the first thing I’m faced with is whether or not I should go the black box route that Core Data seems to be.

I say seems because I am new, so please don’t flame me over that comment. If it is not a black box methodology, simply explain to me how that is so. Meanwhile, I’m going to assume that it actually is a black box method and step into it very cautiously. I like Core Data quite well and it really seems to be pretty powerful. However, I can’t help but wonder about scalability and running into the same issues I had using Microsoft’s dev tools. I’ll continue to document my progress and findings here.

Is CamelBones Viable? An Outsider’s Perspective

CamelBones is a Perl-Cocoa/Objective-C bridge framework written by Sherm Pendley and it appears that is doesn’t yet work with OS X Leopard. I’ve written Sherm a couple of messages myself to find out if he has plans to update it for Leopard. I haven’t heard back from him yet, but according to some posts I read from back in May, Sherm may no longer want to pursue this project, or he just can’t afford to since he has been doing it on a volunteer basis. This is a shame to people like me who are just getting into the Cocoa/Objective-C game and would love to have access to Perl inside of my apps–yep, that’s right I want to access Perl from Objective-C.

I realize that you can do this using the PerlObjCBridge, but Sherm’s library is much more robust and, frankly, easier to use. In fact, just before I upgraded to Leopard I got version 1.0.3 of CamelBones working from within a Cocoa application in Tiger. I was stoked. I can now have all of the text parsing power of Perl from within my application and this, from my point of view is the real strength of CamelBones. You can imagine my disappointment when my application would no longer work when built in Leopard.

I suppose that’s the point of my post. Obviously I’m speaking without any evidence whatsoever that the majority of people who might use CamelBones would agree with me, but I really see CamelBones being more viable as an embedded Perl interpreter than anything.

If the examples that are included in the CamelBones distro are any indication, then the majority of people who use CamelBones are using it to be able to develop Cocoa apps from Perl. I submit that because Sherm has had trouble establishing viability using CamelBones in this way, maybe he ought to consider promoting it more from the perspective that those of us who still use and love Perl, would find it far more useful as a way to run perl scripts from within our Cocoa/Objective-C apps. Here is how I am planning to use it:

  • To develop a plugin framework. New plugins developed as perl scripts could use known tokens to access the internals of my app and could therefore allow the app to evolve depending upon what I or others envision.
  • To embed a powerful text parsing engine. Perl is best known for its ability to parse and process text. There are regular expression libraries available for Objective-C, however, to simply embed a Perl interpreter in your app provides a powerful regex engine that is already familiar if you know Perl compatible regular expression syntax.

If need be, I’ll find another way to get what I need in my applications (regex, plugin framework, etc.), however, Sherm’s CamelBones library is mature, solid, and very powerful. It would be ideal. I hope Sherm will continue to work on the project. Meanwhile, if you, like me, use Perl on a regular basis, let Sherm know that you would like to see the project continue–maybe make a donation (Click Donate) to help support its further development.

iCal Development Sample SimpleCalendar Doesn’t Work

I was wanting to learn the iCal API for the Mac so I downloaded the sample application called SimpleCalendar at the Apple Developer Connection website (you’ll need to log in with your ADC member account info). Apparently, when the sample code was last modified it was with code that didn’t make it into the release build of Leopard. The application will compile in xCode 3.0, but it won’t run properly (the calendar never displays).

To fix it, all you need to do is fix all of the warnings that come up when you do a compile. I’ve gone to the trouble of finding the correct API, so I figured I would highlight it here. The FileMerge results between my fixed version of Calendar.m (the offending file) and the original version show that there are four changes. They are as follows:

Line No. Original Fixed
74 NSPredicate *eventsForThisYear = [NSPredicate eventPredicateWithStartDate:startDate endDate:endDate
calendars:[[CalCalendarStore defaultCalendarStore] calendars]];
NSPredicate *eventsForThisYear = [CalCalendarStore eventPredicateWithStartDate:startDate endDate:endDate
calendars:[[CalCalendarStore defaultCalendarStore] calendars]];
193 NSPredicate *uidPredicate = [NSPredicate eventPredicateWithStartDate:startDate endDate:endDate UID:uid
calendars:[[CalCalendarStore defaultCalendarStore] calendars]];
NSPredicate *uidPredicate = [CalCalendarStore eventPredicateWithStartDate:startDate endDate:endDate UID:uid
calendars:[[CalCalendarStore defaultCalendarStore] calendars]];
240 NSPredicate *uidPredicate = [NSPredicate eventPredicateWithStartDate:startDate endDate:endDate UID:uid
calendars:[[CalCalendarStore defaultCalendarStore] calendars]];
NSPredicate *uidPredicate = [CalCalendarStore eventPredicateWithStartDate:startDate endDate:endDate UID:uid
calendars:[[CalCalendarStore defaultCalendarStore] calendars]];
280 [[CalCalendarStore defaultCalendarStore] saveEvent:object span:CalSpanThisEvent]; [[CalCalendarStore defaultCalendarStore] saveEvent:object span:CalSpanThisEvent error:nil];

I’ve successfully built the application without any warnings or errors and it now will run. On to learning what the code is actually doing.

The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store.

I’ve put the whole error message in the title of this post so that people can find the answer to this problem easier when looking on the web. The first Core Data application I built since starting to learn how to develop applications for Mac OS X Leopard threw me for a loop because I kept getting this error message when I would try to run the application:
Core Data Error

The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store.

The problem would not happen as long as I hadn’t made any Core Data binding connections in interface builder, so I was puzzled. I looked around on the web for a while and couldn’t find any answers, so then I asked Marcus. He knew exactly what was wrong.

Apparently the Core Data applications create an XML file in which they store the data for your application in:

~/Library/Application Support/ApplicationName/ApplicationName.xml

where ~ means your home directory and ApplicationName and ApplicationName.xml are the name of your actual application.

All you have to do is delete that XML file and rebuild your app. It will then work fine as it regenerates the object model according to what is in XCode.

What happened was I had created a Core Data application and started trying to do things during which I screwed up completely and decided to scrap the whole project. I then went into the finder and deleted the application code directory completely and decided to start over. When I created the new Core Data application, I used the exact same name as the first project. So, now when I went to build the application, it went and looked in:

~/Library/Application Support/ApplicationName/ApplicationName.xml

and found the file there, so it tried to use it. Meanwhile, my data model had changed in the new project. The application didn’t know what to do with the incompatible model and then threw up its hands and gave me this error. Anyhow, it’s an interesting lesson and very helpful. Thanks to Marcus for providing the answer. Meanwhile, take a look at this code that is part of the default Core Data template:
[c]
– (NSString *)applicationSupportFolder {

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
return [basePath stringByAppendingPathComponent:@”ApplicationName”];
}
[/c]
This code is returning the path to the specific Application Support directory for your application.

Hope this helps.

Getting Started with Cocoa and Objective-C

Most of my posts related to programming on this site center around programming .NET using C# on Windows. Well, it looks like that era in my programming career has come to a close. I bought a MacBook Pro back in June and have been working toward starting to learn how to develop applications for the Mac. I’ve waited until now for several reasons–one of which is that the new XCode 3.0 and Objective-C 2.0 just came out with Mac OS X Leopard. As I have time, I am going to start documenting my experiences here to help others figure things out as well. I could be wrong, but with the introduction of Mac OS X Leopard, I believe the demand for Mac developers is going to rise dramatically. Time will tell.

Anyhow, while my general programming experience is very useful to me as far as logic and flow are concerned for developing an application, the Apple way of doing things is different and takes some getting used to. From what I’ve seen so far, though, is that the Apple way is also very cool. I am fortunate to work with Marcus Zarra who is an independent software developer on the Macintosh. He is helping me close some gaps in my own knowledge and so I’m going to journal the things I’m learning here from now on.

So, lets get coding…