I have come to this same conclusion after many years. It's not cost-effective to have any bespoke business logic (models, controllers, etc.) shared between the two mobile platforms (don't get me started on sharing UI code). If you have some incredibly tricky low-level algorithm/library and/or need for speed, think database, crypto, intense graphics, etc., then fine, you may be able to swing a shared module in C++ or something. Other than that, it's almost like the collective consciousnesses of Google and Apple conspire to make cost-effective code-sharing of typical CRUD apps almost impossible.<p>Here's a fine alternative to code-sharing: well first and foremost you need to have a good requirements spec. After that, implement it on one platform first in a platform agnostic way. So heavy use of delegates/interfaces/injections to handle platform-specific functionality, even for one-liners like getting current system time. So the code should be pure, boring, plain old Java, Kotlin, Swift, whatever. Minimal use of fancy language features that may not port cleanly. After one platform has the module in place and well-tested, do a copy/paste port to the other platform. You will find that the copy/paste port will actually uncover bugs, optimizations, edge cases, etc., that can then be ported back to the original platform. Things you would not have found if you were only writing the code once. It's like the most intense kind of PR code review you can get.<p>So I've found that copy/paste-port-based code sharing between platforms is not just a lesser evil, but actually a strategy that has its own unique benefits. If you get into a groove you can build up a set of regexes to give you a sloppy transpiler that does most of the tedious porting for you.
We've had a mostly different (positive) experience doing a similar thing at FullStory for mobile instrumentation, though I think I know where some of the key differences are.<p>Our core "business logic" lives in Rust. This is a shared bit of code between Android & iOS that mainly deals with orchestration, serialization, and server communication. We managed to extract ~1/2 of each platform's native code into this shared orchestration. What's left on each platform is more like a platform driver.<p>I fully admit that things are different for us because we're not dealing with a bunch of UI that we manage (instead we're dealing with UI that our customers have written in Java/Swift/Objective-C/etc), but I think that there's a few places where we've made this work in a better way:<p>- We've chosen flatbuffers to serialize most (not all) of the data between the platform drivers and the shared library.<p>- We're using a language that's a little more hip. It's still not very easy to hire Rust developers, but developers interested in Rust are _very_ interested.<p>- We built tooling early on to make this pretty seamless. Our Rust code builds in XCode and gradle, so there's no real friction to a developer getting up and running.<p>Our team is about a year in on this transition to Rust and so far it's helped us move far quicker, especially given the size of our team.
I was the engineering manager for a time at a company who launched a competing product to dropbox (its dead now). During my time there we deployed a common c++ core that did the business logic, and we wrote the uis in Qt with Qml for the forms. We also used swig to export the c++ objects to java. Our ui forms looked native, and they ran on every mobile os at the time (Windows phone, iphone, android), and we even used some of the Qml forms on our desktop ui.<p>Yes it was kind of a pain in the ass to share code like this, but it worked, and the mobile guys mostly just dealt with the specific problems relative to the mobile domain and not api integration issues with our cloud.<p>That being said, I can tell you for certain our mobile devs (most of them anyway) would've preferred writing their own client api in the native language of the platform. Maybe Dropbox just got tired of dealing with that, they have the money now to hire fleets of engineers to write just about anything on any platform, why would you even bother sharing a client library in that case? But in our case, we were a small team, so we really didn't feel comfortable just letting the next mobile dev who walked in the door come up with another foundation library.<p>Coding is hard, coding with a team is even harder.
I often struggle trying to explain to more junior developers that there are times when it's OK to write code more than once. There is a mindset that you should only ever write code once. It exists for (very) good reason. But if you follow it dogmatically, you may end up with an unmaintainable tangle of dependencies that can only be resolved with a rewrite.<p>Sometimes, it's OK to write the same thing twice if the alternative is a major refactor - such as inventing your own stack.
Recently worked at a company doing similar to this to support Windows and macOS.<p>To add to the difficulty, they used Chromium as a UI front end much like Electron. All built in house though.<p>They hired me as a JS/HTML/CSS dev, but same as the article states, the C++ work was the true bottleneck.<p>They knew I had some C++ chops and set me to work doing C++ with a sprinkle of JS here and there.<p>Due to incompatibilities in the compilers, there was a rats nest of dependencies, thousands of #ifdef’s to cover differing OS implementations, and we had to use some of the oldest versions of C++ to be compatible with both XCode and Visual Studio.<p>As the article states, we had custom background job libraries and debugging them was a nightmare.<p>Also similar to the article, we spent more time than one ever should setting up builds to handle our ludicrously complicated build configurations.<p>And lastly, as the article stated, we had a hard time finding new talent to cover the growing amount of work required to deliver our product. There just aren’t many C++/JS devs out there.
It seems like the real issue was that Dropbox lost all of their senior C++ engineers. That’s a real mistake on their part, losing the only people who truly understand your product can be a death sentence for a company. I know my employer is very conscious of who knows what part of our products, and does their best to ensure that we never have any knowledge gaps.
I've been using C++ to share code between iOS and Android for years and have come to the same conclusion. I developed the C++ code on desktop operating systems which was easier to debug, but once you move it to mobile then the debugging gets a lot harder (on Android at least).<p>The overhead of the JNI interface is quite a lot of work too. Luckily I had a UML model that I generated the interfaces out of, so adding JNI was just a matter of templating this out of the UML, but it was still quite a bit of work.<p>On iOS the situation has gotten worse in that the interface between Swift and C++ has to go through C, so if you are using C++ you need a special interface layer, which is almost like the JNI situation on Android.<p>So you have the trade-off of on one hand having two code bases (Swift, Kotlin) and the associated headache of keeping them in sync, versus the extra work of maintaining the C++ interface layers and testing and debugging on each platform. In the end I now believe that it is better to work with the platform native development tools rather than trying to share C++.<p>As far as finding developers goes, because of the rarity of using C++ on mobile there will not be a lot of developers with this experience. I work remotely and have found that any remote C++ work is very rare, Swift and Kotlin are a lot easier to find work with (it's still more difficult that you would think to get remote work of any type).
It looks like that took very poor decisions such as bad frameworks and in-house made libraries vs what was already existing.<p>First, it's not true that there's no C++ mobile community. There are plenty of forums, blog posts, projects, using C++ in mobile field. Xamarin and Qt are helping C++ Devs go mobile since years.<p>Second, it depends on which standard they've used. It looks like they choose a pre-C++11 standard, making things more complicated (in 2013 there were already full C++11 compliant compilers, even for mobile), especially threads. They probably forgot that Boost itself has modules for JSON, checks for non null objects and so on.<p>Third, they probably kicked off the project with some average C++ developers and they left. They haven't found cheap experts (compared to Kotlin/Swift, which are really cheaper) and didn't want to pay high salaries.
The story that those Kotlin/Swift developers didn't want to learn C++ says a lot of the quality of those developers as well. Sure, it's matter of interest, but it was also a great opportunity to earn much more money as well.<p>As for build systems, it's true that it's an unsolved issue, but CMake is pretty much a standard and it can handle dependencies, if someone knows how it works. Sorry, but this is a story of poor choices and unskilled people for this huge job.
The cross platform landscape is pretty daunting for a solo dev. I ended up just writing my app natively, time will tell if that was the right decision or not. Most of my business logic is handled by my backend. I like the performance and being able to implement platform specific features as soon as they're released. I might look into doing some codesharing in Rust if it becomes more straightforward. Sometimes it's OK to write things twice.
This article hits close to home. I've been working with Xamarin for almost two years now. It has done its job and provided a quick avenue to prototype a concept and deliver a product. However, as the article mentions, the maintenance is a bear. Here are some of the issues I face:<p>- The developer experience is awful. Visual Studio for Mac causes so many issues (crashes, mangled project files) it hinders productivity. About once every two weeks I spend half a day wrestling with a VS issue.<p>- As AirBnB's article mentioned, to be effective in cross-platform development, you need to know three platforms well which is a difficult task.<p>- Xamarin's performance on Android has notoriously been poor and only has marginally improved. Try using a Xamarin app on a cheaper Android device or an older version of Android.<p>- No mobile engineers want to work on Xamarin.<p>That said, the good news about working with Xamarin is that it exposed me to C# and the .NET ecosystem. I'm truly impressed with these technologies.<p>EDIT<p>I forgot to mention that I think the complexity of an app ought to determine whether a cross-platform technology is a good idea. Xamarin is a great solution for prototypes and simple apps.
Having worked in multiple places that ship iOS and Android, the real thing to focus on is cross-platform requirements, not code.<p>Writing mobile apps is fairly trivial - writing good requirement documents is black magic I have yet to see in the real world.<p>Trying to share code is like trying scratch your left foot when your right foot itches. The issue with two codebases that are supposed to do the same thing is keeping them in sync over time. The only way to do that is by having actual requirement documents.
Add more fuel to the "write once, run anywhere" dumpster fire. Let's peek in there - I see C, C++, Java, JavaScript, stored procedures, wxWidgets, RubyMotion, GTK, QT, object oriented programming, functional programming, PhoneGap, React Native, Flutter, ... It is getting full in there.<p>What's that about the definition of insanity? Doing the same thing over and over and expecting a different result?<p>Sever side rendered HTML is the closest we've come, but that's not cool anymore.
1.5 years ago Dropbox was looking into rewriting their shared mobile codebase in Rust. It's a shame this blog post doesn't touch upon that at all, instead focusing on C++.
It baffles me that people think duplicating application code for every device is the way to go. Cross platform can be done correctly. I'm working on a stack that can natively target Windows, Mac, Linux, Android, iOS, MacOS, and Web. I couldn't imagine duplicating my code for each one of these devices. If something special needs to be done, I write an extension.<p>I have a feeling posts like these get upvoted because developers who make the native apps want to keep their jobs.
But those developers will always be needed for the native bridges, just not as many of them.
> Because this issue involved debugging multi-threaded code running back and forth between C++ and Java it took weeks to nail down!<p>I don’t think the issue here is the use of c++ — it sounds to me like it’s the use of c++ on problems that would have been far simpler solve on the native code ... not all problems are that way — but even where it makes sense to solve with c++, you have to be careful about the glue.<p>I developed and maintained cross platform c++ for iOS/Android in a previous role and the platform to native glue is inherently complicated — among the most complicated parts of the program to reason about if you get into the details of it. I solved by making this layer dead simple — you could almost never pass objects in or out — just primitive values.<p>The c++ layer exposed to platform was just static methods — including a bunch of methods for retrieving state and we added more static methods when new kinds of communication were required. Every c++ method grabbed the largest lock it could prior to doing anything natively (and in debug mode related methods associated with some kind of stateful lifecycle would fatalError if they couldn’t get the needed lock — the app code shouldn’t have been calling into native code in a way that violated simple assumptions about how the state was allowed to change).<p>Interestingly — this forced the platform layers above to comply with the assumptions needed to keep the native code simple — and helped those working on the UI immediately find out when they were violating these assumptions — things like click handlers that weren’t debounced or weren’t switching to a disabled mode after being clicked — when those click handlers invoke native code and that native code mutates state — you have a potential nightmare scenario for robustness ...<p>This model actually was quite straightforward to add new functionality to over time and we frequently moved decision authority over complicated logic into the native layer so that we could make it robust and cross platform ...
The best way I've seen this work (inside Google Apps) is to write shared business-logic in a common layer (here it (often) gets written in Java, then transpiled to Obj->C and Javascript, other teams go from C++ -> Java & JS, and other other teams embed JS inside of everything.. and other other other teams write everything in a native language (there is no one single way at Google))<p>then use a data-definition-language (like protobuffers) to define a bridge from inside of transpiled code land to your native layer, and compile native language bindings for your UI to read & write data models.<p>then stack a mechanism like GRPC which takes the DDL to the next level and makes services a declarative, language agnostic definition... and compile your service stubs for each platform.<p>...then write the UI in a native layer for each platform, using the native service stubs and data models compiled from your DDL.<p>Once you start trying to abstract the UI models between iOS, Android, and web you are stuck with a shitty status quo solution that leads to terrible hacks or boring concessions that ignore platform differences.<p>However abstracting the common (non-ui) mechanisms like asynchronous data structures, sockets, and storage is a relatively solved problem.
<i>The overhead of C++ adoption actually prevented us from ever moving fully in this direction.</i><p>Today, unlike in 2013 when they started, there are other options.<p>For others considering code-sharing, another option not mentioned in their article is Rust for the core with Swift and Kotlin. Between bindgen, futures, serde_json and non-nullable pointers in Rust, those would satisfy their stated subcategories today.<p>Companion templates are explained here: (January 2019)<p>Medium.com/visly/rust-on-ios-39f799b3c1dd<p>Medium.com/visly/rust-on-android-19f34a2fb43<p>(No affiliation other than starting to proceed down this path myself.)<p>For Common Lisp heads, there's also MOCL, which seemed quite reasonable when I explored it years ago: wukix.com/mocl
This is precisely the experience of my startup trying to rely on flutter. It's a constant battle. Moreover Android and iOS are different implementation with different capability with constantly evolving API. It's hard to keep cross platform code in sync many #ifdef with edge cases.<p>Moreover with REST API architecture majority of the common code is in back-end. So building in Swift and kotlin for respective platform is not as tedious.
Having done this quite a few times, it looks more like they are having issues to retain C++ developers, are too picky on their hiring process and the original devs have left, than anything else.<p>And given some of the macOS client practices, the engineering quality is also to wonder.<p>For me, C++ with native views, or Xamarin, will keep on being the way to do mobile apps that can't be done as PWAs.
What I don't see them saying was that it was the wrong choice in 2013 for a scrappy team and an evolving product, just that it's not the right choice in 2019 for a company with ~infinite dollars and a stable product.<p>I'm looking at building a mobile product solo right now, and I'm finding Flutter a pretty compelling idea. Building everything twice means being circa twice as slow, meaning I can learn about what the market needs half as fast.<p>I might be wrong, of course, but this isn't the article to persuade me otherwise.
I don't understand why someone at Dropbox's size and scale would go after C++ on mobile and blaze their own trail, when its probably more pragmatic to go native.<p>With that being said, I worked for a firm that extended the life of old ERP systems and we had to do a few mobile apps, we chose Xamarin because we were a shop of 7ish devs that had many projects to maintain and the cost of code sharing and familiarity with C# were our driving factors. It was a trade off most definitely but it was a pragmatic choice as well.<p>If you are capable of hiring more developers who know Java or Obj-C and can allow them to do only mobile development then its worth it to go native.<p>But, if you are a small company and know that Java,C# and Obj-C, C# developers are a little bit hard to find (depending on your developer market) then its probably more cost effective to go Xamarin or any other cross-platform code sharing model.<p>In the end its all about pragmatism.
I'm somewhat disappointed that this didn't work out, as I have usually promoted a C++ core along with a thin native wrapper as the solution for those looking to share code across platforms. At least they moved to native development, though, instead of some poor facsimile that was "easier"…
Interesting post. I wonder if the major pain point was the fact that they were doing dev with a language that had nothing to do with either platform.<p>We’re currently investigating Kotlin/native and it looks really promising. We don’t have to write stuff in a foreign language, but can repurpose our existing Kotlin code and share with iOS. This model seems promising.<p>Does anyone have any experience with Kotlin/native?
It's funny that they have a hard time hiring experienced senior C++ devs even though the language has been around so long. Presumably it would have been easier to find someone really good at something newer like, say, Vue.
I'm also in that approach for the same reasons. Currently I have an app I'm cross-developing with separate iOS / Android codebase. the only 'shared-code' is Firebase libs for each platform (which seems to be written in itself cpp and bind to Kotlin / Swift).<p>C++ itself is pretty portable.
There are actually frameworks (QT / JUCE) that allow true cross-platform builds.
They work, but you'll eventually end up having a lot of branches for specific platform.<p>Still if you just need basic algorithms (signal processing or anything expensive CPU based) C++ might be good enough to write simple callbacks with bindings.<p>Evil UX/UI:
-----------<p>Xamarin, Flutter, React Native -
It really depends on the app. but if the app needs to be in the "device" UX and the unique APIs provided by the platform. people can glorify the cross-platform all they want but,
You'll eventually end up with branches for each platform in the good case and bad performance in the worse case.
Using C++ for libraries was not a bad idea but I think they got the architecture wrong. They should have used a protocol like gRPC streams or flat-buffers to communicate between core libraries and the platform UX libraries. Basically the mobile app is treated as a frontend talking to a backend using a communication protocol. You can design this to be stream-based, event-based, whatever fits the boat best. Depending on the platform, you can choose what should be part of the frontend versus what should go into the backend.<p>This is the way a lot of the big C++ mobile apps are built. Also there are lesser debugging headaches as each part can developed independently thanks to de-coupling, so you can hire native platform developers to do the job they know best without messing with C++.
I worked in a company that makes games for both ios and android and it shares majority of the code in between. It was using libgdx which uses Java & opengl and it was working very well for us.<p>I would say things are not so bad when you pick your tools right.
The common thread that I personally see between dropbox and airbnb, though completely different language sets, is adopting a shared codebase in a "brown field" manner.<p>Airbnb admits if they were able to greenfield React Native then there's a world where it would have worked.<p>Separately, the complexity of Airbnb and Dropbox as apps is very high compared to what I believe are the ideal use cases - simple interface apps that are thin wrappers on top of APIs.
How's was your experience in writing iOS and Android app in Cordova? I have a small community app written in Cordova+f7+vue2 which works pretty well on Android.<p>I want to port it to iOS now as there is some demand. I also want to add push notifications later. So far there is a inhouse API+server which serves as backend. Not dependant on Google for any services as of now; only if there is a non-firebase solution to push notifications?
I wish all the articles and blog post are like that. The first sentence sort of gives away what you need to know.<p><i>Until very recently, Dropbox had a technical strategy on mobile of sharing code between iOS and Android via C++. The idea behind this strategy was simple—write the code once in C++ instead of twice in Java and Objective C. </i><p>A lot of people will stop reading after this, for those interested they could continue with the details.
TLDR - it's too hard to find senior C++ mobile devs.<p>I'm more intrigued by AirBNB moving away from React Native - the linked article says "RN was too small a component to bother supporting, and the developer experience wasn't up to par", but I'd like more detail than that.<p>I've been working with Flutter for the past 6 months, and it would definitely be my "go-to" for any mobile application.<p>To be fair, I did spend 2 weeks going down a rabbit-hole to get Flutter talking to a .NET assembly by embedding Mono and invoking via JNI/Obj C, so I know the pain of native interop. If you're mostly doing work at the native platform level, then I can imagine why you'd stay away from a cross-platform VM.<p>In my case, I ended up with a brittle project that was clearly going to be a PITA to maintain & automate builds for, so I just rewrote the component in question in Dart.
Due to C++ inherently close connection with the OS I see this as an absolute happening. But they should've go with Objective-C and Java and stay with them, as they were the matured technologies back in 2013 for their target OSes. Instead they chose another young ones. Oh well, not going to cry due to Dropbox making Kotlin and Swift better due to still lack of libraries there for their purposes. The more the merrier, that's my motto. My absolute fear is the manager's dream to only UML be as programming language and they drag'n'drop with no coding behind (the wet dream back in 2005 my manager at Siemens had, and he told me the world is going that way. Ya sure buddy, not if we let it happen and so far instead of unification we have even more diversification)
Here is the genesis of this blog post: CppCon 2014: Alex Allain & Andrew Twyman "Practical Cross-Platform Mobile C++ Development[1].<p>[1] - <a href="https://www.youtube.com/watch?v=ZcBtF-JWJhM" rel="nofollow">https://www.youtube.com/watch?v=ZcBtF-JWJhM</a>
Does anyone have experience trying to do this kind of thing with LibGDX?<p>LibGDX is a layer on top of OpenGL (lwjgl actually), and used a lot for game development. It is based on Java, and is able to package the application for Android, iOS, Windows, Linux, Mac, and even web (targeting WebGL). For iOS it uses RoboVM, and for the web export it uses GWT to compile to JavaScript.<p>Obviously this is best suited for custom UIs (like games), but with some frameworks on top it seems it would be possible to build a decent interface. The framework already has support for most platform specific functionality (like text input). Performance should be great because it runs close to the metal, so to speak.<p>Just curious if anyone has tried this, as I am considering the approach.
Code reuse on anything that is too complex will usually give you these issues as reuse doesn’t scale unless is very simple and function is super well defined and focused. Programmers will turn it into a monster as it evolves, usually
This reminds me of LLD’s approach of sharing an architecture but having separate ELF, COFF and Mach-O implementations. This made it much faster than gold which wasn’t actually slow.<p>Apparently sharing code isn’t necessarily a great idea.
I just launched (like, an hour ago: <a href="https://news.ycombinator.com/item?id=20700196" rel="nofollow">https://news.ycombinator.com/item?id=20700196</a>) a cross-platform app that is almost all shared code. In my case, the solution is a web app with very lightweight native wrappers, and I'm quite happy with it. Obviously that wouldn't be the perfect fit for all apps, but none of Dropbox's "(not so) hidden costs" are relevant in my case, and I suspect many apps <i>would</i> be a good fit for the architecture I went with.
I shudder to think how many people will read this headline and immediately takeaway that React Native/Flutter/Electron are terrible cross platform solutions.
This is more about not finding enough developers for mobile C++, not much because of any sharing of code.<p>A single platform application with a C++ back-end would have the same issues.
Current state of sharing code between platforms is quite terrible. Most languages support only C FFI, so if you write shared code in C++, will require bridge from C++ to C and then bridges from C to native platforms.<p>For CRUD core, this kind of overhead makes no sense.<p>I think this situation could be improved with automated generation of bridges. Apple implemented this pretty well for their own purposes, you can call Swift from ObjC and ObjC from Swift quite easily.
When you're at Dropbox's scale it's easy to just hire a load of iOS and Android devs, and some product managers to keep them all in sync.<p>But when you're not at that scale - you can't afford to build the same app twice - you are often left with a choice of either Xamarin or React Native. Both of these are perfectly good frameworks on which to build software; don't let the FUD win.
As someone who has built a C++ library to share across iOS and Android I completely agree. The biggest issue for us was finding developers willing to learn and adopt C++.<p>For our use case we weren’t writing UI or user flow logic, it was an ‘engine’ that handled complex business logic. It used JSON as input and output.<p>If I were to do that same project again I would use mostly native code and write our engine in Javascript.
Since it's not stated in the article, I am going to assume they haven't tried Xamarin.<p>I've been really pleasantly surprised lately how much code can be effectively shared when using Xamarin Forms. I haven't encountered much problems, except when dealing with tricky stuff like the Android camera API's (which, from what I understand, is problematic in native Android code as well).
There's quite a few places that are still dealing with 4 codebases with varying degrees of shared code. Desktop, mobile web, native Android, native iOS.<p>A shame, since many of them don't really need more than one responsive web codebase. Native apps do add value for many use cases, but not all.
I think in the specific case of C++, this is mostly an Android problem, not a general cross-platform problem.<p>C++ works just fine on iOS, and interoperates very well with Obj-C (not sure about Swift, though).<p>C++ is a mess on Android. It can certainly be made to work, but the tooling and library support is minimal.
Over time as well, you cannot keep up with features. You will always be lowest common denominator, because if a system handles 6 platforms, and you want the feature of 1 platform on that platform, it will triple or more your amount of effort to implement it.
<i>Find and hire candidates with this very specific skillset (we tried to hire for this role for over a year with no success)</i><p>Really? You weren't able to fill this role? I can almost guarantee that you could throw an extra 25-50k at someone competent to fill it.<p><i>In the end we no longer share mobile code via C++ (or any other non-standard way) and instead write code in the platform native languages.</i><p>I've started to comment on this across the interwebs. If you are a cross-platform (native) mobile developer, and haven't taken a look at Xamarin, you _need_ to give it some attention. Xamarin.Native specifically is the best solution I've come across that mostly gets out of your way, and has robust library ecosystems and sane interop.
Would like to see an analysis of the costs and benefits of two separate codebases after they are done with that and have given it time to prove itself... especially with the more complex code.
Write once run anywhere seems to be the eternally elusive holy grail of cross platform software development. It's a shame AppForge died right before mobile took off (tongue in cheek).
Nah, this is bunk. The cost of code sharing on top of something like Ionic is next to nothing. And for every platform specific feature you can just plumb in whatever plugins you want.
Just look at the code needed to support the file system on iOS 13 to write a file provider. It changed a lot, and non-native code to adopt to that would be a nightmare I imagine.
another code-sharing solution that everyone enjoy to ignore is Adobe AIR<p>in 2013, AIR was v3.6, now in 2019, AIR is v33.0<p>not only you share code via ActionScript 3 (something like TypeScript just available 10+ years ago)<p>but you can also develop ActionScript Native Extension (ANE) in C, C++, Objective-C, Java, C#, Swift, etc.<p>and it does not only publish to mobile it also publish to desktop<p>but that's OK, keep ignoring it
Unless you need something very specific for the display UI. Try cordova (open source version of PhoneGap), and stuff like ionic, framework7.io, mithril.js will mostly get your most apps done needed while still sharing the code via JavaScript, HTML5/CSS. for anything native you can always write your own cordova-plugin if it doesn't already exist.
This comment will probably be viewed as preposterous or based on ignorance.<p>But from my perspective, you're probably doing it wrong.<p>And based on my experiences with different dropbox clients, I'm not too surprised, those apps all seem to be very badly built.<p>Switching language or framework won't help that much, I'm afraid.
I've been considering building a pwa and using a webview as a pseudo native app I know iOS support isn't great but it seems to be improving and iOS push notifications could be built separately in the meantime. How's anyone tried this approach?
OK, but they didn't attempt to use Qt.<p>I'm currently working on a project where we have indeed decided we needed to go Swift/Kotlin native on each platform, but with the long-term goal of building a cross-platform app with Qt.<p>Qt certainly has its issues, but I respect what its developers have accomplished. And it appears to offer adequate ways to do common things like parse JSON, and it abstracts things like Bluetooth usage and file storage in the apps' sandboxes; so I don't see some of the hurdles cited in this article.
This is wild. So Unreal/Unity and others somehow get to run their arguably vastly more complex engines on mobile desktop and consoles, but sharing some logic between iOS and Android is too complicated for Dropbox. What are they smoking?