Shared cross platform development is a concept that resonates very positively with all of us as programmers. It’s a nice outworking of the DRY principle, and seems like it would free engineers up to accomplish more. So why is it so rare that we do it?
I recently asked myself that question while planning a personal mobile project, and here’s what I came up with:
Why Not Cross Platform?
- Often the project only needs to support one or two platforms, and the others don’t really justify serious effort.
Why bother to dual-support (for example) iOS and Windows Phone, if 95% of the profits would come from iOS? If only Mac users would be interested in your shiny gizmo app, why drag it kicking and screaming into the Windows world? If your app lives by its own rules, it probably won’t have much of a life outside the permissive Android ecosystem. So these are fair considerations for the publisher/developer to think about. Budget is limited, and supporting other platforms “just because” is not a good enough reason.
- Cross platform dev frameworks are often awkwardly limiting and buggy.
And sometimes they are downright ugly, because non-native. I’m trying to think of something else insulting to add about the frameworks’ mothers, but nothing comes to mind.
For the above reasons, developers will often create several basically separate code bases in Objective C, Java, C#, and/or C++.
X is for… (Finally an Alternative to Xylophone!)
For the last several years I’ve had my eye on Xamarin and its push to bring the C# language and the Mono .NET replacement onto modern mobile platforms. My personal project seemed like a good opportunity to give it a try, so I downloaded Xamarin.iOS and Xamarin.Android, dragged my shared code files into some new project containers, and started working through the compile errors.
But importantly, this means that full cross platform GUI development remains an elusive goal for ordinary apps. Xamarin lets you use a single language and use shared business logic libraries cross platform, but still requires that you interact with the native API to develop a custom GUI or front end for each platform.
If you really, really like programming in C# (as I kinda do) then Xamarin is an interesting choice to evaluate. But if you hoped that it would mitigate the need to learn each native mobile platform API, then I think I’ve explained why that’s a misunderstanding. If you aren’t familiar with developing in Objective C for iOS, then you’re probably not ready yet to do anything deep with Xamarin.iOS — and similarly with Java and Android. You really can’t avoid the need for specific platform knowledge in each case.
If you were hoping to be delighted by groundbreaking news at this juncture, I’ll just say "sorry".
XNA and Xamarin’s Nifty Alternative
Getting back on a positive note, there is one genre of app that is an exception to the above rule, and which has consistently experienced really good success with cross platform GUIs. And that is games and other highly graphical apps. These apps already avoid using the native GUI controls of each platform in favor of their own image based buttons, sprites and effects. They are also typically written in C++. Now, I use C++ for mobile development when I have to, for example to implement low latency audio apps on iOS. But I really dislike C++. So moving right along…
For my personal project, I decided to try out Xamarin in combination with MonoGame, an open source C# reimplementation of Microsoft’s XNA game framework. My goal was to create a game engine that I can then use to write a variety of 2D games and other graphics heavy apps.
And just for the heck of it, I went against my own professional advice I am always giving clients about 1.0 efforts, and set an ambitious initial goal for my cross platform experiment. I wanted my game engine to run on all the major platforms from a single source code base, supporting:
- Google Android (via MonoGame and Xamarin.Android)
- Apple iOS (via MonoGame and Xamarin.iOS)
- Apple OS X (via MonoGame and Xamarin.Mac)
- Windows desktop (via Microsoft XNA and .NET)
- Windows 8 “Metro”/RT (via a slightly messy mix of Monogame/XNA and WinRT)
- Windows Phone 8 (via Monogame/XNA and .NET)
- Amazon Kindle (really a simple variant of Android)
So far it’s worked out well. I’ve tested my game engine’s runtime successfully on all the above except for OS X (just haven’t gotten around to that one yet, and hey, it probably works).
But Is it Fast Enough?
When you talk about highly graphical multimedia app or game development, performance questions quickly become paramount. How does C#, a managed language with garbage collection, measure up for this task?
In my experience from developing my game engine, the primary setback is simply the overhead of loading the extra Mono libraries on top of the native system. After you pass that hurdle, you can mitigate the effect of garbage collection by manually managing your own object pools, and defining all your most heavily churning objects and data as structs (value semantics) versus classes (reference semantics). Garbage collection is no longer a benefit but a liability; however the closely related side effect that you’re compiling managed code remains a benefit in terms of additional safety checks. (There are actually multiple important constraints to my C# programming style I had to make to optimize memory management; but the nitty gritty will have to wait for a future post.)
In particular on iOS, Xamarin has done a remarkable job of inserting their product as far as possible into the operating system as a first class citizen. They’ve been fighting Apple for years to let them publish to the platform at all, and along the way they followed what I consider a more difficult, but ultimately rewarding path than they have for other platforms. Xamarin actually compiles your C# code natively to ARM under Apple’s iOS development framework and doesn’t rely on any runtime JIT code generation. And of course they couldn’t rely on JIT-ing even if they wanted to, as Apple still disallows dynamically emitting native code. On a side note, this does put a damper on a developer’s ability to supply app updates without pushing new binaries through the approval process of the official App Store. I got around that in my game engine, as others have, by creating my own scripting language, which I compile to a pseudo code format and run with my own interpreter.
A Good Fit
Obviously Xamarin is hoping that the industry at large will embrace their vision of writing most everything in C# on all the major platforms. As I’ve discussed above, it’s not a magical way to get around the need for platform API knowledge, so the jury is still out on how much market share they will capture, in terms of toolsets used for general mobile development.
For my needs (multimedia intensive OpenGL/DirectX based apps) it is a perfect fit that allows me to use my favorite language in a radically cross platform project.