There are only two viable options left. You can write your common shared development tiers using C or C++ (yawn), or you can use Xamarin while taking advantage of the modern language features of C#, including LINQ, async, and Garbage Collection. Since it’s not 1981, we’re going to use Xamarin. It’s an excellent choice for leveraging platform-agnostic code while allowing each OS to implement their own interfaces. The following recommendations are based on a mission critical, enterprise level application that will be used by hundreds of thousands of consumers. What follows are lessons and considerations that might benefit others.
1) Portable Class Libraries Aren’t Worth It
Portable Class Libraries (or PCL) is one way to write multi-platform code in a single class library that is consumed by different platform executables. Each platform you include narrows down the available API in the .NET BCL. The other option to sharing code is file-linking. PCL is neat, tidy, and requires no overhead when your common code library changes. File-linking is a manual process and can begin to get cumbersome after constant project changes. The main problem with PCL is that it’s very much in a beta stage. A new build of Mono could come out tomorrow and PCL support might go away. The volatile nature and its general unpredictability make it a good choice only for non-critical, hobby apps.
2) MVVMCross Is A Tempting Siren
We really wanted to take advantage of all the benefits that are provided by MVVMCross, such as bindings, converters, IoC, etc. We spent several days digging through the documentation and samples but ultimately decided it was simply overkill for this specific project, which is a mission-critical, enterprise-level application nearly all read-only data/views. While MVVMCross is quite impressive, it’s not officially supported by Xamarin and your level of support is limited to the fine folks in the forums. We decided to go with a light-weight MVVM implementation along with a simple IoC framework. We will certainly consider MVVMCross for other projects where the risk is not as great.
3) Crash Reporting Support
Crash reporting on mobile devices is a fickle beast. Luckily, services like TestFlight, HockeyApp and Crashlytics exist to make things a tad bit easier. Right before an application crashes, a crash log is written to disk. When the app starts up again, it sends that crash log to the crash server where the stack trace is symbolicated against debug symbols. A few minutes later you’ll get a delicious email with scrumptious line numbers of where the exception took place. But because Xamarin binds to the underlying iOS API, the symbolicated crash logs are pretty useless. Currently, you’ll see a log of mono-adapter code instead of C#. To combat this, use a service like HockeyApp and piggyback your own call stack as metadata. Right before HockeyApp sends up the crash report, it gives the app a chance to add any additional descriptive information to the report. This is your chance to add something useful to the report. In our case, we log the C# callstack of the unhandled exception to disk and send that up with the report. We don’t get line numbers (since it’s a release build) but we do get class and method names. Yay.
One of the areas that gets the least amount of consideration or foresight is bindings – which is needed for 3rd party libraries or existing open source code/libraries. Every time you have to hit up Stack Overflow to determine the best way to compress a frame from a video in AVFoundation, you’re probably going to have to spend time converting this code to C# just to see if it works. You might have to go through 5 or 6 different prospective solutions before you find the one that works – this can be a lot of effort when you’re used to just copying, pasting and slightly modifying code. If you’re going to use a 3rd party, compiled binary, you will need to bind it. Binding can be straightforward or really complicated depending on the API being bound. It’s not that it can’t be done, but it’s something that should be considered beforehand.
5) To Nib Or Not To Nib
Another decision to make early on with a multi-developer team is whether you want to stick with the traditional .xib files when creating the views and view controllers in iOS. After a couple days of using .xib files, we reversed course and decided all UI would be hand coded. This turned out to be a really wise move because…
- MERGING – It’s already difficult to merge .xib files when committing source code. This is exponentially magnified when using storyboards. The fact is that .xib and .storyboard files do not lend themselves to multi-developer projects.
- CONSTRAINTS – Adding constraints using the Visual Format in code is easier than trying use the constraint controls in Xcode.
- LESS FILES – Getting rid of the .xib files cut our UI files and maintenance in a 3rd because you get to scrap the designer file as well.
By leveraging a flexible design platform as well as Xamarin technology we were able to utilize one core design format and simply swap colors and brand assets to create a new custom branded app for each member of our client’s family of parks. For more information on Cross-Platform Mobile Development, please reach out to us by clicking here.