1. Xamarin Forms
Don't listen to the detractors. When our team started I heeded the rumors that Xamarin Forms isn't ready for anything more than settings pages. Mindful of the advice, we started with mostly MvvmCross and Interface Builder story boards.
But the more Xamarin Forms pages we built, the more we loved it. We eventually went back and replaced every single platform specific UI page with a cross-platform Xamarin Forms version that rendered fully native controls. The two-way databinding, native support for the MVVM design pattern, and easy to understand (for me) XAML were just icing on the cake.
It wasn't perfect. We occasionally ran into hiccups with controls that failed to offer the UI customization we wanted. But once we mastered Custom Renderers we were able to accomplish pretty much anything UI-wise. Animations, completely custom pages, and dynamic rendered controls, all quite doable once you're up to speed.
With Xamarin Forms we got a fully native look and feel for our app while achieving 76.3% code reuse (most of which was the important stuff), plus an easy out if the abstraction failed us. Fantastic.
2. Code Sharing
Not what you're thinking. Sharing code between iOS and Android is (relatively) obvious. We used Portable Class Libraries to share code between our iOS and Android and our server-side web application.
For one thing, sharing our models was huge. This made strongly typed json serialization/deserialization a breeze. But it got even better with the "free unit tests" our compiler gave us. Rename a field on mobile? Zing: immediate compilation error server-side. Nice.
Once we got in the swing of things we started sharing enums between Entity Framework ORM and database on the server-side, the cross platform models, our SQLite database, and our mobile code. Then we started sharing utility methods, validation, and even miscellaneous code like cryptography. Yes, the crazy-smart folks at Xamarin even ported the .Net framework's cryptography libraries to iOS and Android, thus allowing the exact same logic for encryption/decryption everywhere, How cool is that?!
While we used TypeScript for the web front-end, I suppose one could extend code sharing absolutely everywhere by using Script Sharp. That would be pretty insane.
var animation1 = AnimateLayout(CategoryAttributes); var animation2 = AnimateLayout(TemplateAttributes); await Task.WhenAll(animation1, animation2); // ui thread is free. FREE! FREE!!!! DoStuffAfterAnimations(); // <- *UI thread* picks back up here, after all of ^ & when it finishes other UIish stuff!
"await Task.WhenAll()"? Be still my beating heart.
Somewhat related is using Visual Studio plus ReSharper to build iOS and Android apps. My only hesitation is it took about 10 seconds from the time I hit F5 on the PC to the time I was debugging (with breakpoints and stuff, mind you) on Mac Emulator or an iOS device. The pro's of this great IDE setup outweighed those cons for me personally, but many undoubtedly will prefer Xamarin Studio (or obviously a Cordova/PhoneGap based solution with its super-fast dev feedback cycles).
4. Native Library Interop
Interop wasn't exactly easy with Xamarin, but it was doable, and for a cross platform solution that's a differentiator. As I'll describe it's also essential to know that it's possible so that if (when) part of the Xamarin abstraction fails you you can stop cursing the framework and carry on with your life.
The main reason we needed interop initially was our requirement for an expensive physical RFID reader hardware device thingy (that's a technical term) that came with its own proprietary Bluetooth based protocol and set of libraries. If it were a C library we could use normal P/Invoke semantics to call in. However, since it was an Objective-C API, we needed an iOS Binding Project.
Basically we defined a bunch of C# Interfaces with Attributes that told Xamarin how to map to the Objective C API's. At compile time Xamarin code generated an implementation to call the API's. While Xamarin's Objective Sharpie saved some time by building out some of the many interfaces we needed, it was still a pretty manual process. Basically Objective-C Protocols map poorly to C# Interfaces and some fiddling is involved.
Only once did we need interop because of a Xamarin failing. We needed a dynamic tone generator and despite having audio playback capability (even MIDI libraries) we couldn't get to the lowest level audio API's we needed (you know, the ones when you need to access sine and cosine and stuff).
Fortunately, interop can solve any problem if you're desperate enough. The good news is we only needed it once, and for a pretty obscure case. Otherwise Xamarin's mapping of the .Net Framework worked perfectly and gave us everything we needed.
5. Minimize Hardware Costs
Warning: my last reason for choosing Xamarin again in a heartbeat likely won't most readers.
My team mostly has PC's (nice, fast, expensive ones, but PC's nonetheless). Mac's are expensive. Building iOS apps requires a Mac. Handing out an extra Mac, even an Air, to all developers on our team for a six month project is a silly expense.
The latest Xamarin Build Host will allow multiple PC's to pair with it. One iMac purchase later and we're good to go. Well, in theory. Technically that version hadn't come out when we started, so we actually gave lots of money to Apple. But it sounds like a super awesome feature to thwart Apple from receiving lots of money (..oh wait).
A good platform is one that boosts your productivity, allows you to share more and write less code, has great documentation and community support, and gives allowances for its own potential failings. Xamarin has all of this and more.
I'm really looking forward to the opportunity to use it again. Give it a try, I bet you will too.