11 ms·
Ask HN: Best language to share code between an Android and iOS app?
Hello app developers of HN!
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).
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)?
- shams93 7y agoI 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.
- cerberusss 7y agoHave you seen this answer on Stack Overflow? https://stackoverflow.com/a/5234868 https://stackoverflow.com/a/5234868
- karmakaze 7y agoOne 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.
- stockkid 7y agoIn 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. It comes with some restrictions and is still deemed experimental. But it could be a viable choice in the days to come. [0] https://github.com/golang/mobile https://github.com/golang/mobile
- eliasnaur 7y agoGomobile bridges Java and ObjectiveC/Swift to Go, and probably entails the same overhead the author is trying to avoid. Shameless plug: If you like Go and immediate mode UIs in particular, Gio[0] runs the same Go code across desktop and mobile alike. No bridging or native code required. If you like a more mature framework and don't mind Dart, I think Flutter is an attractive toolkit. I started Gio wanting to write a Flutter clone in Go before going for the immediate mode design. [0] https://gioui.org https://gioui.org
- JaggerJo 7y agoF# with Xamarin.Android + Xamarin.Ios
- thescribbblr 7y agoI used the same once a long ago
- tluyben2 7y agoOr the more common choice C#.
- jamil7 7y agoI'm not an expert but you could consider sharing Swift (or Kotlin) code between platforms. Nim (https://nim-lang.org https://nim-lang.org) could also be explored.
- saagarjha 7y agoYou can't really share that between platforms.
- jamil7 7y agoAh shame, I remember reading about targeting iOS at least with nim but didn't look to closely into it.
- rijoja 7y agoCame here to mention nim that I've followed with great interest. As it compiles to C you can probably use it just about everywhere. As far as android support this guy is working on adding support to android via Dalvik assembly. The usual approach to get nim to work with android would be JNI but that might cause problems for example with x86 android machines if I am not mistaken. https://github.com/akavel/dali https://github.com/akavel/dali
- nimmer 7y agoNim generates C, C++, Objective-C and js - so yes, you can target Android and iOS
- jamil7 7y agoRight, thought so. Thanks.
- W0lf 7y agoI 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.
- me551ah 7y agoJust use JavaScript. 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.
- auggierose 7y agowhich is not allowed on iOS ... Edit: Sorry for being unclear, was only referring to the updating JS on the fly and circumventing App Store part. Obviously (facepalm) ... ️
- jaredsohn 7y agoWhich part isn't allowed? A project I worked on did this a few years ago.
- mcraiha 7y agoI think there is some confusion around this. You can use Javascript with iOS if you use Webkit + JavaScript Core, and ship all your features in the binary that your app uses. 2.5.2 "Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code which introduces or changes features or functionality of the app, including other apps." and 4.7 " your app must use WebKit and JavaScript Core to run third-party software and should not attempt to extend or expose native platform APIs to third-party software"
- robjan 7y agoWhat specifically is not allowed? Microsoft provide CodePush as a service which allows you to push updated JavaScript bundles to Android and iOS apps.
- lultimouomo 7y agoIt is totally allowed on iOS. Perhaps your thinking about downloading such JS code at runtime from your servers, thus escaping Apple's control on the app, which was indeed forbidden (it is now ok as long as you don't drastically change the app) Bundling JS in the app and running it has always been just fine.
- skinnyasianboi 7y agoI 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 https://github.com/SimonSchubert/Braincup https://github.com/SimonSchubert/Braincup
- skinnyasianboi 7y agoIt's worth to mention that it also supports native Linux, Windows and macOS buildings. Plus web via JavaScript and server via jvm.
- victor106 7y agoThis is really cool. Care to share some resources from which others can learn to get started?
- soulnothing 7y agoThis is the official docs https://kotlinlang.org/docs/reference/multiplatform.html https://kotlinlang.org/docs/reference/multiplatform.html I've also done multi platform recently. I've taken a contract first approach. Swagger / openapi for rest clients. Outside of that I use vertx which has bindings for almost every platform. With those two I can account for interoperability across all platforms. Big hitches * No ts.d defintions at this time. But: https://github.com/vojtechhabarta/typescript-generator https://github.com/vojtechhabarta/typescript-generator * Dukat for automatic typescript definition importing (beta) https://github.com/Kotlin/dukat https://github.com/Kotlin/dukat * I've not done LLVM iOS. But I've read of some generic issues. They are improving dependency management to handle multi platform. I can't find a link but it was on their blog
- earenndil 7y agoD allows you to export an obj-c api. This won't help much on the android side, but would definitely help with talking to swift on the ios side.
- zelly 7y agoC++ 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.
- saagarjha 7y agoI wouldn't call C++ through the NDK "first class", especially compared to Objective-C++ on iOS.
- pjmlp 7y agoC++. It is part of both SDKs, you have direct support for mixed mode debugging on the IDEs. No need of extra tooling. On Android JNI is always going to be a pain, but at least with C++ Studio gives you an hand on accessing JNI APIs.
- izacus 7y agoCan concur, we had huge success sharing our core business logic as a C++ library which was then used by UI on Android/iOS/Web and even desktop native apps. Using Dropbox Djinni (https://github.com/dropbox/djinni https://github.com/dropbox/djinni) also helped with the horrible pain of JNI... although it's unmaintained these days. I guess people use SWiG now.
- gumby 7y agoI want to like this answer but not sure it's true. Do you mean bridging ObjectiveC++ and Swift? Apple is now deprecating ObjectiveC++ (after all the work we went to to make it work back in the NeXT days). I would like to integrate C++ code into a SwiftUI app but am not sure how to do it. Are there some iOS C++ APIs I'm overlooking?
- saagarjha 7y ago> Apple is now deprecating ObjectiveC++ How so? Objective-C++ drives a number of Apple projects, so I don't see how they're deprecating it.
- gumby 7y agoDocumentation seems to have vanished.
- armadsen 7y agoApple’s documentation for all sorts of things is in a sorry state lately. That includes mass “retiring” of perfectly good documentation for non-deprecated things with no replacement. I wouldn’t take missing or hard-to-find documentation for any specific thing as an indication that it’s deprecated. As far as I know, Objective-C++ is as supported as ever. That is to say, it’s not exactly a banner feature, but it works fine, and there’s no reason not to use it if it’s the best solution to your particular problem. I use it in a number of places, including to expose C++ code to Swift, which doesn’t interop directly with C++.
- _31 7y agoGood thread previously here on HN about code sharing between iOS and Android: https://news.ycombinator.com/item?id=20695806 https://news.ycombinator.com/item?id=20695806
- gok 7y agoC.
- tonyedgecombe 7y agoYes.
- shanth 7y agoDart+flutter?
- elmcrest 7y agoYeah, definitely worth a try. Includes progressive approach.
- mgleason_3 7y agoThis would definitely be my choice - for almost anything except certain types of game development. Flutter makes cross platform life so much easier - why do anything else?
- latchkey 7y agoI agree fully. Please consider that the Flutter team are having a hard time keeping up with iOS changes with regards to developer tooling. For example, print() is now broken due to iOS 13 in everything but xcode and while using a debugger/tests is the right solution, it sure is nice to be able to add a print() statement in there for quick and dirty...
- mightybyte 7y agoSo 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 (https://github.com/obsidiansystems/obelisk https://github.com/obsidiansystems/obelisk) and it's actually getting to be a pretty good development experience.
- malux85 7y agoI love hacker news. This is the comment I came here for. Just use this : A language that is (at best) fringe on the platform you are using. Here's a toolset nobody has ever heard of. Now build your mission critical bit of infrastructure on this house of cards, wait for the toolset maintainers to be outpaced and under-resourced by underlying OS/platform changes and then have to rewrite the whole thing which if it doesn't kill your startup, will certainly massively impact its resources. Go! (THIS IS A JOKE)
- dimator 7y agoWell, developers are the kind of people that love to be contrarian, so it shouldn't be that surprising. Half the fun (in my mind) is doing something no one else is doing. Being novel. It's probably unwise in a business sense, but if everyone was being wise all the time, there wouldn't be much fun in software development.
- whateveracct 7y agoYou're not obligated to be a brutal capitalist as an engineer. It's okay to make decisions that are suboptimal (but still passable) for your employer but highly aligned with your own career interests. If you always optimize for whichever company is employing you currently, you're doing yourself a disservice and essentially "leaving money on the table" :)
- deleted 7y ago[deleted]
- whateveracct 7y ago
- aaronbrethorst 7y agoEnglish
- StreamBright 7y agoI would say React Native. For the things you are doing it works perfectly.
- lewisjoe 7y agoWe 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 (https://blogs.dropbox.com/tech/2019/08/the-not-so-hidden-cost-of-sharing-code-between-ios-and-android/ https://blogs.dropbox.com/tech/2019/08/the-not-so-hidden-cos...). Pros: 1. Sharing native APIs with JS runtime and vice versa, was well supported & trivial to implement. 2. Easy to find skill-set. 3. We can run the same code in browsers as well. Cons: 1. The app will be slightly heavier in Android (as V8 has to be bundled with the app. iOS allows using native JsCore runtime.) 2. The shared code runs slower (Obvious, because dynamic language).
- panpanna 7y ago> as V8 has to be bundled with the app. Cant you make use of Webview somehow? It has the benefit of being updated from the market if a security issue is found.
- njsubedi 7y agoI'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]
- novocaine 7y agoWe'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. Main advantages are * kotlin is a nice language with good type support * has good swift bindings out of the box * also compiles to js and cpp so we can use it in our Web product as well
- werber 7y agoHow much work do you have getting it into js?
- crummy 7y agoWhat's the debugging experience like?
- faitswulff 7y agoWhat tipped the scales over to Kotlin Native for your team over Rust?
- mojuba 7y agoSomething 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: https://www.scade.io https://www.scade.io https://academy.realm.io/posts/swift-on-android/ https://academy.realm.io/posts/swift-on-android/ https://blog.readdle.com/why-we-use-swift-for-android-db449feeacaf https://blog.readdle.com/why-we-use-swift-for-android-db449f...
- zwetan 7y agoActionScript 3.0 with the Adobe AIR runtime you will be able to publish to iOS, Android, Windows and macOS, see "Adobe AIR" [0] ActionScript is something similar to TypeScript you will have access to the whole Flash stack and more, see "Building Adobe AIR Applications" [1] 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] Note, the latest Adobe AIR SDK are now maintained by Harman [4] [0] https://www.adobe.com/products/air.html https://www.adobe.com/products/air.html [1] https://help.adobe.com/en_US/air/build/index.html https://help.adobe.com/en_US/air/build/index.html [2] https://www.adobe.com/devnet/air/articles/extending-air.html https://www.adobe.com/devnet/air/articles/extending-air.html [3] https://help.adobe.com/en_US/air/build/WS597e5dadb9cc1e0253f7d2fc1311b491071-8000.html https://help.adobe.com/en_US/air/build/WS597e5dadb9cc1e0253f... [4] https://airsdk.harman.com/ https://airsdk.harman.com/
- dandigangi 7y agoActionscript? Really?
- zwetan 7y agoyep really I know it, few other dev know it too, and the rest well... they will keep spewing stupid stuff about how flash is dead and ignore that wonderful tech their loss
- tpetry 7y agoAnother concept would be using Haxe Lang: You wrote shared logic in haxe which will be transpiled to c++ and java (and many more languages).
- masterwok 7y agoXamarin iOS and Xamarin Android using C#
- toast0 7y agoSince no one else has said it, I'll be the voice of reason. Share your design specs only, and let each platform team write the implementation in the language that they think best. Yes, you'll have two teams spending time on doing the same thing. However, you'll get important benefits. 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. 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.
- underwater 7y agoThe poster is talking about data processing code, and not UI code. > The app is responsible for processing data, submitting to ML models, and then displaying results in a UI There is not need to handle this logic seperately. And lots of reasons not to.
- onion2k 7y agoUsers will be at best confused, and at worst insulted by this. However... Don't assume that a user has an exclusive affinity with one platform at a time. Users will load the app on different phones, sometimes at the same time, so if there are any differences in the way the apps handle data you'll soon see things getting corrupted. Make sure you have lots, and lots, and LOTS of tests.
- fizx 7y agoThis is a UI-centric take. There are lots of internals that could/should be shared between apps. Recently relevant examples: a customized WebRTC stack, a websocket client with extra authentication and delivery rules. FWIW, my take on this has been to embrace Conway's law: if you have enough shared work to form a team around it, then break off a c++/whatever library and a team to maintain it. But if the hope is just to save 200LOC here and there, just bite the bullet and write it twice. Big thanks to whoever pointed out Kotlin Native: seems interesting enough to poke around with.
- cpeterso 7y agoHere'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. https://hacks.mozilla.org/2019/04/crossing-the-rust-ffi-frontier-with-protocol-buffers/ https://hacks.mozilla.org/2019/04/crossing-the-rust-ffi-fron...
- kerryritter 7y agoI'm surprised no one has pointed out the value of Ionic Framework (https://www.ionicframework.com https://www.ionicframework.com). I'm a huge, huge proponent of this. TypeScript is a great language (in my opinion), UI code-sharing is inherent, and Capacitor (https://capacitor.ionicframework.com/ https://capacitor.ionicframework.com/) is great for all the native work you need to do. Worth noting you can do this in Angular, React, Vue, or pure JS. This won't suit your needs for processing-heavy apps (though can WebWorkers help), but will work well for many apps (https://csform.com/top-10-apps-built-with-ionic-framework/ https://csform.com/top-10-apps-built-with-ionic-framework/ for a "top 10" list for examples). 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?
- deleted 7y ago[deleted]
- gagabity 7y agoThere is a google tool that converts Java to Objective C, it should be easy to find.
- santa_boy 7y agoI have a similar use case where the crux of my business is really data / analytics centric. The user experience is pretty much limited to mostly information consumption with a few click events (favorites, like, dislike, delete and the occasional standard input forms). I'm leaning towards using [Meteor](https://www.meteor.com/ https://www.meteor.com/) to share code between mobile apps and web apps. Using cordova shells is pretty neat for business applications. Would be interested in thoughts.
- deleted 7y ago[deleted]
- pier25 7y agoI'm looking at solving a similar problem but for desktop. 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.
- arcticbull 7y agoYou 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 exact same UI at the cost of platform-specific idioms. It hurts customers on both platforms to take that approach. 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. 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.
- timwaagh 7y agoXamarin (C#) and Cordova (JavaScript) are the usual suspects for such multiplatform endeavours. You should not use three languages in production if one is enough.
- arcticbull 7y agoThere's very limited appetite for introducing JavaScript on any client platforms. Your iOS app has to introduce a garbage collector, bridging, and yet another language that nobody on your team knows. Android has to spin up a second garbage collector. C# has all the same problems for core logic, and is all fine and good but you can't really get a native enough interface out of it.
- mister_hn 7y agoIf you really want to optimize and share code across platforms, you should really go for C++. 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.
- andriydruk 7y agoIn Readdle we use Swift as common language to run one codebase on all platforms. Currently, we use it for macOS, iOS and Android. In Spark for Android almost everything except UI written in Swift https://play.google.com/store/apps/details?id=com.readdle.spark https://play.google.com/store/apps/details?id=com.readdle.sp... The blog post about how it works https://blog.readdle.com/why-we-use-swift-for-android-db449feeacaf https://blog.readdle.com/why-we-use-swift-for-android-db449f... And our toolchain https://github.com/readdle/swift-android-toolchain https://github.com/readdle/swift-android-toolchain The biggest disadvantage is the lack of swift evaluation in Android Studio LLVM debugger. But we work on this.
- rsecora 7y agoI have 22 years of shipping products on time with Delphi. The latest versions do a wonderful job compiling to android, iOS, macapp or Windows. Delphi is not cheap, but in my case the time to market, and tight release dates make it worth. www.embarcadero.com/products
- nfriedly 7y agoFullStory 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. 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.
- pcstl 7y agoKotlin 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. However, a lot of the tooling around this is experimental, so you might want to tread carefully here.
- enjoiful 7y agoSurprised no one has mentioned NativeScript yet. I've used it, admittedly only for investigation purposes, but was super impressed. https://www.nativescript.org/ https://www.nativescript.org/
- omonien 7y agoI 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.
- fmxexpress 7y agoRAD 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++. 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.