So I’ve had a bit of exposure to both the iPhone and Android SDK’s, and while my impression of both is generally positive, each one has some of its own unique strengths and weaknesses.
To begin I’ll focus on one of the iPhone SDK’s biggest strengths: Interface Builder. This is a very slick and polished tool for building out an interface (or for more complex applications, the basic underpinnings of an interface) and hooking it up to the rest of your code, and it completely blows away Android’s layout-editor. With Interface Builder, it is generally possible to build exactly what you want using simple drag and drop interactions. With Android’s layout editor, often the best you can do is express the general idea of what you want using the graphical editing tools, and then you are forced to manually edit the XML document that the layout editor generates in order to fully realize your idea. Put simply, I have never once had to manually edit the XML output by Interface Builder, and I have never been able to build a non-trivial Android UI without having to do at least some manual editing of its XML output.
Interface Builder is not without its faults, however; its mechanism for configuring referencing outlets for UI elements is counter-intuitive to the newcomer, at best, and the way it integrates with your XCode project seems to be more as if by magic than through any discernable coupling. Perhaps you like such behind-the-scenes magic, but personally when I am coding something I like to be able to see how all the tools are fitting together, and that’s something that you can’t do with XCode and Interface Builder. And with respect to configuring referencing outlets I think Google has the better approach here, generating a single class that any other class can use to directly reference any bundled resource (interface components, images, properties files, etc.). I fault them for calling this class “R” and not something more meaningful like “Resource”, but the overall concept behind it is sound, and I think superior to Apple’s approach of requiring that each reference be manually configured by the developer.
And of course, Apple does have a bit of an unfair advantage in the realm of user-interface editing. They only need to worry about targeting a single device with a single interface resolution (the 2x resolution “retina display” models implement an internal scaling algorithm so that they, too, can be targeted using the original iPhone resolution), while Google’s Android SDK developers need to target a myriad of devices, each one with a potentially unique interface resolution. In essence the UI for an iPhone application can be effectively specified using a fixed/absolute layout, which greatly simplifies things for Interface Builder. On the other hand, the lack of a consistent interface resolution in Android devices means that layouts must be specified in a relative fashion that allows them to change as needed to accommodate different screen resolutions. This makes the task of building an effective interface editor much more complex for the Android guys.
As an aside, I find it interesting to note that both Android and iPhone use very similar XML-based layout systems, so in theory there is nothing preventing Google’s implementation from being just as smooth as Apple’s, apart from a lack of polish. And I would be that that will come in time.
Platform and Tools
Moving along, and pushing a bit closer to the realm of personal opinion, there is also the difference in development platform, tools, and language to consider. If you are doing iPhone development, then you have very little choice in the matter. You must develop on a Mac (or Hackintosh) running the latest version of OS X; your only real option as far as IDE’s are concerned is XCode, and you’ll be writing Objective-C. Android developers have a bit more freedom. You can choose to develop under OS X, Windows, or Linux (or presumably any other operating-system that can run Java), although you are still essentially locked into a single IDE; Eclipse (you can technically use other IDE’s, but the Android development plugin only works with Eclipse, so you probably won’t want to), and you’ll be writing code in Java.
While the merits of one OS versus another can be debated endlessly without ever reaching a definitive outcome, I think Android comes out the winner by virtue of letting developers choose their desired operating-system. Would it be terribly difficult for Apple to do the same? I don’t think so, however I very much doubt that they will in the near future. With respect to IDE’s, I do personally feel that Eclipse is a better product than XCode, particularly if you have multiple projects that you are working on, and doubly so when SCM is introduced. But then, I am sure there are some people, somewhere, who genuinely prefer coding in XCode, no?
And as for Java versus Objective-C, that’s mostly a matter of personal preference. Both languages are reasonable, although nowadays there are probably more developers who are comfortable with Java than with Objective-C, and in some areas Objective-C does show its age; particularly in the realm of memory management. There is also a wider variety of Java-based libraries and build tools available, and using them with an Android project is generally a bit simpler than accomplishing the same task in the Objective-C and iPhone world. But in the grand scheme of things, it’s really not enough of a difference to say that one platform is any better than the other here. Both languages are reasonable, and a skilled Java developer should not have much difficulty adapting to Objective-C, or vice-versa.
Even further in the realm of personal opinion lies the relative merits of the SDK frameworks themselves. The iPhone SDK is built strictly around the model-view-controller pattern, and the development tools all but force you to structure you applications in this same pattern. You can subvert it if you want to (not that you would), but you really have to go out of your way to do so. The Android SDK, on the other hand, is a bit more free-form. Yes, there are model-view-controller overtones throughout, but the pattern is not as thoroughly pervasive as in the iPhone SDK, and more significantly, the developer can choose to follow some other pattern if they prefer without being penalized by the framework SDK and its tools.
Of course, this freedom comes at a price; model-view-controller is widely viewed as a very good pattern to follow in many circumstances, and freedom to choose a different pattern means freedom to choose a less appropriate pattern, a bad pattern, or even no pattern at all. Ultimately each SDK is following a different philosophy here, but I don’t think that one approach is inherently any better than the other. The rigidity in Apple’s approach may frustrate beginners and advanced users alike while giving intermediate-level coders some comfort in its uniformity and predictability. And while the extra freedom afforded by the Android SDK may prove useful to the skilled developers, it also makes it easier for neophytes to dig themselves into a hole and requires that the intermediate-level developer devote more thought to the overall structure and architecture of their code. Each approach has its own pros and cons.
Both platforms start out equal here, with both Android and iPhone providing developers with access to an SQLLite database for use within their applications. Apple goes one step further, however, and provides Core Data; an ORM framework that runs on top of the SQLLite database and abstracts away the actual database operations. As such, the iPhone SDK enjoys a slight advantage here. While Core Data is a bit crufty in its terminology and somewhat restricted in its functionality, it is still much better in most cases than writing SQL directly.
But even ignoring its pedantic nature and functional limitations, Core Data is not perfect. If you change your data model after your application has been released you will be left with little choice but to go through the Core Data migration process (if you don’t, you app will simply crash the moment it tries to access the old database instance). And while this process is generally adequate for simple migrations using simple schemas populated with a relatively small number of entities, you are in for an onerous time if you have a complex data model populated with several hundred (or more) entities. You may experience crashes caused by memory-management issues internal to the Core Data framework (I suspect that it doesn’t periodically re-fault entities as it migrates them, causing them to “leak” during the migration process), and there is no straightforward way to wrest control away from the framework to try and rescue things yourself.
In this sense, having to write some manual SQL statements to update your data model may well be preferable to Core Data. You have full control over the process yourself, and the ability to ensure that the migration is performed in an efficient way that won’t crash the system or cause the app to fail if it is opened with an outdated schema revision. And it’s worth noting that while Android doesn’t provide any explicit ORM framework for developers to use, it also doesn’t prohibit developers from bundling an ORM framework of their choice with their app. As the platform uses a custom Java SDK and runtime, there are quite a few potential candidates available; though sadly not long-time favorites like Hibernate and other similar tools.
So you can have ORM on Android if you want it, you just have to pay the cost of bundling and configuring it yourself. Overall it’s not a bad solution, but it still lacks the convenience of Apple’s approach with Core Data, which is entirely adequate to cover the needs of most developers, most of the time. As such, the iPhone SDK comes out slightly ahead of the Android SDK here.
Another important part of both the iPhone and the Android SDK is their device simulator/emulator software. And here is another area where the iPhone SDK shows its polish. The iPhone emulator is fast, sleek, and looks and feels very much like an actual iPhone. It has an on-screen keyboard that works just like the on-screen keyboard on the actual device, and the same applies to all the standard built-in navigation components as well. The Android emulator, on the other hand, feels and looks a lot more like a window with an Android UI drawn into it. There is no on-screen keyboard, instead you get a kind of sad-looking grid of keys that sits next to the Android window, and the same applies to the navigation buttons. The Android simulator feels a lot less like a simulator, and a lot more like a tool.
But again, much of this is not Google’s fault. Apple only has exactly one device to worry about, and they have complete control over and advance knowledge of its capabilities. Furthermore, they benefit more from having a robust simulator, because they are in the business of manufacturing physical handsets far more than Google is or ever was (Nexus One notwithstanding). Android has literally dozens of different devices to worry about, some of which have physical keyboards, some of which do not, and each of which may implement a unique navigation layout/paradigm. In this light some of their simulator’s limitations start to make sense, and I will say that Google has come up with a good solution to this issue; creating a virtual Android device of any desired configuration is quite simple, and works exactly as it should. In the end, while the iPhone emulator certainly feels a bit nicer to use and delivers an experience that more closely mirrors the actual device that it is simulating, both emulators are acceptable when it comes to actually getting the job of testing and debugging done.
One other thing I feel I must say about the Android simulator, unfortunately, is that it is slow. Painfully so. It’s tempting to blame Java for this shortfall, but I’ve been around Java enough to know that well-designed and optimized Java code is very nearly as fast as compiled binaries. The difference in performance between the Android emulator and the iPhone emulator is an order of magnitude greater than any variance that I would credit to the Android emulator being Java-based where the iPhone emulator is a native binary. As with some of the other Android development tools, I suspect the problem here is mainly a lack of polish, and that the situation will improve in time.
Lastly, deploying a development copy of an application to a physical iPhone for testing is a ridiculously circuitous process (at least initially), requiring multiple round-trips between the developer and Apple to generate, configure, and download the certificates and provisioning profiles necessary to cajole an iPhone into accepting a developer’s application. To further complicate matters, these certificates expire periodically and must be refreshed, and they also impose various other limitations on what actions a developer or development team is allowed to take. All told, it is a very developer-unfriendly process, and probably an offshoot of Apple’s “we control everything that happens on our devices” paranoia.
Contrast this with the Android approach, where all you need to install a development copy of an application is a device and a USB cable (and a custom USB driver, if you are developing on Windows). There is simply no contest here, Android’s approach to application deployment/provisioning is vastly superior to Apple’s from the developer’s point of view. That is, unless you happen to like jumping through a series of hoops for no good reason; in which case Apple has you covered.
So which is better; iPhone SDK or Android SDK? Neither, really. While the iPhone SDK is absolutely more polished than the Android SDK, both provide usable tools that make building an iPhone or Android application a relatively straightforward process. What the Android SDK lacks in polish it tends to make up for in flexibility, accessibility/developer-friendliness, and a greater availability of open-source third-party libraries, tools, and plugins. So pick your preference, and start coding!