How to code sharing between Android and iOS
I'm moving away from strict Android development and wanting to create iPhone applications. My understanding is that I can code the backend of iOS applications in C/C++ and also that I can use the NDK to include C/C++ code in Android apps. My question however is how? I've googled quite a bit and I can't find any clear and concise answers. When looking at sample code for the NDK, it seems that all the function names etc. are Android (or at least Java) specific and so I would not be able to use this C/C++ backend to develop an iPhone frontend? I'd appreciate some clarification on this issue and if at all available some code to help me out? (even just a simple Hello World that reads a string from a C/C++ file and displays it in an iOS and Android app).
Thanks guys Chris
Note that I almost exclusively work on "business/utility/productivity" applications; things that rely heavily on fairly standard UI elements and expect to integrate well with their platform. This answer reflects that. See Mitch Lindgren's comment to Shaggy Frog's answer for good comments for game developers, who have a completely different situation.
I believe @Shaggy Frog is incorrect here. If you have effective, tested code in C++, there is no reason not to share it between Android and iPhone, and I've worked on projects that do just that and it can be very successful. There are dangers that should be avoided, however.
Most critically, be careful of "lowest common denominator." Self-contained, algorithmic code, shares very well. Complex frameworks that manage threads, talk on the network, or otherwise interact with the OS are more challenging to do in a way that doesn't force you to break the paradigms of the platform and shoot for the LCD that works equally badly on all platforms. In particular, I recommend writing your networking code using the platform's frameworks. This often requires a "sandwich" approach where the top layer is platform-specific and the very bottom layer is platform-specific, and the middle is portable. This is a very good thing if designed carefully.
Thread management and timers should also be done using the platform's frameworks. In particular, Java uses threads heavily, while iOS typically relies on its runloop to avoid threads. When iOS does use threads, GCD is strongly preferred. Again, the solution here is to isolate the truly portable algorithms, and let platform-specific code manage how it gets called.
If you have a complex, existing framework that is heavily threaded and has a lot of network or UI code spread throughout it, then sharing it may be difficult, but my recommendation still would be to look for ways to refactor it rather than rewrite it.
As an iOS and Mac developer who works extensively with cross-platform code shared on Linux, Windows and Android, I can say that Android is by far the most annoying of the platforms to share with (Windows used to hold this distinction, but Android blew it away). Android has had the most cases where it is not wise to share code. But there are still many opportunities for code reuse and they should be pursued.
While the sentiment is sound (you are following the policy of Don't Repeat Yourself), it's only pragmatic if what you can share that code in an efficient manner. In this case, it's not really possible to have a "write once" approach to cross-platform development where the code for two platforms needs to be written in different languages (C/C++/Obj-C on iPhone, Java for Android).
You'll be better off writing two different codebases in this case (in two different languages). Word of advice: don't write your Java code like it's C++, or your C++ code like it's Java. I worked at a company a number of years ago who had a product they "ported" from Java to C++, and they didn't write the C++ code like it was C++, and it caused all sorts of problems, not to mention being hard to read.
Writing a shared code base is really practical in this situation. There is some overhead to setting up and keeping it organized, but the major benefits are these 1) reduce the amount of code by sharing common functionality 2) Sharing bug fixes to the common code base. I'm currently aware of two routes that I'm considering for a project - use the native c/c++ (gains in speed at the expense of losing garbage collection and setting targets per processor) or use monodroid/monotouch which provide c# bindings for each os's platform functionality (I'm uncertain of how mature this is.)
If I was writing a game using 3d I'd definitely use approach #1.
I posted this same answer to a similar question but I think it's relevant so...
I use BatteryTech for my platform-abstraction stuff and my project structure looks like this:
On my PC:
gamename
- contains just the common codegamename-android
- holds mostly BatteryTech's android-specific code and Android config, builders point to gamename project for common codegamename-win32
- Just for building out to Windows, uses code from gamename project
On my Mac:
gamename
- contains just the common codegamename-ios
- The iPhone/iPad build, imports common codegamename-osx
- The OSX native build. imports common code.
And I use SVN to share between my PC and Mac. My only real problems are when I add classes to the common codebase in Windows and then update on the mac to pull them down from SVN. XCode doesn't have a way to automatically add them to the project without scripts, so I have to pull them in manually each time, which is a pain but isn't the end of the world.
All of this stuff comes with BatteryTech so it's easy to figure out once you get it.