Hello app developers of HN!<p>My team owns an Android (Kotlin) and iOS (Swift) app. The app is responsible for processing data, submitting to ML models, and then displaying results in a UI. We chose to do a lot of that processing in a shared Rust component. What we have found is a high overhead of bridging Kotlin/Swift to Rust. Some core logic has also seeped into our bridging code resulting in some duplication (exactly what we were trying to avoid).<p>With that, those of you who have found yourselves in similar situations, which language would you choose to be shared between your Android and iOS app (if any)?
Since no one else has said it, I'll be the voice of reason.<p>Share your design specs only, and let each platform team write the implementation in the language that they think best.<p>Yes, you'll have two teams spending time on doing the same thing. However, you'll get important benefits.<p>Each team will be able to implement appropriately for their platform. While iPhones and Android phones are rather similar in terms of capability, the interaction models have a lot of differences, and forcing a common component often results in non-native feeling apps. Users will be at best confused, and at worst insulted by this.<p>Additionally, when you have two teams working on similar problems, they can help each other. Training on this interaction with things known to be pretty much the same helps people realize they can do it with things that aren't obvious. Meeting on a regular basis to discuss things that worked/didn't on the various platforms will help them all.
C++.<p>It is part of both SDKs, you have direct support for mixed mode debugging on the IDEs.<p>No need of extra tooling.<p>On Android JNI is always going to be a pain, but at least with C++ Studio gives you an hand on accessing JNI APIs.
I have great success using Kotlin Multiplatform to share code between iOS and Android. Have a look at my Android Jetpack Compose and iOS SwiftUI project sharing the common logic for a game <a href="https://github.com/SimonSchubert/Braincup" rel="nofollow">https://github.com/SimonSchubert/Braincup</a>
Just use JavaScript.<p>Javascriptcore is a lightweight way to execute JavaScript on iOS and you can use V8 context or duktape on Android. This way you can also update code in your app without an app store update.
I'm surprised no one has pointed out the value of Ionic Framework (<a href="https://www.ionicframework.com" rel="nofollow">https://www.ionicframework.com</a>). I'm a huge, huge proponent of this. TypeScript is a great language (in my opinion), UI code-sharing is inherent, and Capacitor (<a href="https://capacitor.ionicframework.com/" rel="nofollow">https://capacitor.ionicframework.com/</a>) is great for all the native work you need to do. Worth noting you can do this in Angular, React, Vue, or pure JS.<p>This won't suit your needs for processing-heavy apps (though can WebWorkers help), but will work well for many apps (<a href="https://csform.com/top-10-apps-built-with-ionic-framework/" rel="nofollow">https://csform.com/top-10-apps-built-with-ionic-framework/</a> for a "top 10" list for examples).<p>I noticed after submitting that you mentioned machine-learning. Any reason you can't offload that to a web API and take the load off the client?
So I'm sure lots of people will think that this definitely doesn't qualify as "Best language to share code...", but Haskell has stuff for getting web, desktop, iOS, and Android out of one code base. It's called Obelisk (<a href="https://github.com/obsidiansystems/obelisk" rel="nofollow">https://github.com/obsidiansystems/obelisk</a>) and it's actually getting to be a pretty good development experience.
Good thread previously here on HN about code sharing between iOS and Android:
<a href="https://news.ycombinator.com/item?id=20695806" rel="nofollow">https://news.ycombinator.com/item?id=20695806</a>
We're using kotlin native, after considering rust for a bit. It's been working great, we've had it in production for about six months.<p>Main advantages are<p>* kotlin is a nice language with good type support<p>* has good swift bindings out of the box<p>* also compiles to js and cpp so we can use it in our Web product as well
We use JavaScript for sharing code between devices(iOS & Android), browser as well as the server. Surprisingly, we haven't faced any of the problems, that Dropbox claims to have faced (<a href="https://blogs.dropbox.com/tech/2019/08/the-not-so-hidden-cost-of-sharing-code-between-ios-and-android/" rel="nofollow">https://blogs.dropbox.com/tech/2019/08/the-not-so-hidden-cos...</a>).<p>Pros:<p>1. Sharing native APIs with JS runtime and vice versa, was well supported & trivial to implement.<p>2. Easy to find skill-set.<p>3. We can run the same code in browsers as well.<p>Cons:<p>1. The app will be slightly heavier in Android (as V8 has to be bundled with the app. iOS allows using native JsCore runtime.)<p>2. The shared code runs slower (Obvious, because dynamic language).
I did one cross iOS/Android platform project using Kotlin/Native with its MPP plugin with reasonable success. However, this was 6 months ago and the JetBrains people surely haven‘t stopped moving forward.
FullStory is using Rust for our shared code, however the other sides are different: Java & Objective-C. It seems to be working pretty well for us so far.<p>Our requirements are probably a bit different than yours, though, because we're shipping a tool for app developers rather than the app itself. In particular, Objective-C was chosen over Swift because we didn't want to risk potential conflicts if our customers were using a different version of Swift and/or have to bundle a Swift runtime for older iOS versions.
I'm not completely sure about your requirement, but as a game developer who uses Unity everyday, I would recommend it. Core graphics and UI components are available out of the box, and sometimes even when we need an app(nothing like a game) that need to access native APIs of the platform, we use Unity. It used C# as the default language, and platform-specific core logic can be separated within the code, using #directives so it's pretty straightforward.[edit: typo]
ActionScript 3.0<p>with the Adobe AIR runtime you will be able to publish to iOS, Android, Windows and macOS, see "Adobe AIR" [0]<p>ActionScript is something similar to TypeScript<p>you will have access to the whole Flash stack and more, see "Building Adobe AIR Applications" [1]<p>with ActionScript Native Extension (ANE) you will be able to add your native code with an easy to use AS3 interface, see "Extending Adobe AIR" [2] and "Using native extensions for Adobe AIR" [3]<p>Note, the latest Adobe AIR SDK are now maintained by Harman [4]<p>[0] <a href="https://www.adobe.com/products/air.html" rel="nofollow">https://www.adobe.com/products/air.html</a><p>[1] <a href="https://help.adobe.com/en_US/air/build/index.html" rel="nofollow">https://help.adobe.com/en_US/air/build/index.html</a><p>[2] <a href="https://www.adobe.com/devnet/air/articles/extending-air.html" rel="nofollow">https://www.adobe.com/devnet/air/articles/extending-air.html</a><p>[3] <a href="https://help.adobe.com/en_US/air/build/WS597e5dadb9cc1e0253f7d2fc1311b491071-8000.html" rel="nofollow">https://help.adobe.com/en_US/air/build/WS597e5dadb9cc1e0253f...</a><p>[4] <a href="https://airsdk.harman.com/" rel="nofollow">https://airsdk.harman.com/</a>
One way would be to host a script engine and run the script language, e.g. JavaScript. Another would be to create your own grammar and simultaneously translate to Kotlin and Swift. You could even use a strict subset of either Kotlin or Swift then you'd only have to deal with one translator.
C++ is first-class in Android via NDK. You can write directly to your app's memory from a C++ library without having go through FFI. I'm pretty sure it's the same for iOS but through a C ABI.
In Go, there is an official, experimental project called gomobile [0] that allows one to generate a Java or Objective C binding to be used in mobile projects based on Go source code.<p>It comes with some restrictions and is still deemed experimental. But it could be a viable choice in the days to come.<p>[0] <a href="https://github.com/golang/mobile" rel="nofollow">https://github.com/golang/mobile</a>
You should share design specs between client teams and allow each of them to implement them within the parameters of what's expected on each platform. Don't force them to have the <i>exact</i> same UI at the cost of platform-specific idioms. It hurts customers on both platforms to take that approach.<p>Your business logic should be, to the maximum extent, implemented once on the server. Your client implementations should simply display what the server has computed, once. Caching it is fine, rendering it locally is fine for the most part, and you get a clean, well-fitted, elegant UI for it.<p>Any limited amounts of business logic that must be correct and truthful should be implemented as a Rust (or if you insist, a limited, well-defined subset of C++) library with C linkages and idiomatic wrappers for iOS and Android. If this can be shared with the server and/or web front-end (via emscripten for instance), it should be. It's usually painful to do this, but there's usually only a small part of your codebase that should fall under this section.
If you really want to optimize and share code across platforms, you should really go for C++.<p>Make your core logic in C++ and write bridges for Kotlin and Swift, where only the UI logic is involved.
C++ has the better ecosystem so far and the very modern standard (C++17) let you write robust code. There are also so many tools that help you catch errors and typos, plus thousands of libraries available.
I'm not an expert but you could consider sharing Swift (or Kotlin) code between platforms. Nim (<a href="https://nim-lang.org" rel="nofollow">https://nim-lang.org</a>) could also be explored.
Something just crossed my mind while reading the question, that Swift could be a good candidate. Turns out there are compatibility layers that are based on Swift:<p><a href="https://www.scade.io" rel="nofollow">https://www.scade.io</a><p><a href="https://academy.realm.io/posts/swift-on-android/" rel="nofollow">https://academy.realm.io/posts/swift-on-android/</a><p><a href="https://blog.readdle.com/why-we-use-swift-for-android-db449feeacaf" rel="nofollow">https://blog.readdle.com/why-we-use-swift-for-android-db449f...</a>
I have a similar use case where the crux of my business is really data / analytics centric. The user experience is pretty much limited to <i>mostly</i> information consumption with a few click events (favorites, like, dislike, delete and the occasional standard input forms).<p>I'm leaning towards using [Meteor](<a href="https://www.meteor.com/" rel="nofollow">https://www.meteor.com/</a>) to share code between mobile apps and web apps.<p>Using cordova shells is pretty neat for business applications. Would be interested in thoughts.
Here's a Mozilla blog post about rewriting Firefox's Sync client code in Rust so the same code can be used on desktop, Android, and iOS. The FFI between the shared Rust code and C++, Java, and Swift app front ends is a little hairy but well encapsulated, generated code.<p><a href="https://hacks.mozilla.org/2019/04/crossing-the-rust-ffi-frontier-with-protocol-buffers/" rel="nofollow">https://hacks.mozilla.org/2019/04/crossing-the-rust-ffi-fron...</a>
I'm looking at solving a similar problem but for desktop.<p>I would like to avoid C++ and so far the best candidate seems to be Nim. It transpiles to C which then can run in pretty much any platform.
I do a lot of consulting for clients who use Embarcadero's Delphi to create native iOS and Android apps from a single source base.
Delphi is a commercial product, that comes with its price tag and there is, of course, a learning curve, but once you know the processes you can create great multi-platform mobile apps, with way less effort than having one team on Xcode and the other on Android Studio.
RAD Studio let's you build cross platform apps targeting Android, iOS, macOS, Windows, Linux, and HTML5 with a single codebase and single UI. Choose either Object Pascal or C++.<p>I prefer the Object Pascal side but the C++ side is also powerful because it solves some of the problems that the Dropbox team talked about in their "The (not so) hidden cost of sharing code between iOS and Android" article.
I use c++ rather than rust because as much as I would love to use the best language its just not so well supported on mobile compared to c/c++. I'm not sure how well flutter ffi does using rust compared to more mainstream approaches its possible that flutter ffi is more friendly to rust than jni/kotlin.
Kotlin can generate both JVM bytecode and iOS binaries. I've successfully shared code between iOS and Android projects using Kotlin before. The overhead is quite low, and, all in all, I was quite satisfied with the results.<p>However, a lot of the tooling around this is experimental, so you might want to tread carefully here.
Surprised no one has mentioned NativeScript yet. I've used it, admittedly only for investigation purposes, but was super impressed.<p><a href="https://www.nativescript.org/" rel="nofollow">https://www.nativescript.org/</a>
I have 22 years of shipping products on time with Delphi. The latest versions do a wonderful job compiling to android, iOS, macapp or Windows.<p>Delphi is not cheap, but in my case the time to market, and tight release dates make it worth.<p>www.embarcadero.com/products
Have you seen this answer on Stack Overflow?
<a href="https://stackoverflow.com/a/5234868" rel="nofollow">https://stackoverflow.com/a/5234868</a>
Xamarin (C#) and Cordova (JavaScript) are the usual suspects for such multiplatform endeavours. You should not use three languages in production if one is enough.