Plug-ins the Cocoa way

For many graphics applications, plug-ins are a way of life. This essay presents a method that minimizes the amount of work required to support different host applications, or even different versions of the same host. I used these techniques in our IconBuilder plug-in for Photoshop. These instructions have already helped one fellow developer; with the help of Google, hopefully there will be more.

My goal was to use Cocoa and NIB files produced by Interface Builder for driving the plug-in user interface. As I began to work on this project, I also realized that it was possible make the user interface independent of the underlying binary file formats: a CFM shim can load a Mach-O bundle.

Here are the steps to accomplish the task:

  1. Photoshop loads the plug-in which is built with Carbon.
  2. The Carbon plug-in searches for a Cocoa bundle in the plug-in’s resources with CFBundleGetBundleWithIdentifier and then loads it with CFBundleCreate.
  3. Once the bundle is loaded, I get a function pointer to the Cocoa code to execute using CFBundleGetFunctionPointerForName.
  4. After I’m in the Cocoa code, I create my own NSAutoreleasePool and then call NSApplicationLoad(). At this point, you can work with controller objects to get things setup and call [NSApp run] to get a run loop going.
  5. From this point on, I can use all the Cocoa and Foundation frameworks. Interface Builder NIB files work fine, too.

I use the Carbon code base with both Codewarrior and Xcode to produce both the CFM and Mach-O versions of the shim.

The biggest advantage to this approach is that your user interface and processing code is independent of the glue code that passes data back and forth to the host application. You could, for example, easily adapt the “plug-in” part to work with Aperture’s new plug-in architecture and not have to worry about 99% of the rest of the code. We take this approach with our IconBuilder product: PS7 and CS3 have slightly different plug-in specifications, so we offer two plug-ins that use the same UI/processing bundle.

Another advantage to this approach is that you can do testing without having to run under the host application. I use a small test harness that loads the UI/processing bundle and feeds it data. This makes it much simpler to work in a debugger without the host application getting in the way. You could also use a similar technique to build a standalone application.

Finally, there’s much better documentation than when I figured all this stuff out. Here’s something at ADC that will help get you started.

Thank you

Wow.

There’s no denying the physical beauty of the award or the cool prizes that accompany it. But in this “day after” the thing that I’m finding most rewarding is the outpouring of support and congratulations. The six weeks of eating, sleeping, and breathing [REDACTED] preceded by months of digging through class-dump and respondsToSelector output was far from easy: but it’s all worth it.

From everyone here at the Iconfactory, all we can say is thank you. It means so much.

Unfortunately, we’re still under NDA and have been advised by Apple not to share screenshots. We’re all anxious to show off our work, but we need to respect the wishes of our new partner.

If you’re here at WWDC, you can get a look at the UI on the panels on the third floor. There are also some photos from last night’s event that hint at what’s about to come. For those of you wondering about the photo I took before going on stage last night: my big fat finger was over the lens on my iPhone—a great example of why ergonomics in your application is important.

Vote for virtualization

In this election year, there is an issue facing Macintosh developers. Ask yourself the following:

How can you develop new products for Leopard when you need to have Tiger installed for supporting your legacy applications? How easy is it to test a new feature on Mac OS X 10.4.11 when you’re running 10.5? How quickly can you reproduce a bug on 10.4.10 if you’re running 10.4.11? Can you run Xcode versions 3.0 and 3.1 at the same time from /Developer?

We all know the way to get Apple’s attention regarding our issues is to submit bugs. So now is the time to vote for virtualization. If you agree with the following, please copy and paste this bug report and submit it so that it becomes a duplicate of Bug ID# 5812840.

Summary:

A Macintosh developer’s ability to produce world-class products is inhibited by the lack of desktop virtualization.

Steps to Reproduce:

  1. Create a virtual machine using VMware or Parallels on your desktop.
  2. Try to install Mac OS X on this virtual machine.

Expected Results:

You should be able to install and run any version of Mac OS X on this virtual machine as long as the host is a Macintosh.

Actual Results:

The installation does not work.

Regression:

This ability has never existed, but ever since the arrival of virtual machines in Mac OS X, developers have dreamt of being able to do this.

Notes:

The ability to run multiple versions of Mac OS X has many benefits for a Macintosh developer and for Apple:

  • Being able to run any version of Mac OS X in a virtual machine makes it much easier for a developer to create features for both older and newer versions of the operating system. Many developers need to support their existing applications on the current platform, while at the same time developing new applications for an upcoming version of Mac OS X. For example, developers would like to have virtual machines that would allow Tiger and Leopard to run at the same time. The benefit to Apple is that there will be many more applications available at each new OS launch because the barriers to developing on that new OS are much lower.
  • Developers constantly need to test their products on various versions of Mac OS X. If a customer reports a problem on 10.4.11 and the developer is running 10.5.2, there is a significant amount of effort required to bring up a system that allows investigation. The result is that many problems are ignored or deferred. With virtualization these barriers are removed and fixing bugs becomes much easier. The benefit to Apple is higher quality software for the Macintosh platform.
  • Apple often releases beta versions of development tools that are not compatible with older versions. One such example is the current Xcode 3.1 release—it cannot be run simultaneously with the 3.0 release. This creates a situation where a developer working on iPhone applications cannot work on their current Macintosh applications at the same time. Again, developer productivity suffers and the availability of products for both of Apple’s platforms is affected.

Virtualization is currently being made available for the Mac OS X Server product. We respectfully ask that Apple make the same features available in the desktop version of the operating system.

Update: Several people have written to inform me that you can run Xcode 3.0 and 3.1 side-by-side. While this is true, I have heard that there are some problems. We all appreciate the excellent job the developers at Apple do with Xcode and the other fine tools we work with, but there will always be growing pains as these tools advance. Virtualization would lessen the impact of change on our development environments.

Brain surgeons

Unless you’ve been stranded on a remote Pacific isle, you’re no doubt aware of the current furor over third party iPhone applications not being able to run in the background. To be blunt, I’ve never seen so many experts without a fricken’ clue. If you haven’t written code using the jailbreak tool chain, your opinions on the iPhone SDK, based entirely on what you see in a simulator, just aren’t relevant. You might as well be explaining the nuances of brain surgery.

As someone who has been involved in iPhone development for the past six months, please let me offer you a healthy dose of reality.

Twitterrific on the iPhone could definitely make use of a background process to gather new tweets. In fact, a prototype version of the software did just that. And it was a huge design failure: after doing XML queries every 5 minutes, the phone’s battery was almost dead after 4 hours. In fact, the first thing I said after giving Gruber this test version was “don’t use auto-refresh.”

The heart of the problem are the radios. Both the EDGE and Wi-Fi transceivers have significant power requirements. Whenever that hardware is on, your battery life is going to suck. My 5 minute refresh kept the hardware on and used up a lot of precious power.

(Those of you under NDA with the iPhone SDK should take a look at the documentation for Core Location. After reading about how it should be used, you’ll understand why getting your location in Maps and similar applications is only done on an “as needed” basis.)

And right about now, you’re thinking “But I’ll be smart about how I use the hardware.” Sorry, bucko, but you’re the exact reason why we don’t have background processing in the current SDK. You’re living in your own little dream world.

What happens when App A uses the network at 5 minutes past the hour, and App B uses it at 10 minutes past, and App C uses it at 15 minutes past, and so on? There’s no way for you to know what other apps are doing is there? And yet the battery is still taking a pounding.

In my opinion, such a scenario is quite likely. As a satellite device, the iPhone requires contact with other machines to do interesting things. Periodically hitting the network is the primary reason that developers want to run in the background.

Some have stated that Apple is limiting innovation. My opinion is that they are helping us from collectively shooting ourselves in the feet.

It takes several months of actual iPhone development before you eventually realize that the iPhone requires a completely different mindset. Until that happens, you’ll make assumptions based on desktop experience, and that in turn will lead to a lot of bad designs.

For what it’s worth, I think Apple will address this issue in the future. I can imagine a solution based on a plug-in (bundle) architecture that lets your application do things when the phone decides it’s a good time (not when you decide it’s a good time.) If the radios go on because you’re checking Mail, then you get a “network active” notification and a chance to run some short-lived TCP/IP connections. If you take too long, you’d get killed, much like Safari does with Javascript that runs too long.

Do I expect such a sophisticated system to be available in a beta of version 1.0? Hell no. And neither should you.

Hello App Store

The big day has come and passed. And you know what? We’re still in uncharted territory: for most of us Mac developers, the App Store is something new and strange.

Let’s start by looking at Apple’s cut in the deal. Is 30% reasonable?

My first impression was that it seemed a little high, but acceptable. You’re getting someone else to deal with the hassles of downloading, payment processing and, to some degree, promotion. There’s a lot of value in that. Look at what it costs to be on other plaforms, such as Xbox Live, and it seems fair.

But thinking through the situation a bit more, I realized that those things pale in comparison to the value of being associated with the Apple brand. Having their explicit stamp of approval and being included in the App Store will make any product more appealing to a customer. Buying directly from Apple means that your software won’t screw up their phone and that can be returned if it doesn’t live up to expectations. That, combined with the ease of a single click purchase, is going to drive a lot of sales. You’ll make up that 30% without even trying.

Update on March 13th, 2008: A reader, Philip Smith, wrote in with an interesting observation: how many developers have the ability to offer gift cards for their products? Traditionally, giving software as a gift has been a very hit or miss affair. But when friends and relatives can go down to the local grocery store and pick up a gift card for the App Store, that problem is solved. Yet another way to increase your sales with the help of Apple.

One thing that disappoints me about the iPhone SDK sign-up is that the entry fee of $99 is too low. I look at the entry fee as a way to filter out developers that aren’t fully committed to the platform. Unfortunately from what we’ve seen so far, including the load on developer.apple.com on the day of the SDK release, there’s a huge amount of interest. I fear that Apple is going to be overloaded with application reviews, issuing certificates, and other administrative tasks. A higher entry fee would lessen the chance of this becoming a bottleneck for getting my product into the system. Please charge me $499 and let move to the front of the line.

Now, let’s look at how this affects our current business and way of doing things. Even though writing applications for the iPhone is now incredibly easy, selling software is much more than just writing code. My primary concerns at this point are with the details of distribution.

Take a look at our Twitterrific product: we’d love to offer both free and paid-for versions. Will that be allowed in the App Store? There’s also the traditional “try before you buy” model that we’re used to having with our desktop applications. As a customer, I’d like to know what I’m getting before I put my money down. Will the App Store allow some kind of trial period?

As Apple builds out the App Store, I hope they take the approach that they have with the iTunes Store. Let me write an application “preview” that anyone can download freely. If they like it, the buy button makes us both happy. All I need to do in order to make this happen is provide two files to Apple: one is the software equivalent of the 30 second clip, the other is the real deal.

Anyone who’s been selling online for more than one major release knows how important upgrade fees are to the continued growth of a product. It drives new features and keeps the product life cycle moving along. Yet we’ve heard nothing about how this will be handled at the App Store. Will we be able to identify existing users and offer them discounts? Keeping existing customers happy is in my best interest and that of my new partner: Apple.

Update on March 10th, 2008: Another issue that occurred to me was how we’ll be able to offer the product at varying price points. For example, NFR licenses for reviewers, free licenses for contest prizes and discounted licenses for promotions like MacSanta. Again, I hope that Apple keeps our promotional needs in mind as they implement the App Store.

There has also been no indication on how we’ll be able to handle distribution during a beta test. There’s no way I’m going to release a major product without letting a significant number of users run a private version of the application. Can we get these pre-release versions of the product onto their phones without using the App Store? Will the App Store itself provide some special beta mechanism? Will we have to run our own App Store like large enterprises? Any guidance in this regard needs to happen soon, June will be here before we know it.

This is an exciting time to be an OS X developer. I feel confident that Apple will address some of the concerns mentioned above and we’ll all be happy campers by the time the App Store launches. Now, excuse me while I open up my new Xcode project…