When creating mobile applications, developers have many tools at their disposal. Google, Apple, and Microsoft all have specific development environments for their mobile operating systems. But what happens when you want to develop an application that targets the big three all at the same time? (This is what some refer to as “Write once, run anywhere.”) There are several options available for developing applications in a common environment and deploying them across multiple platforms. What are these options and how do they compare? We take a look at some of the options below.
Native Tools
The major players in the mobile OS/device market each provides a toolset for developing applications for their platforms. Google provides Android Studio for building Android mobile applications in Java. Apple offers Xcode to build iOS applications using either Objective C or, more recently, Swift. Microsoft provides versions of Visual Studio to develop Windows Phone applications in C#.
There are many advantages to working with the native development tools for a given platform. One advantage with writing in a platform’s native language is that the full feature set of the API is available, since the developer is directly accessing the platform’s API. For anything from subtle customizations of a UI element to taking full advantage of multithreading, background processing, and GeoLocation services, going native offers straightforward access to more advanced functionality. Additionally, new features of the platform will first be available to the native tools, while other tools have to react to the release of new features by the likes of Google, Apple and Microsoft.
It can also be easier to achieve the look and feel customers expect from an application when using the platform’s development tools. Since the native UI elements are being used directly, the characteristic experience of a given platform can be easily achieved. Also, in many cases, the UI/UX performance is better with a native apps for similar reasons. There is no extra layer getting in the way.
One other advantage of the native route is the volume of collected knowledge that is available to help developers when they run into problems. The substantial number of developers using the native tools make it much more likely that there is already an answer out there for the inevitable “How do I do X” questions that arise.
There are, however, some drawbacks to using the native development environments on each platform. The platforms change at a rapid pace with major revisions of each mobile OS being announced annually and minor releases staggered in between. Because these platforms change so frequently, it makes it difficult for engineers to be experts in multiple OSs. Each platform has a different application lifecycle, a different programming language, and a different set of APIs for doing the same thing. To write a high quality app a developer needs a good understanding of how things are done on each platform. Code, especially UI code, is not really transferable across platforms. While it is possible to build shared libraries for some logic in a common language like C++, it is not just plug and play. For example, in Android, a C++ to Java layer needs to be written for an app to make use of a C/C++ library. Generally speaking, if a developer wants to build a native application for two platforms, it will be roughly twice the work of writing for one platform.
Cross-Platform Tools
Cross-platform tools allow a developer to use a common set of tools and a common development environment to write applications that can be built for multiple mobile operating systems. While there may be some platform-specific pathways in the code, generally much of the code is common across platforms.
There are three basic approaches taken in cross-platform development. The web-based cross-platform environment allows a developer to use HTML, CSS and Javascript to build an application, which then runs as a web app in a native web view on the platform. Phonegap may be the best known and most frequently used tool with this approach. Interpreted environments use an interpreter to execute a common language and interface with the native platform. Appcelerator/Titanium is a good example of this approach. Titanium apps are coded in Javascript and are bundled with an interpreter/executor into a native application. Finally, there is the natively compiled cross-platform tool which compiles code to a native executable which then interacts with the native runtime environment. Xamarin takes this approach using C# and Microsoft .NET as the environment.
The major advantage of all these approaches is that one codebase can produce applications that run on iOS, Android, Windows and other platforms. The more platforms being targeted, the bigger an advantage this becomes. All three of the tools listed above allow a developer to code both logic and UI in common code to be run on multiple platforms. The common UI is HTML/CSS/Javascript in the case of Phonegap. Titanium offers its’ Alloy UI which involves xml layout and javascript code. Xamarin offers the Xamarin Forms package for common cross-platform UI. Xamarin also offers C# wrappers around Android and iOS native UI elements if a developer wants to make common C# libraries for things like web apis but want to use native UI elements more directly.
The other advantage of these tools is that a developer can code in a language they are already familiar with. If you are a master of HTML and CSS, you can put together an iOS without learning objective C or Swift and the Xcode environment. Have a strong C# background? Xamarin lets you use these skills and write for Android without learning Java. This ability of a company to use existing resource and not have to hire a new set of skills can be very valuable.
Unfortunately, there are several drawbacks to these tools that are worth considering.
It can be difficult to achieve a native look and feel with the common UIs provided by these tools. Since Phonegap is web based, it doesn’t use native UI elements at all, and the look of the app reflects that. Titanium Alloy and Xamarin Forms end up rendering native UI elements, but since they are abstracted from the native objects, they lose some of the configurability and flexibility of the native UI elements. For example in Xamarin Forms, an “Entry” UI element renders an EditText on Android and a UITextField on iOS. Entry doesn’t expose an option for changing the “Hint” text color, though, so if the UI requires a specific color for the hint, platform-specific code needs to be written to achieve the desired effect. If the UI is complex enough, it becomes necessary to do a fair amount of platform-specific work which then defeats the purpose of using a cross-platform tool.
Another issue is that, in practice, it is difficult to completely avoid platform-specific coding. Want to access bluetooth, read device sensors, or even just launch a native email composition view? These actions are all handled differently on each platform and require platform-specific code. While there are sometimes “plugins” available to handle the task, oftentimes there are not. In the case of Phonegap, this means writing a plugin with Java code for Android and objective C/Swift for iOS. Titanium has a similar mechanism called modules, but still requires Java or objective C to do the platform-specific coding. In Xamarin, platform-specific code is all written in C#, but a developer still needs to understand the specifics of how each platform handles the task they wish to perform. It can also be difficult to handle lifecycle events in a common way, since there is a translation process between platform events and common UI events. Titanium for example has a “pause” and a “resume” event for when the application goes into the background and returns. These events do not fire when running on the Android platform, since there are no application-wide pause-and-resume lifecycle events in Android.
Finally, these cross-platform environments ultimately make use of parts of the native tools to actually build and publish apps. Since they are all dependent on some form on the native tools, they all add an addition layer of fragility to the development environment. Xamarin can have issue building Android apps, for example, if there is a mismatch with the installed Android SDK. Titanium Studio is very sensitive to the version of Java installed on the build machine when building Android apps. All three tools still have to deal with certificates and profiles, which are handled through Xcode, when building iOS apps for distribution. It can sometimes be a fragile, frustrating environment to work in.
Conclusions
Cross-platform tools can be a valuable alternative to native mobile development under the right circumstances. An application that is heavy on web content and light on user interface may be a good fit for a Phonegap app. An enterprise application with a functional, less flashy UI may be the right fit for Xamarin and Xamarin forms, especially if the company already has C# resources.
Cross-platform is not the utopia it is made out to be. The idea of “write once, run anywhere” rarely works in practice. There is just too much customization and platform-specific work needed to produce a quality app that adds time and cost. It may be possible to save 15% – 20% in development time/cost when targeting two platforms but almost never 50%.
Ultimately, it is generally just easier to write a high quality, polished iOS application in Xcode and an Android app in Android Studio than it is to try and force the app into the abstraction provided by the cross-platform tool.
Filed under: Product Engineering | Topics: app development, mobile apps