iPhone from A Game Developer’s Perspective: The iPhone API

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.

Starting Out

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.

Cocoa Touch

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.

  • Eric Scrivner

    Great article, I’ve recently started Cocoa and iPhone development myself and it’s good to read the opinions of someone else as well. Keep the good articles a-comin’ :)

  • Claus Hoefele

    Because you mentioned the fixed-function PowerVR chip: I wonder if you mostly use fixed-point math or if the iPhone is fast enough with floating-point calculations.

    I find the lack of common basic types such as float and stl::vector makes it difficult to share code between game engines for Windows/Mac and smartphones.

    Last time I looked, Wolfgang Engel’s Oolong Engine makes heavy use of floating-point math and he also uses USTL, see http://www.oolongengine.com/, but I somewhat doubt the performance beyond simple demos.

    I’d be interested in reading your thoughts about cross-platform development or whether you see your iPhone games as completely separate implementations.

  • mos

    @Claus Hoefele

    No stl? Yikes. That’s …not good. I’m going to have to refactor quite a bit of code later this week when I pick up my mini. (I naively thought I could write the C++ game engine in Visual Studio.)

  • Michael Seare

    “I hope that books and other resources pop up with that audience in mind.”

    Hmmm… I smell another book you can write. :-)

  • http://www.gamesfromwithin.com Noel

    Claus,

    To tell you the truth, I hadn’t even looked into the STL. I don’t like it for runtime stuff, so I didn’t even think of looking. The template support in the iPhone compiler is a bit old, but I just checked and the STL headers are there and they compile and link just fine. One weird thing is that they aren’t in the std:: namespace but in _GLIBCXX_STD. WTF? :-b

    Even if that wasn’t the case, I’m sure you could get STLPort or uSTL to work just fine.

    As far as floating point support, is right there. The CPU has a hardware floating point unit, so performance is supposed to be decent.

    I admit that I’m working on 100% iPhone exclusive apps though, so I’m not trying to keep them cross-platform. I was able to create a prototype in C++ and OpenGL on Windows and have it up and running on the iPhone with almost no changes though, so as long as you’re not doing iPhone-specific stuff, porting should be pretty easy.

  • http://www.gamesfromwithin.com Noel

    No way Michael! No way I’m writing another technical book any time soon. It’s such a thankless job and there’s hardly any money involved unless you’re targetting a huge audience.

  • Rod

    I think I tried STL as a test and it worked, and I also installed Boost and it works as well.

  • Tim

    Regarding your issue with the UIPickerView sound flag, Objective-C doesn’t really have private variables. With Key Value Coding (KVC), you can get and set the value for any member variable. Use -valueForKey: and -setValue:forKey:. Now, you still might not want to do it since Apple could change the _pickerViewFlags structure at any time.

    I recommend the new book Learn Objective-C on the Mac. It is a good, concise book that teaches cool ideas like this.

  • Rod

    Is there somewhere I can get a copy of the “Crash Landing,” source? It appears to be no longer available in the Apple Developers samples.

    thanks

  • http://www.gamesfromwithin.com Noel

    @Tim: I looked into accessing _pickerViewFlags from UIPickerView through valueForKey, but that was a no go. I was able to access the private variables OK, but somehow not that one (it would cause an unhandled memory access just to try and access it). I don’t know if it’s because it’s in the @package visiblity or what.

    Then I tried to do a really horrible hack: Figure out where _pickerViewFlags is in memory (UIPickerView + 0x3C) and change it directly. Unfortunately, it looks like soundsEnabled is not really used! I can tweak some of the other variables, and turn off the selection bar for example, but the soundsEnabled bit is turned off already.

    Thanks for the technique anyway, I’m sure it’s going to come in handy. Too bad it won’t solve this one problem.

  • http://3DTOPO.com Jeshua Lacock

    Hello Noel,

    Is there anyway you could tell me what variable you used to disable the selection bar for the UIPickerView?

    Thanks!

  • http://www.gamesfromwithin.com Noel

    There’s no need to get into undocumented stuff to turn off the selection bar in UIPickerView. Just turn the property showsSelectionIndicator to false and you’re all set :-)