As I mentioned last week I've started learning more about developing for the Apple iPhone. This week I'll be sharing my experiences during a 5-day course on iPhone programming presented by Joe Conway from Big Nerd Ranch. In particular, I'll be pointing out differences between Android and iPhone development.
I have to preface this by saying that I'm not a big fan of class instruction. Give me a computer and an internet connection and I'm usually happy to find out everything on my own. The down side of this technique is that I sometimes spend a lot of time going off on some interesting tangent that, strictly speaking, isn't necessary for the task at hand. Classes enforce a linear learning structure, which some people like but I find a bit restraining. There's something to be said for total immersion in a subject though, in a setting where you won't be interrupted. So that's what I'm doing this week.
The first day of classes covered the following topics:
- Simple iPhone Application -- Creating an XCode project, bringing up the Interface Builder, and using Targets, Outlets, and Actions.
- The Device -- Provisioning, setting a default icon, and setting a frozen UI image.
- Text -- Defining the UI, TextViews, TextFields, responder chains, and the virtual keyboard.
- Delegates -- Handling user interface events.
- Core Location -- Location based services.
Here are a few impressions I recorded during each session, followed by a wrap-up of my conclusions for the day:
Next: Simple iPhone Application, The Device > Simple iPhone Application
iPhone programs are typically written in Objective-C, a language that first gained popularity in the NeXTstep user interface in 1988 and then later in MacOS X in 1996. Objective-C was an attempt to add Smalltalk like object orientation to the C language. In fact some of the initial implementations were simple preprocessors that produced C code. Aside from Apple, almost no one uses the language any more, tending to favor other OO languages like C++, Java, and C#. Android uses Java for example.
The Interface Builder program is the real jewel of the iPhone development toolkit. Like any GUI editor, it lets you design your user interface visually instead of using code. However, you can tell that IB has essentially been refined over a period of about 20 years because it's a joy to use. Of all the UI builder programs I've used, there are only a handful that I would consider to be in the same league (MS Visual Studio, NetBeans Matisse, Instantiations WindowBuilder). In particular, there's nothing close to this for Android.
All iPhone development is done in the Xcode development environment. As IDEs go, Xcode is adequate. I found myself missing several features of Eclipse such as hover help, code generation (for example of getters and setters), and good code completion. Compiler errors aren't discovered until you save and build the project, unlike the instant feedback you get with Android development in Eclipse. However given enough time to become familiar with it, I'm sure you can be productive.
I already covered some of the challenges getting your application onto a physical phone in my last article so I won't rehash that. Once all the certificates are set up once you don't have to worry about them again, so today it wasn't an issue.
Both Android and iPhone devices are accessed via a USB cable during development. Both allow you to set breakpoints, single steps, and view variables in the IDE. Both are sluggish in downloading and starting up your program in each iteration of the compile-build-debug loop, though it was a bit faster on the T-Mobile G1 phone than the 1st generation iPhone I was using for the class. Once the app is loaded on your phone, you can disconnect and walk around with it, which is essential for a location based application. Of course you can't debug while walking around (unless you're especially dexterous with a laptop I suppose), but there are limits to what one can expect.
One unique feature of iPhone apps is the "default image". Basically you run the app once and take a screenshot of it, then save the screenshot as Default.png in the app bundle. The next time you build and start the program it will show the static image for a few moments and then do a little slight-of-hand to swap it with your real program. This gives the user the impression that app loading is a little quicker than it actually is, as long as they don't try to touch any of your fake buttons until the real ones appear.
In Android, instead of a default image the system looks at the theme you have set up for your app and begins by displaying that. For example, if your theme says you have a blue background, Android will show that first before your app is done initializing. So far I've never noticed a delay where just the background was visible for more than a faction of a second on the gPhone. However on the iPhone the default image does show long enough for it to be important.
Next: Text, Delegates >
For the class we created a few sample "Hello, iPhone" type of applications. One used a TextField, a TextView, and a Button. The main difference between TextField and TextView is that the former is just for one line and the latter is for many lines. Interestingly, they subclass different classes in the UI hierarchy and have some behavior differences regarding keyboard support.
Again I was struck by how useful the Interface Builder is. Although IB does create an XML file behind the scenes, you never edit this file. Contrast this with Android UI design where you're forced to edit the XML text. The Android XML layout file is much simpler than what IB creates, though, so it's not too onerous, but I will find myself missing IB when I go back to Android.
Objective-C uses delegates and protocols the same way that Java uses listeners and interfaces. To receive a user interface event like a keystroke you make your class implement the UITextViewDelegate protocol and then implement methods such as textFieldShouldReturn. Although the names are different, the concepts are somewhat similar to Android and Swing programming. Instead of event bubbling you have a responder chain, but it's 6 of one and a half dozen of the other.
One big difference between Android and iPhone code is that the dynamic nature of Objective-C. To a large extent, Objective-C is dynamically typed, while Java is statically typed. Dynamic vs. static typing is something of a religious preference among some programmers, so I won't try to talk you out of your favorite, but I will say that it's very common to make errors in an iPhone program that are not caught until run time. For example if you implement one of the protocols so you'll get called when some event happens, if you make the tiniest error in the declaration you won't get an error and you also won't get called. The instructor indicated this was very common and suggested adding logging statements in your event handlers to make sure they are really called. I prefer getting an error earlier, rather than later, in this case.
Another big difference is the lack of garbage collection on the iPhone. In an Android program you allocate objects and don't free them - Android frees them when it notices they are not needed any more. On the iPhone you have to explicitly keep track of reference counts using the retain and release messages. I can see how it would be very easy to leave memory leaks in an iPhone program, especially a long running one where tiny leaks can add up. On the other hand, this programmer convenience comes at a price. Tiny pauses to clean up garbage in an Android app might come at a bad time, so memory allocation is somewhat discouraged on that platform, especially in tight loops and in your onDraw() method which is called on every screen refresh. So on both platforms, you can't ignore memory allocation and deallocation issues.
Core Location is a service available on the iPhone that lets your program query your current geographical location. As on Android phones you can ask for various degrees of accuracy and the phone will use GPS, Cell tower, or WiFi location as appropriate. There's not much to say about this except that the iPhone's location API is a bit less complicated than Android's, but gives you a bit less flexibility in return. For example on Android you can query all the location providers and make some intelligent decisions if you want to in choosing between them. Both offer a way to filter calls so you don't get an update every 3 feet if you only want to know your location within 100 meters.
Conclusion, Day 1
There are many similarities as well as differences in programming on the two platforms. During Day 1 I've mostly concentrated on differences in the development environments. iPhone's Interface Builder certainly shines here, but Xcode's editing capabilities are no match for the Android Eclipse plug-in for grinding out the code. Memory management on the iPhone is closer to the metal, but dynamic method calls sometimes make development more challenging. So far it seems that it's easier to create a correct application on Android, but some developers might object to the hand holding needed to achieve that.