Maintaining your business presence or mobile apps on different platforms is challenging. A lot of companies hire platform specific developers, form one team for each platform which work in their own silos, each responsible to maintain their respective platform, having different implementation, different code paths and different kind of design. Each team may or may not have face similar functional/UI issues.
At Nintex, we build and ship native mobile apps across iOS, Android and Windows platforms to support access to workflows and forms securely from wherever you are on your mobile devices. Here we have followed a slightly different approach where we design and implement any feature once and then we port the implementation to other platforms. Therefore we have feature based mobile developers which design and implement each feature across Android, iOS and Windows platform.
This has work really good for us, breaking the silos and help us achieve design and code path consistency across multiple platforms.
This often lead us concluding that if we have functional bug in one platform, chances are we have that bug in other platforms as well.
The crux of the idea is that we follow Model-View-ViewModel (MVVM) pattern across all platforms. So we have similar classes for model, view and view-model, contracts, repositories, helpers etc. across Windows, iOS and Android. By similar classes I mean, similar name, code path and structure yet they are written in their own platform specific languages. So if we have a view model with a method on one platform, we will have it across all.
As an example, consider following sample snippet of a view model from Android and iOS and you will see the point here.
However view, which comprises of UI and code, can be platform specific. e.g.
In Android, View = XML Layout + Activity
In iOS, View = Storyboard + ViewController
In Windows, View = XAML + Code behind
Each view has reference to its view model (initialized through IoC or passed by its parent) where all user interactions are done through events or binding or listeners etc. depending on platform. For instance, in iOS we leverage KVO to observe value change in ViewModel to reflect update to View/UI and stuff like button click is simply routed back to ViewModel method either via simple method call or some mechanism. So our views are just there to render UI widgets/components/layout.
The advantage of this approach is, first, it gives us shared design and code consistency, second, it gives opportunity to open a cross platform conversation and knowledge across team, third, it improve code testability by decoupling UI logic from View (ViewControllers/Activity/CodeBehind) to ViewModel, fourth, it makes relatively easy for us to follow SOLID principles.
However, we have came across challenges with platform specific components like showing alerts/notification, http clients, retrieving geolocation etc. The way we handle it is by injecting contract (interface/protocol) to ViewModel class which has platform specific implementation however code structure remains same in ViewModel across all platforms.
If you are interested to see some sample yet naive MVVM implementation:
– MVVM implementation in Android
– MVVM implementation in Windows Store and Windows Phone
How do you develop cross platform native apps? It would be interesting to know… is it C++ shared/wrapped code? Do you use Xamarin? You prefer each platform specific team working in their own silos?
PS: This post is revised version of my original blog post at Nintex Labs