Apple is very aware that a crucial aspect to the success of a new platform is getting developers on board. Requiring a Mac for all iPhone development isn’t a good start. That’s the first barrier of entry for a lot of developers, like me, who came from a Linux or Windows background. Strike one. Objective C, even though I have come to like it, isn’t exactly a hot, popular language (although that’s changing a bit). Strike two. Fortunately, Apple doesn’t strike out and gets everything else right. They provide a top-notch development environment, tools, and great APIs.
Don’t worry, I’m not going to get into the details of the iPhone API. You can get all that and more from Apple’s iPhone development web site. I’m just going to talk about my experience starting with a new set of APIs and how they hold up in the process of a full project development.
Apple has done a great job holding the hand of developers new to the iPhone. As soon as you sign up for iPhone development, you’ll have access to several “Getting Started” documents and videos. Some of the videos are a bit on the fluffy, advertising side (“look at our new platform, it’s sooo cool!”), but they’re not a bad intro anyway. The docs on the other hand are pure gold. They’re a perfect introduction but with a fair amount of detail as well. They cover everything, from UI, to graphics and sound, to platform-specific features such as the accelerometer. I still find myself referring back to those every so often.
When the “Getting Started” docs aren’t enough, you have a full reference of all the classes and APIs at your fingertips, both online and through the XCode help system. I found the quality of the class reference to be pretty good. Usually, when something isn’t clear from the function name, the help is good at clarifying things.
I have to admit that I’m not a read-the-manual-first kind of guy. So while all those documents are great, and I use them a lot now, that’s not how I started out. Apple provides a bunch of sample code, covering all the major APIs, so I just downloaded the ones I was interested in, compiled them and fired them up. Then I used the docs to answer my questions about what the code was doing. The Crash Landing project was a perfect example of how to get started with games. I must have spent a whole day just pouring over that code the day I got my hands on the SDK.
Keep in mind that while Apple does a great job of getting the experienced developer up and running on the iPhone, they’re certainly not catering to new programmers. It’s a shame because the iPhone is such a fun, little platform, that I could see lots of kids wanting to jump in and getting their first real programming experience there. I hope that books and other resources pop up with that audience in mind.
Low Level Stuff
Things will look very familiar at the bottom of the API chain. Most of the low-level functionality can be accessed through pretty standard POSIX libraries: thread, file IO, sockets, etc, all in straight C. My code ported over to using this libraries without having to make a single change.
As game developers, the first thing that we worry about is how are we going to do graphics. Fortunately, the iPhone includes an OpenGL implementation, so that’s very familiar territory. Specifically, it’s OpenGL ES 1.1 with a few extensions thrown in. The hardware itself is a fixed-function PowerVR chip with hardware vertex processing and texture combiners. Very 1999 🙂 All of that makes writing 3D graphics app on the iPhone a breeze, even if performance isn’t top notch. At least they didn’t throw yet another proprietary API at us.
Surprisingly, the online help falls short with OpenGL. There are actually hardly any docs on that, and they mostly cover a couple functions to interface with their view system. I guess they figured you can just go to the internet and read all about it there, but I would have expected them to integrate them with the rest of the references at least.
OpenGL meshes relatively well with the user interface libraries, in the sense that you can render to almost any surface and combine it with other user interface elements. Unfortunately, it seems that putting any user interface views on top of OpenGL causes pretty major performance hits, so the integration isn’t perfect.
I haven’t used it yet, but Apple also provides the Open AL API for 3D sound. Again, props to Apple for sticking to an existing API.
This is where the real fun starts. At least for me, this is all new territory. Mac programmers should be a lot more familiar with it. Cocoa Touch are the libraries for all the high-level user interface and accessing device-specific features. Since the iPhone is such an interface-centric device, this is where a lot of your time is going to be spent. The exception is if you decide to make a game that is 100% OpenGL, user interface and all. In that case, you’ll only be using this layer to access a few things, like touch inputs and accelerometer readings.
My impression coming to Cocoa Touch from an MFC/WTL/.Net background and no Cocoa experience was a breath of fresh air. Sure, the interface on the iPhone is simpler than the horrible monstrosities you can create with MFC, so maybe that’s why the API seems simpler. But whatever the reason, it just makes sense. You have one window, views, and view controllers. Once you get how they relate, the rest just comes together. I find myself guessing how things should be and getting it right most of the time. That tells me they’re doing something right (for the record, I never manage to guess anything with the .Net framework and it’s always a struggle).
When something isn’t obvious, you can look it up in the extensive online help, or just crack open the header file and look at what properties each class exposes. The class hierarchy isn’t too crazy, and each level adds a manageable number of functions.
It’s also really easy to extend controls and create your own versions to have special behaviors or even draw them in different ways. To me it was always a pain to create custom controls in MFC with their own rendering, but here it’s a breeze.
I also really like how a lot of controls don’t own your data, or even keep a copy that you need to refresh, but simply ask you for it when they need it. For example the picker (which you can quickly guess it’s called UIPickerView) will ask a delegate how many columns and rows to display and what data or views to render in each of them. Nice and simple.
We’re done with the fan boy raving. Not everything is perfect and some things are downright annoying.
Initialization of views and view controllers can be a bit weird. Sometimes the initFromNib gets called, sometimes it’s the viewDidLoad, sometimes it’s none of those and I have to hook up the loadView function, and sometimes I just have to make one myself. All depending on how the particular view gets created. Annoying.
Then there are some bugs and weird behaviors that you have to put up with. Because Apple doesn’t provide the full source code, you can’t just fix them or copy them and make your own version. Some controls are pretty elaborate so writing them from scratch is quite time consuming. For example, the segment control behaves as a toggle if you only have two segments, but as a button if you have more than two. There is a boolean variable that allows you to turn the toggle behavior off, but, guess what, it’s protected. So to make such a simple change, you need to create your own class and extend the UISegmentedControl. Doh!
Sometimes you’re not even so lucky. Looking at the header file for the UIPickerView class I noticed there was a flag to turn off the sound it makes when rotating the wheels. But it was marked as private (as @package actually), so I couldn’t do a thing about it. Double doh!
And it’s more than a flag here or there. Maybe you’d like to change the background of the picker, or the way the selection works? Out of luck. That’s all neatly wrapped up inside the picker class itself and you have no access to it. If you want to make a change, you need to reimplement it all from scratch. Hopefully Apple will continue refining the API and exposing more functionality where needed.
All of this leads me to my number one complaint about the Cocoa Touch API. It’s something that annoys me profoundly and I can’t believe Apple is doing. The API you have exposed to you is different than the one Apple uses internally. Why oh, why?? It violates everything I hold true and sacred about library and API design. I understand their wish to keep thing simple and clean, and to provide good documentation to everything is there. They managed to do those things admirably well. But why not provide whatever API calls they consider to be “expert” without documentation and a big warning saying you’re on your own? Why???
But wait, it gets better. Apple has been actively rejecting apps from the App Store from people who went to the trouble of reverse engineering the libraries and calling undocumented functionality from them. What is up with that? Is it Apple’s way of ensuring future compatibility? Then how are their own apps going to work when changes happen since they’re obviously using a bunch of undocumented features. Not only that, but they get it wrong sometimes!
I thought this was as bad as it was going to get, but wait, there’s more. Apple is playing favorites. So if you’re a big company and have two Os in your name (and your name doesn’t start with M) then you get to use their undocumented APIs without getting rejected. How totally annoying is that?
All In All…
Apart from the questionable decisions of what to expose in the API and a few stray bugs, the iPhone has a great set of APIs to develop for. I found it really easy to get into them and became productive in no time. If only they would expose the full functionality, it would be an almost perfect setup.