“
Author: Drew McCormack
For those of you who have been wondering about what Apple’s mystery WWDC Science Coding Project will be, I am now able to spill the beans. I’m sure some have already connected the dots, but for those who haven’t figured it out yet, Apple’s WWDC code-a-thon is centered around the new open source Core Plot framework.
The Core Plot project began back in January after a post I made here on MacResearch as a ‘call to arms’ to build a decent open source plotting alternative for Apple systems. There are some options already available, such as SM2DGraphView and my own Narrative framework, but these are getting long in the tooth and are reasonably basic. There is also the very capable DataGraph framework, which is a commercial offering, but one drawback of all of these solutions is that they were developed before the iPhone, and do not support what has become a very important platform for developers.
“
(Via MacResearch – Online Community and Resource for Mac OS X in Science.) Original Link: Apple’s WWDC Mystery Coding Project Revealed
“
Thanks to the ability to have configurations in a Core Data Managed Object Model and being able to save data to multiple Persistent Stores, it is possible to have a Core Data Model that is constructed from not only an internal model, but from the models of all the plug-ins that are loaded into the application.
In this example we are going to build a basic application with the following requirements:
Core Data allows a NSManagedObjectModel to be constructed from multiple ‘sub’ models. Therefore we can load up all of our plug-ins and ask them for their NSManagedObjectModel references. Using those plus the models included with the application we can build a composite model.
However this would still save into a single file which would then become fragile if a plug-in disappeared. Instead we will use Core Data Configurations. By declaring a configuration for each model, we can specify a different file on disk for each configuration and thereby be able to split the persistent store by model on disk. If a plug-in disappears, the configuration is not loaded and its corresponding persistent store is not loaded and therefore the integrity of the persistent store stays intact.
In this example we are not going to explore Plug-in design in too much depth. That subject has been covered elsewhere. Our plug-in for this design is going to use a framework to host the shared code and both the application and the bundles will link to it and import from it.
Our framework is going to consist of a header file that defines the protocol that the plug-ins must implement to be loaded. The header is as follows:
@protocol ZSPlugin <NSObject> ' - (NSString*)name; - (NSString*)modelConfigurationName; - (NSManagedObjectModel*)managedObjectModel; ' @end
To test this we need to include at least one plug-in. That plug-in will consist of a principal class along with a data model. The plug-in does not need to stand up a Core Data stack because its model will be included in the primary application’s Core Data stack. Therefore we just need to implement the methods in the protocol.
The name method in this example just returns a string.
- (NSString*)name; { return @'Example Plugin v1.0'; }
Like the name method above, the -modelConfigurationName method only returns a string. In a more robust solution we would check in the plug-in manager to confirm that this name is unique and does not conflict with the configuration of the base application.
- (NSString*)modelConfigurationName; { return @'ExamplePlugin'; }
The final method that we declare in the protocol returns the NSManagedObjectModel for the plug-in. This method does a simple load from the plug-ins bundle.
- (NSManagedObjectModel*)managedObjectModel; { if (managedObjectModel) return managedObjectModel; ' NSBundle *myBundle = [NSBundle bundleForClass:[self class]]; NSArray *bundles = [NSArray arrayWithObject:myBundle]; managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:bundles] retain]; return managedObjectModel; }
The one interesting part of this code is that we need to get a reference to the NSBundle for the plug-in from its principal class. This is because the call [NSBundle mainBundle] will return the application’s bundle instead.
The plug-in manager loads all of the available plug-ins on launch. In this example we do not allow dynamic plug-in loading.
#import <ZSPlugin/ZSPlugin.h> ' @interface ZSPluginManager : NSObject { NSArray *loadedPlugins; } ' @property (retain) NSArray *loadedPlugins; ' + (id)shared; ' - (NSArray*)pluginModels; - (NSArray*)modelConfigurations; - (NSString*)applicationSupportFolder; ' @end
-initThe plug-in manager is a singleton that initializes itself and loads all of the existing plug-ins upon first request.
- (id)init { if (!(self = [super init])) return nil; ' //Find the plugins NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *plugins = [fileManager directoryContentsAtPath:[self applicationSupportFolder]]; ' if (![plugins count]) { NSLog(@'%@:%s No plugins found', [self class], _cmd); return self; } ' //Load all of the plugins NSMutableArray *loadArray = [NSMutableArray array]; for (NSString *pluginPath in plugins) { if (![pluginPath hasSuffix:@'.bundle']) continue; NSBundle *pluginBundle = [NSBundle bundleWithPath:pluginPath]; Class principalClass = [pluginBundle principalClass]; if (![principalClass conformsToProtocol:@protocol(ZSPlugin)]) { NSLog(@'Invalid plug-in, does not conform to the ZSPlugin Protocol: %@', pluginPath); continue; } id<ZSPlugin> plugin = [[principalClass alloc] init]; [loadArray addObject:plugin]; NSLog(@'Plug-in Loaded: %@', [plugin name]); [plugin release], plugin = nil; } [self setLoadedPlugins:loadArray]; ' return self; }
In the -init method we first find all of the files in the Application Support directory. If there are no files then we quickly return self. If there are files then we start looping over them. On each iteration we check to see if the file is a plug-in and if it is not we skip to the next loop. If it is then we look-up its principal class and confirm that it conforms to the ZSPlugin protocol. If it does not we warn the developer and skip to the next loop.
Once we pass all of the integrity checks we then call alloc and init on the plug-in and add it to the array of loaded plug-ins.
-pluginModelsTo help the main application initialize we have a couple of helper methods in the plug-in manager. The first is a method that returns all of the plug-in models.
- (NSArray*)pluginModels; { NSMutableArray *array = [NSMutableArray array]; for (id<ZSPlugin> plugin in [self loadedPlugins]) { [array addObject:[plugin managedObjectModel]]; } return array; }
-modelConfigurationsThe second helper method returns an NSArray of the configuration names used by the plug-ins. These names will be used both to load the configurations and to decide on the persistent store’s file name.
- (NSArray*)modelConfigurations; { NSMutableArray *array = [NSMutableArray array]; for (id<ZSPlugin> plugin in [self loadedPlugins]) { [array addObject:[plugin modelConfigurationName]]; } return array; }
With our quick walkthrough of the plug-in structure complete we need to review the changes to the application itself. All of the changes are limited to the Core Data methods.
-managedObjectModelThe first change we need to make is how we load the NSManagedObjectModel. Normally we would just call [NSManagedObjectModel mergedModelFromBundles:nil] and be done. However we want to load not only the models within the application itself but also merge with all of the models in the plug-ins. Therefore a couple of extra steps are required.
- (NSManagedObjectModel*)managedObjectModel { if (managedObjectModel) return managedObjectModel; ' NSMutableArray *models = [NSMutableArray array]; [models addObject:[NSManagedObjectModel mergedModelFromBundles:nil]]; [models addObjectsFromArray:[[ZSPluginManager shared] pluginModels]]; ' managedObjectModel = [[NSManagedObjectModel modelByMergingModels:models] retain]; return managedObjectModel; }
In this method we start with the NSManagedObjectModel from the Application itself and add it to a NSMutableArray. We then request an array of all the models from the plug-ins via the ZSPluginManager and add those models to the NSMutableArray. Once we have all of the models together we call +modelByMergingModels: and merge all of the models into one super model. We retain that model and return it to the caller.
-persistentStoreCoordinatorThe second and last change we need to make to the Core Data stack is the way that we handle the NSPersistentStoreCoordinator.
- (NSPersistentStoreCoordinator*)persistentStoreCoordinator { if (persistentStoreCoordinator) return persistentStoreCoordinator; ' NSFileManager *fileManager; NSString *applicationSupportFolder = nil; NSURL *url = nil; NSError *error = nil; NSString *filePath = nil; ' fileManager = [NSFileManager defaultManager]; applicationSupportFolder = [[ZSPluginManager shared] applicationSupportFolder]; if (![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) { if (![fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil]) { NSLog(@'%@:%s Failed to create app support directory', [self class], _cmd); return nil; } } ' NSManagedObjectModel *mom = [self managedObjectModel]; if (!mom) return nil; NSPersistentStoreCoordinator *psc = nil; psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom]; ' NSMutableArray *configArray = [NSMutableArray array]; [configArray addObject:@'Core']; [configArray addObjectsFromArray:[[ZSPluginManager shared] modelConfigurations]]; ' for (NSString*configName in [[ZSPluginManager shared] loadedPlugins]) { filePath = [configName stringByAppendingPathExtension:@'sqlite']; filePath = [applicationSupportFolder stringByAppendingPathComponent:filePath]; url = [NSURL fileURLWithPath:filePath]; if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:configName URL:url options:nil error:&error]) { ' [[NSApplication sharedApplication] presentError:error]; [psc release], psc = nil; return nil; } } ' persistentStoreCoordinator = psc; return persistentStoreCoordinator; }
The first half of the method is almost straight out of the template. However once we have the application support directory created and the raw NSPersistentStoreCoordinator initialized it is time to deviate.
The first then we do is construct a NSMutableArray and add our application model’s configuration name to it. In this example I called it ‘Core’. With the array initialized we then grab all of the configuration names from the plug-ins via the ZSPluginManager and add them to the array.
With the array fully populated it is time to iterate over it. Within each iteration we do the following:
We construct a file path for the configuration using the application support folder and the configuration name. We add a ‘sqlite’ extension to it although in a production system you should use an application specific extension.
We then add the newly constructed file path to the NSPersistentStoreCoordinator re-using the configuration name and checking for failure. If we fail we present an error and abort.
That is all there is to it! Core Data takes over from there and automatically saves the correct objects into the correct store files for us. If a plug-in goes away we don’t load its model and we don’t reference it’s store so integrity remains.
In the included example application I have also built a UI which lists the entities that are available in the model. If you run it straight from the zip file you will see the following UI:

However, if after building the application, you copy the example plugin into your ~/Library/Application Support/CDPlugins directory and run the application again you will see the following.

Which shows that not only is the plug-in loaded but that it’s entity (Widget) has been included in the Core Data stack. This can even be extended to create widgets and then remove the plug-in to confirm that integrity is maintained.
“
(Via Cocoa Is My Girlfriend.) Original Link: Core Data and Plug-ins
“The next CocoaHeads Silicon Valley meeting is this Thursday, April 23 at 7pm. Our featured speaker is Wil Shipley of Delicious Monster, who will share what he’s learned while writing his first iPhone app. I’m told this is the first time the app will be shown to the general public, so you may get to see something special…”
(Via Theobroma Cacao.) Original Link: CocoaHeads Thu Apr 23: Wil Shipley on iPhone
Learn How to Build iPhone Apps from Stanford University [IPhone Apps]: “
If you’ve ever hand an idea for an iPhone application but you’ve never known how to begin creating it, Stanford will be offering how-to-build-iphone-apps computer science courses via free video podcasts through iTunes U. Later this week, you’ll be able to get a Stanford-level education without the stress of having to apply to the prestigious school and especially without having to pay tuition being a huge dbag. [Ed. note: Ed went to Cal.] [TechCrunch]
“
(Via Gizmodo.)
Apple Seeds Second iPhone 3.0 Beta to Developers: “
After only two weeks from its initial release, Apple has released a second beta version of their iPhone 3.0 operating system. The new seed is available only to registered iPhone developers. The iPhone 3.0 beta was first introduced earlier t…”
Filed under: Features, How-tos, Developer, iPhone, iPod touch

In our last iPhone Dev 101, a continuing series on iPhone development, we talked about resources that you can use while you are coding with Cocoa. In this dev post, I’m going to walk you through Xcode and creating your first project.
First we need to open Xcode, so once you have the SDK installed, you’ll need to open /Developer/Applications/ and look for Xcode.app. This is Apple’s IDE (Integrated Development Environment) that allows you to code, debug, test, and build all of your iPhone and Mac applications. When you open this application, nothing specially really happens, although you might see the welcome center — if you see this, you can choose to disable it at startup by using the check box at the bottom.
To create a new project, select File > New Project. In the resulting window select iPhone OS Application > View-based Application, and click “Choose.” You will then need to specify a save name and location for the resulting files that will combine to create your application. In the resulting Xcode window, you should note that most of the work is already done for you!
At this point you have a fully functional application. Try it out: click the “build and go” button at the top of the window and wait while the app is compiled and opens in the iPhone Simulator. The app definitely doesn’t do much, but still, it’s a running application you made without writing any code.
Continue reading to learn more about Xcode, and get a brief UI overview.
Continue reading iPhone Dev 101: Creating Xcode projects, brief Xcode UI overview
TUAWiPhone Dev 101: Creating Xcode projects, brief Xcode UI overview originally appeared on The Unofficial Apple Weblog (TUAW) on Tue, 31 Mar 2009 09:30:00 EST. Please see our terms for use of feeds.
Read | Permalink | Email this | Comments
(Via The Unofficial Apple Weblog (TUAW).) Original Link: iPhone Dev 101: Creating Xcode projects, brief Xcode UI overview
Filed under: Features, How-tos, AppleScript
We’ve discussed some pretty neat uses for Automator workflows in the past, but did you know you can easily integrate Spotlight searches into your automation workflows? Well, you can, and it might be easier than you think. In this Mac Automation post, I’m going to show you how you can integrate it into a workflow that will burn the resulting files to a CD or DVD.
Creating the workflow
To create this simple workflow, you’ll need to use two actions. Find the “Spotlight” action and drag it to your workflow section; then, find the “Burn a Disc” action and drag it below the newly added Spotlight action. That’s it; your workflow is now completed, but we need to tweak the actions.
Using the workflow
To test the workflow, you can enter a search term in the Spotlight action, and a Disc name in the Burn a Disc action. Insert a rewritable disc, or a regular CD/DVD, and click the “Run” button in the upper right corner of the Automator window. Automator will then go to work finding all of the search terms that matched files, then will then burn all found items to the disc. This could take a while to burn, depending on the resulting files.
Remember that all of the Spotlight tricks, such as exclusion, denoting kind, etc. are still available even though you’re using the Automator action.
Continue reading Mac Automation: Integrating Spotlight searches with your workflows
TUAWMac Automation: Integrating Spotlight searches with your workflows originally appeared on The Unofficial Apple Weblog (TUAW) on Mon, 30 Mar 2009 10:00:00 EST. Please see our terms for use of feeds.
Read | Permalink | Email this | Comments
(Via The Unofficial Apple Weblog (TUAW).) Original Link: Mac Automation: Integrating Spotlight searches with your workflows
Filed under: Features, How-tos, Developer, iPhone, iPod touch
It has been a while since the last iPhone Dev 101 post (and I must apologize for that — sometime life can get in the way of different things, and this was one of those times). In this Dev 101 post, I want to take you through a few of my favorite resources for Cocoa/iPhone development. Some of these resources are books, while others are sites, but all of the resources are valuable to up and coming developers (and experiences developers) alike.
Books
Some books are just invaluable and couldn’t be replaced with another. Aaron Hillegass’ Cocoa Programming for Mac is just that book. Currently in it’s 3rd edition, the book gives you much of the Cocoa programming information that you need to program for both the Mac and iPhone. There are only a few subtle differences in programming for these platforms, namely the use of the Cocoa Touch. If you ever have the chance, going to one of the Big Nerd Ranch Cocoa programming classes gives you the ability to learn Cocoa hands-on.
Another title that is useful to beginning iPhone developers is the Beginning iPhone Development book. This book has a useful approach to stepping into the world that is programming on iPhone. It talks about numerous topics including UI design, Quartz, and OpenGL. Also covered in the book are APIs like CoreLocation and interfacing with the camera.
If you already know Cocoa and a little about iPhone development, Erica Sadun’s iPhone Developer Cookbook is a great jumping off point to start development. She assumes, however, that you already understand Cocoa.
Continue reading to learn about more valuable books, websites, and resources for iPhone/Mac developers.
Continue reading iPhone Dev 101: Useful Cocoa Development Resources
TUAWiPhone Dev 101: Useful Cocoa Development Resources originally appeared on The Unofficial Apple Weblog (TUAW) on Wed, 25 Mar 2009 10:00:00 EST. Please see our terms for use of feeds.
Read | Permalink | Email this | Comments
(Via The Unofficial Apple Weblog (TUAW).) Original Link: iPhone Dev 101: Useful Cocoa Development Resources
Measuring the Design Process: “Both John Gruber and Buzz Anderson have commented on the experiences of former design lead at Google, Doug Bowman. Doug’s observation is that at Google, every design decision must be backed by data. In essence, you must prove you’re right. The post is quite short, but it resonates with me because I’ve seen the same thing at other companies…”
(Via Theobroma Cacao.)
Filed under: iPhone, SDK, iPod touch
Tuesday’s iPhone OS 3.0 announcement has left the interwebs even more iPhone-obsessed than usual. If you find digging through all this information overwhelming (or, if like me you were out of town when OS 3.0 was announced), check out this round-up of news, opinions and videos. The only thing missing is a beta copy of OS 3.0 and that’s already floating around various torrent sites.
If that’s not enough, be sure to check out our continuing iPhone OS 3.0 coverage.
Watch the OS 3.0 presentation — Were you left off the invite list too? Check out the video in HD or SD at the link above or in iTunes [iTunes link] as a video podcast.
Engadget’s iPhone OS 3.0 Hub — Engadget has a whole page dedicated to their furious and hands-on iPhone OS 3.0 coverage, including this video walkthrough.
What Apple Didn’t Announce — Apple’s iPhone OS 3.0 presentation didn’t answer every question or address every iPhone issue. Our old friend David Chartier tackles what was left out.
SDK 3.0 brings more NDA fun — Much to the chagrin of many iPhone devlopers, the NDA is back for SDK 3.0. At Arstechnica, our pal Erica takes on what this means for developers. Let’s just hope the NDA is lifted as soon as 3.0 is officially released.
OS 3.0 Screenshot Pr0n — Pfft, what NDA? iLounge has put together a great gallery of iPhone OS 3.0 screenshots, showing off what’s new and improved. Love it.
iPhone OS 3.0 vs. Android — Lifehacker has a pretty neat comparison of features that are currently avaialable in the iPhone 2.21, stuff that’s coming in OS 3.0 and what’s available and coming for Android. As someone who has spent a LOT of time using both the iPhone OS and the T-Mobile G1, I’d just add that hardware and UI is actually just as important as “features” when comparing the two platforms. Right now, the iPhone absolutely cleans Android’s clock — despite having fewer “features” — because the hardware is better (that G1 keyboard is terrible), the UI is more thought-out and the third-party software is better by leaps and bounds. (hat tip, Gruber)
Future iPod/iPhone models referenced in latest betas — The latest iPhone OS 3.0 SDK includes references to future iPhone and iPod models (3,1) and two other unknown devices.
TUAWiPhone 3.0 Friday roundup originally appeared on The Unofficial Apple Weblog (TUAW) on Fri, 20 Mar 2009 16:00:00 EST. Please see our terms for use of feeds.
Read | Permalink | Email this | Comments
(Via The Unofficial Apple Weblog (TUAW).) Original Link: iPhone 3.0 Friday roundup