If you want mobile apps for both Android and iOS, the cross-platform framework approach sounds pretty great, promising that you only have to develop the app once to run on multiple target platforms. Developing two separate apps sounds as if it will require fully twice as much work.
But in my experience, the time required is actually somewhat less. And developing two separate apps can have some advantages as well, mostly in the area of being able to fine-tune platform-specific features.
My current project involves an iOS app and an Android app, both written natively for their respective platforms. Our typical workflow involves spending a couple of weeks developing a new feature on iOS, then porting that feature to Android.
The second step of porting to Android often takes 20-50% less time than the initial iOS development. This is simply because most of the higher-level design and user experience questions have been worked out through our iterative development process. (This doesn’t include lower-level, platform-specific implementation issues, which can still be a pain.)
Here are a few guidelines we try to follow to keep both apps in sync.
1. Keep the Code Structure as Similar as Possible
Maintaining two separate code bases doesn’t have to mean doubling the number of classes that you need to keep track of. If you can structure things identically in both places, you’ll have a much easier time navigating, no matter which codebase you happen to be working in at any given moment.
On our project, that meant going as far as having View Controller classes in the Android project (the Android SDK doesn’t have View Controllers per se, but the closest analog is Fragments). But since we’re using the MVVM pattern (Model-view-viewmodel), most of the logic is in the view model anyway.
Refactoring two separate apps can be a little tedious, since the same changes need to be made twice. And since refactoring tends to be somewhat more straightforward than initial development, we don’t usually see a great time savings when porting to Android. At the same time, because it’s a very mechanical process, it’s pretty easy to predict how long it will take.
2. Use Nearly Identical Test Cases
While implementing features can vary somewhat due to differences between platforms, test cases tend to be nearly identical–so much so that it is possible to translate the most repetitive parts of tests using a script full of regular expressions.
For our project, I wrote a quick script to parse a test case class in Objective-C and generate a test case class in Java. The parts that can’t be translated are commented out in the output, to be translated by a human. I haven’t included the script here because it’s very specific to our project and the test frameworks we’re using, but I’m sure you get the idea.
3. Distribute Knowledge among All Team Members
It can be tempting to split up the work cleanly along platform boundaries (that is, have a couple of people work on iOS and a couple of people work on Android). But this makes it pretty difficult to maintain the identical structure previously discussed. In order to keep the codebases from diverging too much, it’s best to have everyone work on one platform for a while, or at least rotate the team often.
Conclusion
Cross-platform frameworks have come a long way in the past few years, and I would seriously consider using one if targeting multiple platforms. But unfortunately, starting over from scratch with existing apps is rarely a viable option. I’d be interested to know what other tips or habits you have for maintaining separate, yet identical, apps.