Now that we’ve had a year to get the 99-cent “ring-tone” apps out of our system, are you ready to write some serious software for the hottest platform going?
It’s been a few years since Apple has used its television ads to tell us to “Think Different.” But maybe their actions speak louder than words: with the iPhone SDK, they’ve brought a desktop-like platform and toolset to mobile developers, while the App Store offers a hitherto unheard-of number and variety of applications to users. The competition sure isn’t thinking different: within a year of the App Store’s launch, “me too” app stores are popping up on other platforms almost monthly.
But what about you? Is this a field of programming you should get into? In this article, we’ll take a brief look at what’s involved in iPhone development, focusing on language, frameworks, tools, and distribution. If you like new challenges, I think you may well be intrigued by what this new platform has to offer.
Code Different: Objective-C
Chances are you’ve heard that iPhone applications are written in Objective-C. Recruiters certainly have: online iPhone job postings seek candidates with an arbitrary number of years of experience in this ostensibly exotic language. Yet Objective-C is fundamentally like other object-oriented languages such as Java and C++, and a developer can learn its core concepts in an afternoon.
Objective-C is a “strict superset” of C, meaning only that any valid C program compiles in an Objective-C compiler. Primarily, Objective-C adds a Smalltalk-inspired object layer atop C. In the abstract, the concepts aren’t unlike other OO languages: classes use single-inheritance (like Java and unlike C++), protocols allow you to define methods that can be implemented in multiple classes (similar to Java interfaces, but with the option of marking some methods as optional), and you call methods on these objects.
Well, you don’t really call methods, per se. While it is convenient to use that terminology, Objective-C technically sends messages. This is an important distinction, as it allows for interesting flexibility in the language. What we see as a method call is maintained by the Objective-C runtime as a string naming what is to be called. In effect, the runtime asks the receiving object if it implements such a method, and if so, the runtime sends it the parameters. The practical upshot is that for a compiled, strongly-typed language, Objective-C allows for dynamic traits we typically associate with scripting languages.
Oh, and the square braces. And the really long method calls. We can’t let this syntax escape our gaze, since the first glimpse of Objective-C code seems to give some developers shivers. Square braces denote the sending of a message, with the name of the message/method split up to denote its arguments, like the following:
In this pseudo-code, target is the object being operated on, and message:with: identifies the message to be sent (written with just the message name and not the argument types, it is called a selector). While seemingly verbose, the style is highly self-documenting. Other C-based languages may send you scurrying for the docs when you come across a function or method call with three or more comma-separated arguments, but a similar Objective-C call speaks for itself, like the following:
Notice in this example, the * character on our local variable. This is your constant reminder that despite the consistent and coherent world of objects that has been created for you, at the end of the day, you are still in the land of C, with every object an honest-to-goodness C pointer. For some developers coming over from scripting languages, the asterisk is a strange bit of arbitrary syntax, but those who’ve worked with C know well the power and danger of working with pointers. Free the pointer and then mistakenly re-use it, and you will likely be headed to a memory-related crash (often the dreaded EXC_BAD_ACCESS that so baffles newcomers). The realities of C can be ignored for a while, but in time, you should familiarize yourself with the wisdom of Messrs. Kernighan and Ritchie, or any modern equivalents you can find.
Call Different: Cocoa Touch
For many of us, what makes a platform is not the language but the libraries. After all, on the Mac, you can develop Mac applications not only in Objective-C, but also Ruby and Python. The iPhone remains Objective-C-only, but as in Mac development, you write your applications in the rich Cocoa environment. Technically, Cocoa is not a set of libraries, but frameworks, which in Apple’s use are collections of code libraries, documentation, localizations, and any other resources (perhaps images and sounds) needed to use them.
These frameworks are much-tested and refined from years of use. Most of Cocoa traces back to the original NextStep operating system developed over 20 years ago, which evolved into Mac OS X and then formed the basis of the iPhone OS. While the UI layer is new for the iPhone, specifically designed for use on a mobile touch-screen device, core classes like strings, collections, dates, URLs, etc., are the same as on the Mac, well thought-out and well-understood.
Using Cocoa Touch, as it’s called on iPhone OS, may require a shift in attitude. While other platforms are customized through subclassing—Java exhibits this to an extreme—Cocoa places a high value on making its classes usable as-is. In many cases, you customize a class through the delegation pattern. With this approach, you supply an object with a delegate that implements some methods of a protocol, providing your custom behavior in these callbacks. For example, every iPhone application should, at startup, set the delegate property of the UIApplication object that represents the application’s existence and role within the iPhone OS. This delegate implements the UIApplicationDelegate protocol, and is called when events of interest to the application as a whole occur: the application has started up, the application is running low of memory, the application has received a message from Apple’s “Push Notification Service.” To the developer, it looks and feels like a lot of callback or listener patterns, but to Cocoa, the idea is that a given class cannot know how it is to react to a specific situation, and relies on its delegate, if any, to act. In this case, the UIApplication object doesn’t know what to do when memory gets tight, so it throws control to the code you’ve provided as the app delegate and says, “hey, do something!”
Delegation is one of the most common, most distinctive traits of Cocoa programming, one that is made possible by Objective-C message dispatch: delegates are set late, and the Objective-C runtime inspects delegates to see if they respond to a delegate message at all, moving on if they don’t.
Delegation is one of the most important Cocoa patterns, but it’s not the only one. Model-view-controller is present and accounted for throughout Cocoa Touch, most obviously in the GUI classes: onscreen views subclass UIView, and you’ll typically manage them in subclasses of UIViewController (yes, you do some subclassing!).
A crucial pattern to learn is Cocoa’s scheme of memory management. On the Mac, Objective-C offers garbage collection, but this is absent on the iPhone. Instead, you must employ a scheme of reference counting. All Cocoa objects maintain a count of references to themselves. Objects begin life with a reference count of 1, which is incremented any time another object wants to share in ownership of the object, by calling the retain method. Owners that have no further use for an object release it, decrementing the reference count. When the count goes to 0, the object is freed. It is challenging to get used to, particularly if you’ve had a garbage collector cleaning up after you, but the basic rules are simple: if you create an object (by means of the alloc method), or retain it, you must call a corresponding release at some point. Conversely, if you acquire an object by other means, such as a “getter”-style call, you don’t own it and must not release it.
It’s also worth noting that iPhone programming isn’t all about Cocoa Touch. The platform includes a number of third-party libraries that are largely independent of Cocoa Touch, such as OpenGL for 2D and 3D graphics, OpenAL for spatialized sound, BSD sockets, and an API for using the included SQLite database. These are all programmed in procedural C, as are a handful of Apple frameworks, some of which offer a greater level of control (at the price of complexity) than their Objective-C counterparts. And in a few cases, such as graphics (Quartz) and audio (Core Audio), there may be no Objective-C counterpart, meaning you’ll have to use procedural C directly. Fortunately, Apple’s C-based frameworks generally employ design patterns similar to what’s used in Cocoa, in some cases forging quasi-object structures that can be cast to Objective-C objects at no cost.
Build Different: The iPhone SDK Toolset
Thus far, I’ve discussed the language and frameworks in the abstract, without touching on the craft of code, where fingers meet keys, and code meets compiler. The SDK includes a compelling set of tools to master.
You’ll develop your applications with Xcode, an Integrated Development Environment that will be familiar to users of other IDEs, and is more or less comparable to its counterparts on other platforms. When you begin an Xcode project, you choose the style of application you want to write (an app with a single view, one that flips between two views, one that navigates through many views, etc.), and it sets up the GUI resources and a basic set of application delegate and view controller classes to get you started.
Xcode sits atop the classic GNU C compiler and debugger, but makes their use far more appealing than they could ever be on the command line. As you set breakpoints in your code and step through statements, you can mouse over the variables in your source to see their current values and members pop-up as you mouse over them, or view them in a more traditional debugger window with source, assembly, and variables. Better yet, this works not only with the capable iPhone Simulator (which runs your iPhone application in a Mac process on your desktop), but also remotely with your code running on an actual iPhone or iPod Touch device.
The SDK also provides a set of performance tools to help you find and fix slow spots in your code. Shark lets you get up and running quickly with an overall assessment of which function and method calls consume the most of your app’s running time. For a more detailed view, you can use Instruments, which samples your application as it runs and lets you view your app’s runtime history on a timeline, examining specific points at which the app’s CPU or memory use spiked, with the ability to trace down to specific calls. To top it off, the open-source Low-Level Virtual Machine (LLVM) group’s Clang Static Analyzer project works with iPhone SDK projects, allowing you to perform a build-time analysis of your code to find errors like memory leaks, unreachable code paths, unused and uninitialized variables, and more.
Design Different: Interface Builder
iPhone applications are also distinguished by their appearance, something that is greatly facilitated by the most unique of the SDK tools, Interface Builder. Many platforms have GUI builders, but few are as tightly integrated as Interface Builder.
The most distinctive feature of Interface Builder is that unlike so many other GUI builders, it does not generate code that you then compile. IB creates honest-to-goodness Cocoa Touch objects, allows you to customize them, and then serializes the objects to disk inside nib files. At runtime, your application loads the nibs, deserializing the GUI objects and adding them to the GUI.
“But,” you might ask, “without code, how do I provide the GUI components with any behavior of my own?” In one of the most unique (some would say peculiar, others would say awesome) patterns of iPhone and Mac development, you use IB to relate objects to variables and methods in your code. An outlet, marked with the IBOutlet keyword, is a variable that is meant to refer to an object loaded from a nib. You associate the outlet with an object by connecting dots in IB, an association that is stored in the nib and is “wired up” when the nib loads. Similarly, an action is a method that can be called from an object created in IB, commonly from an event generated by a GUI object. For example, your view controller code might have an IBAction that is connected to a button’s “Touch Up Inside” event (i.e., the user has tapped and released the button), which does some work and updates a table in the GUI, which it accesses by means of an IBOutlet to the table.
Some developers seem to over-think IB, and look for ways to retreat to the seeming safety of creating GUI objects in code. The key is to understand that the objects created in IB are honest-to-goodness objects, stored in the NIB along with enough information to bring them to life in your application: what kind of class “owns” them (and therefore can provide outlets and actions), the actions and outlets to connect to, etc.
So why do it this way? One advantage of IB is its tolerance for radical interface overhauls. If your GUI builder generates code, it’s hard to avoid modifying that code, or at least depending on its implementation details. With IB, there’s a great deal of decoupling of GUI and logic, connected only by the outlets and actions. Designers can own the GUI and make profound changes, in many cases acting independently of coders.
Deploy Different: The App Store
Coming from the desktop or webapp world, it’s hard to appreciate how locked down mobile platforms have traditionally been. I often relate the anecdote about being at a mobility conference just a month before the unveiling of the iPhone SDK, attending a role-playing panel discussion in which a carrier representative openly mocked the romantic notion of the indie developer toiling away on a breakthrough application. She asked the panel member representing the mobile developer if he was interested in going “big time,” with zero interest in his application if he wasn’t.
And two years ago, that would have been it: many carriers and handset makers used security technologies to cripple or utterly disallow third-party applications, allowing users to at best see a handful of apps from big-name corporate partners. A forum post I saw years ago put it perfectly: the carriers couldn’t stand the thought of you making a buck off their network if they don’t keep 99 cents.
Instead of you being left with just a penny, how does 70 cents sound? Or, if you like, give your app away for free, and pay nothing for hosting or bandwidth. Those are the options offered by Apple’s App Store, the primary means of delivering iPhone OS applications to iPhones and iPod Touches. You enter into an agreement with Apple, deliver your built-for-distribution application with some metadata (description, screenshots, support e-mail, etc.), and the App Store lets users download your app to their devices. As a developer, you don’t have to deal with hosting, authentication, billing, or any of the other tasks that developers don’t particularly like to deal with.
The openness of the App Store has been revolutionary, with indie developers offered as much access to the end-user as big companies enjoy, and with the indies often outshining their deep-pocketed peers. With a billion and a half downloads of the more than 60,000 apps available in the first year of the App Store, it’s comical to see other platforms and carriers, the same ones who turned up their noses at small-fry developers, racing to get their own app stores into production.
As the biggest break from convention, the App Store isn’t without controversy, mostly involving the opaque review process that all apps must undergo before appearing in the store. A slow approval process has frustrated developers trying to get bug fixes to users, who post negative reviews and complaints about problems that already have fixes done and awaiting release. In an event earlier this year, Apple crowed that 98% of apps were approved in 7 days or less. But the more significant complaints about store reviews have involved the fairness of the process, as well as the competence of reviewers. In one recent controversy, developers have complained that Apple is now requiring them to apply an “adults only” rating to apps that can connect to the internet, and therefore access potentially illicit content. By this logic, the iPhone’s bundled web browser, mail app, and iTunes player should all be similarly rated and restricted. Other developers have had apps rejected for unwittingly duplicating functionality of upcoming software updates, or providing functionality that is merely similar to Apple-provided apps.
The other challenge with the App Store is one of marketing: with tens of thousands of apps in the store and more arriving every day, it’s hard to stand out. If the App Store interface is the only way for users to find an app, it leads to a battle to get visible in that interface, something that many have tried to do by gaming their prices to get into the “Top 25” tab, creating a downward price spiral that hurts all developers. But the App Store isn’t the only way to get noticed: it’s easy to provide a web link that takes browser users to the App Store (either on their iPhone, or via iTunes on Mac and Windows). As the iPhone platform continues to grow, it’s likely that more and more people will discover apps through means other than the App Store itself. At least that’s my fervent hope, because there are whole classes of applications that won’t get written if developers can’t charge more than a dollar or two for them.
In many ways, the iPhone goes against a lot of the recent trends in software development, conventional wisdom we’d taken for granted. While we’ve spent much of this decade learning scripting languages, praising Open Source, and predicting that everything would eventually turn into webapps, the iPhone SDK revolution arrived in the form of C-based native applications on a highly proprietary and closed platform. That it’s successful at all should give many of us pause to rethink our assumptions and beliefs: were webapps only popular because they didn’t have to be installed? Did the App Store solve that?
Now that the iPhone is the most talked about platform of the day, it might make you wonder if you should jump on board. The price of admission is low. To run the SDK, you’ll have to use an Intel-based Mac, reflecting the high level of code sharing between the Mac and iPhone. The SDK and basic membership in Apple’s iPhone Developer Program is free, allowing you to get your feet wet developing apps and run them in the included iPhone Simulator. When you’re ready to test your code on a device, you need to purchase either an iPhone or an iPod Touch, and upgrade to a paying developer membership (currently $99 for individuals, $299 for corporations). With your paid membership, you’ll be able to generate app-signing certificates to put code on your device, and to submit apps to the App Store.
We’ve heard a lot in the media, and from Apple’s own PR, about “get rich quick” stories, developers who plugged away on iPhone code at night, hit the jackpot, and quit their day jobs to tour the world. Entertaining as these anecdotes are, I’d like to encourage you to set them aside and consider the merits of iPhone programming as an end in itself. If you’re, for example, a server-side middleware developer who works in Ruby or Perl, the experience of writing user-facing mobile applications in Objective-C couldn’t be more different than what you’re doing now. As an intellectual exercise alone, an exposure to Cocoa’s patterns, Interface Builder’s elegance, the challenge of working with significantly limited resources, and the sheer fun of getting a whole lot of cool into a tiny little app is probably irresistible to many developers.
Perhaps more importantly, the emergence of the platform and the popularity of quirky third-party apps means that the indie developer is back. And with luck, he or she can actually pay the bills by working on a platform that’s fun and intellectually rewarding.
We’ve had a year to get the 99-cent “ringtone apps” out of our system, and every week we see remarkable new ideas take flight in the App Store. And this is only the beginning. Declaring that “there’s an app for that” is premature; there are lots of great ideas that don’t have apps yet. Will you write one of them?
Chris Adamson is a writer, editor, developer and consultant specializing in media software development. He is the co-author, with Bill Dudney, of the forthcoming Pragmatic Bookshelf book iPhone SDK Development. He has served as Editor for the developer websites ONJava and java.net. He maintains a corporate identity as Subsequently & Furthermore, Inc. and writes the [Time code]; blog.