[Note: If you are using some cross-platform development environment like react-native or Xamarin or building a Web/Hybrid app you are "lucky" and this post doesn't apply to you :)]
Unless you are working in a very simple app at some point you will realize that there are some parts of the application that you are implementing twice because you need it in both platforms (for example some business logic or the code to make requests to the HTTP server APIs).
Based on the capabilities of Android and iOS you have basically two options:
Option 1: Implement everything twice using the official language and libraries of each platform (f.e. implement the access to HTTP APIs using Swift and URLSession in the iOS app and using Java and Volley in the Android app)
Option 2: Implement the reusable code in C++ and compile it in the iOS app (creating a Objective C++ wrapper) and use it in the Android app (creating a JNI wrapper).
These are some possible advantages of Option 1:
- Code is usually easier to read and maintain when written in modern languages (for example Swift vs C++).
- Native integration: When using an Android library to make HTTP requests it will be probably integrated with the system proxy configuration and validates the SSL certificates with the system CAs by default.
- No plumbing/boring code to write to provide access to the C++ library from the application (for example with JNI). This can be partially mitigated using frameworks like SWIG to autogenerate the wrappers but it is still boring and usually problematic.
- Simpler to debug because there is a single layer instead of having to make calls accross layers with different technologies(for example with JNI).
- Build process faster and simpler because of less libraries/tools (for example no ndk required)
- No duplicated code to develop and maintain.
- Avoid inconsistencies in naming, algorithms, protocols implementation because it is implemented in a single place.
- Performance can be better. Almost this is not an issue in most of the cases.
I put some of those libraries in a diagram across two axis: Y for size/complexity of the library and X for number of platforms to support. Other relevant variable could be how relevant is the performance optimisation but I don't want to make a 3D diagram :)
In blue libraries using Option 1 and In green libraries using Option 2 |
As we can see most of the popular libraries are using Option 1 reimplementing the library twice, once for Android and once for iOS. On the other side some big libraries related to real time communications or databases are using Option 2 implementing the core in C++ and exposing it with wrappers to Java and Objective-C applications.
Conclusion
What is the right solution probably depends on the type of project and the team building it but in my opinion in many (or most) of the cases it is less effort to develop and maintain 2 simple implementations than writing and maintaining a single more complex implementation plus the wrappers to different platforms. In addition you can (should) mitigate the issues of Option 1 making use of tools to autogenerate code when possible, for example using protocol buffers/grpc for the client-server communication or swagger to generate clients for REST APIs.I'm very interested on knowing your opinion on this topic, What do you think? What are you doing right now in your projects?