Please create an account to participate in the Slashdot moderation system

 



Forgot your password?
typodupeerror
×
Programming

Dropbox Engineer Explains Why the Company Stopped Sharing Code Between iOS and Android And Started Using Native Languages on Each Platform (dropbox.com) 63

Eyal Guthmann, a software engineer at cloud storage service Dropbox, writes: 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. We adopted this C++ strategy back in 2013, when our mobile engineering team was relatively small and needed to support a fast growing mobile roadmap. We needed to find a way to leverage this small team to quickly ship lots of code on both Android and iOS. We have now completely backed off from this strategy in favor of using each platforms' native languages (primarily Swift and Kotlin, which didn't exist when we started out). This decision was due to the (not so) hidden cost associated with code sharing.

Here are some of the things we learned as a company on what it costs to effectively share code. And they all stem from the same basic issue: By writing code in a non-standard fashion, we took on overhead that we would have not had to worry about had we stayed with the widely used platform defaults. This overhead ended up being more expensive than just writing the code twice.

This discussion has been archived. No new comments can be posted.

Dropbox Engineer Explains Why the Company Stopped Sharing Code Between iOS and Android And Started Using Native Languages on Eac

Comments Filter:
  • by wherrera ( 235520 ) on Wednesday August 14, 2019 @01:47PM (#59086728) Journal
    This can easily be interpreted instead as an advantage to switching from C++, not changing to platform specific code.
    • by sconeu ( 64226 )

      No, because now any changes to "common code" need to be implemented twice. Once for each platform.

    • by Tablizer ( 95088 )

      The article implied C++ was the only language that had cross-compilers available for the two platforms, at least when they started. I'm not sure how a different language would solve the problems listed anyhow.

      • Comment removed based on user account deletion
      • by HiThere ( 15173 )

        Perhaps the article implied that, but it's clearly wrong. I believe that C, Fortran, and Ada had cross-compilers, and I'm rather certain that Forth either had cross-compilers, or could easily have had them added. Perhaps he meant that they chose C++ as the best language for the purpose that had cross-compilers available.

  • Good article (Score:5, Insightful)

    by SuperKendall ( 25149 ) on Wednesday August 14, 2019 @01:54PM (#59086742)

    The kind of things that a codebase shared across platforms helps with is not the tricky stuff, but the simple stuff that is easy to just write as appropriate for each platform.

    Over decades of programming I've found the real enemy of stable and good code is complexity. The truth is that writing the code as simply as you can for two platforms is always going to be less complex (In many respects) than writing code that is shared but has to adapt for the needs to many platforms...

    Also the thing I didn't see mentioned is that invariably sharing code across platforms means slower to adopt new features for each platform, or sometimes never adopting really useful platform features because it would be too hard to add to the shared codebase.

    So glad this article exists that I can point to when someone considers sharing code across platforms...

    • Re:Good article (Score:5, Insightful)

      by kbahey ( 102895 ) on Wednesday August 14, 2019 @03:00PM (#59087012) Homepage

      Over decades of programming I've found the real enemy of stable and good code is complexity. The truth is that writing the code as simply as you can for two platforms is always going to be less complex (In many respects) than writing code that is shared but has to adapt for the needs to many platforms...

      Mod the parent up!

      Well said indeed!

      This has been a major disappointment that I keep seeing happening everywhere: simple code evolves into complex code for no good reason, other than new developers wanting to do things the only way they learned or know. Whether it is making procedural code object oriented for no good reason, adding components that will not be often used, or many other reasons.

      The end result is that the code base becomes more complex, and less stable, less maintainable, and less secure.

      Technical debt ...

      • by balbeir ( 557475 )
        Second that.

        Using a "common" layer makes things more complex. If you encounter a bug, it could be in the common layer or in the native code. It makes debugging a PITA

        At least when you write native code you know that the SDK you work with is supported by the manufacturer of the device and that it will be well maintained. Not so with all kinds of javascripty/Csharpy/darty mobile solutions that are often 3rd party. They also tend to lag behind the latest versions of the native platform.

        So the received de

    • I think it greatly depends on the type of application. I write games (for PCs currently, but will eventually port engine to mobile), and my game engine and game code vastly overweighs any platform-specific interfaces I need. Something like a videogame interfaces with native systems in a fairly narrow and specific manner (video, audio, input, filesystem). My rough guess is that about 95% of my engine code is modern, platform-neutral C++, and virtually 100% of game code is cross-platform. It would absolut

    • The kind of things that a codebase shared across platforms helps with is not the tricky stuff, but the simple stuff that is easy to just write as appropriate for each platform.

      Did you ever stop to ask yourself where all that "tricky stuff" comes from?

      Likely answer: badly engineered APIs that export platform complexity to the application codebase in ways they really shouldn't be doing.

      Second root cause: this is almost always because our APIs are excessively procedural and insufficiently declarative. In a dec

    • by Kjella ( 173770 )

      Over decades of programming I've found the real enemy of stable and good code is complexity. The truth is that writing the code as simply as you can for two platforms is always going to be less complex (In many respects) than writing code that is shared but has to adapt for the needs to many platforms...

      The good thing about common code: It behaves the same.
      The bad thing about common code: It behaves the same.

      I've dealt with a lot of bugs where the programmer didn't use the common functionality, they simply copy-pasted or hard coded. Like you got 100 reports, 95 use the correct header/footer template and 5 simply copy-pasted from another report. Looks right until somebody modifies the template and suddenly those 5 reports are off but unless you manually go in and see okay report 1 looks good, report 2 looks

    • by jrumney ( 197329 )

      It depends on the platform too. iOS and Android both have a rich set of libraries that cover a lot of functionality. There really is little benefit to trying to commonize code between them, since most of what you are doing is putting a UI on top of a specific configuration of library functionality. If you try to commonize there, most of your effort ends up being spent on duplicating functionality already available in the platform libraries just so you can have a common implementation. For more bare bones

    • by AHuxley ( 892839 )
      Most should have found that out during the PPC/Intel years.
      Great design and smart people to work on both products at the very start of the project.
      Cant pay the 2X expert wages? Make a great Windows product.
    • That is the most false thing I've read all week. Imagine you have something complex, like self-driving car code. Would it be easier to write the core AI code once, or twice? Nah, each platform is going to use tensorflow, even if they wrap it in a native UI. The problem here is knowing what parts of the code should be shared, and what should not. That is something a good architect can determine. As a general rule, UI code makes sense as native code, and heavy algorithms make sense as native code (if you use
    • by _merlin ( 160982 )

      OK, take a look at the codebase of MAME [github.com]. It's fully cross-platform with only a small platform-dependent layer. Are you seriously going to try and tell me that the the millions of lines of cross-platform emulation code is the simple stuff, and it should be re-written for each platform? What planet do you come from?

    • While what you are saying has merit, decisions like this are made by managers who are very pleased and think they have done a great job and they can write a lot of crap to justify it (Can be all true.) but three or four years later a new manager makes the exact opposite decision cuts the dev team in half (prematurely) and writes why the new decision saves the company money.
      Probably both ways it does just because it shakes things up and cuts a significant amount of legacy rubbish out. It also has an expense
  • by surfcow ( 169572 ) on Wednesday August 14, 2019 @01:56PM (#59086754) Homepage

    Many of the old precepts we were taught about programming ... may turn out to be shit in today's world. Ideas that made sense 25 years ago might be laughable today.

  • The real challenge of programming is problem solving, not writing the code. You can take a working code base and give it to another developer and they'll have very little trouble translating it into another language or platform as long as the original code isn't a mess. But even then, they'll figure out how to untangle it and then they can pass their solution back to the original team so they can see how to untangle their own code.

    • by loufoque ( 1400831 ) on Wednesday August 14, 2019 @02:05PM (#59086798)

      If only that were true.
      What's more likely to happen is that the developer will copy the code, which is the worst possible thing you could do.

      Better just explain what the code does and let the developer rewrite it from scratch.

    • by Ichijo ( 607641 )

      You can take a working code base and give it to another developer and they'll have very little trouble translating it into another language or platform...

      When you do that, you run the risk of re-implementing Objective-C features in Java or vice-versa rather than using native features.

      No, the code should be for reference only. Give the developer the complete set of requirements that "contain everything you need to know to write software that is acceptable to the customer...if a product satisfies every state [tufts.edu]

      • I have never in my life seen such a spec written for anything in technology. I do not expect I ever will.

        • I have never in my life seen such a spec written for anything in technology. I do not expect I ever will.

          I had 2 days to write a spec partway through a project - 130 pages, nicely indexed, with example code for the tricky stuff. Turns out it was "too complicated" for them to understand - though the project itself was complicated.

          I told them that until they can pass a test proving they read it, I'll never write another one.

          "We wanted to see if you understand it," Of course I did, I spent a couple of years fixing it after several teams got bogged down and polished their resumes rather than admitting they coul

    • by Livius ( 318358 )

      they'll have very little trouble translating it into another language or platform

      No, they'll have quite a bit of trouble.

      But that doesn't mean it wouldn't be the right decision. When you do cost-benefit analysis, both costs and benefits have to be counted.

    • by q_e_t ( 5104099 )

      The real challenge of programming is problem solving, not writing the code. You can take a working code base and give it to another developer and they'll have very little trouble translating it into another language or platform as long as the original code isn't a mess. But even then, they'll figure out how to untangle it and then they can pass their solution back to the original team so they can see how to untangle their own code.

      Verifying that it is the same, functionally, as the original is non-trivial. Test cases help but it's more the case that a case that fails means it is not the same more than something passing all the test cases means it is the same. Formal proofs of congruence across two different languages aren't really available. And this is before new features are added to each new code base.

    • by AHuxley ( 892839 )
      How did that work out during the Intel/PPC years?
      The GUI work great, look great?
      Expected speed on the OS/GUI the same?
      People on each OS expect GUI perfection as thats what they are paying for.
      Hire two teams after the problem solving part? Version drift between the OS?
  • Comment removed (Score:5, Insightful)

    by account_deleted ( 4530225 ) on Wednesday August 14, 2019 @02:05PM (#59086794)
    Comment removed based on user account deletion
    • Essentially they switched to the "official language" so that they could sit a code monkey at a desk with an Android/iOS IDE and have them glue together frameworks instead of having real developers who understand how software is built and interacts with the system analyze the problems and develop solutions.

      A common practice in the app/web world. No wonder they have retention problems.

    • by Livius ( 318358 )

      Using a particular kind of life cycle management doesn't mean someone is "not good at C++". It is a strength and a weakness of C++ that it gives programmers so many options, and programmers have to be conscious of the trade-off of using one or the other or using both with the added complexity that that implies.

      Someone who thinks there's exactly one way to do *anything* in C++ has missed the point.

      • Not quite true. They are not good at designing a solution (of such applications) sanely, where all resources are identified having proper ownership before any coding works. In short, "life cycle management" is not the work that most application developers should ever do. Such things should have been specified in the design independent to languages to implement it. The complexity for coders is not the excuse to ignore the complexity of the solution. And one sad thing is historically few users have respected
    • Re: (Score:3, Interesting)

      by Waffle Iron ( 339739 )

      If you don't need to communicate with Javascript (i.e. web browsers), then JSON is completely the wrong tool, and adds many more problems than it fixes. No wonder they were having a tough time, they were trying to use untyped data or weakly typed data in a strongly typed language.

      What do you propose? Dumping C++ structures straight from memory to disk or a socket?

      If so, Good luck ever changing anything, even your compiler flags. (Not to mention that using unsanitized data a security nightmare waiting to happen.)

      If not, you have to parse the incoming data somehow (even if it's some kind of binary format). If you have to do any parsing at all, then you might as well use a JSON library, because it's mature, universally supported, and simple.

    • The main problem was that they did not build a clean seam between C++ and platform-specific layers, but decided to use djinni that would automagically connect the two worlds.

      We tried djinni in a smaller project, and our team faced many problems with this framework – not because it did not deliver on its promises, but because it turned our execution flow into a callback chaos, and debugging into nightmare.

      Eyal writes about the same experiences, but attributes them to the hybrid C++/(Java and Obj-C) nat

    • they actually spent time on non-nullable pointers instead of just using the C++ standard shared pointers and unique pointers. They were writing and using JSON in a capacity where they did not need to talk to anything Javascript related

      Where are you getting all of this? This wasn't in the article.

      • by Dog-Cow ( 21281 )

        He pulled it out of his ass, obviously. Dropbox has had a website far longer than it has had mobile clients. The website almost certainly uses a REST api (or some such) which communicates using JSON. It's a well-tested API that would be foolish to duplicate in binary format, having to write new parsers on both ends and keeping them up-to-date with the JSON format over time.

    • by Dog-Cow ( 21281 )

      In short, you didn't read the entire article and you don't understand mobile platforms (particularly iOS and Android). An app such as Dropbox has the vast majority of its code interfacing with the system. The systems are very different, and writing common code to present an abstraction just means maintaining two concrete implementations in a language that each platform has to jump through hoops to interface with. It's not worth the effort because you spend more time debugging than you do writing. You lo

      • In short, it seems that you don't have ever make any cross-platform framework that just work. Surely any developers working with these "mobile platforms" should have known how shitty the differences they have to work around among these systems (and those who maintain cross-platform frameworks should know more), it does not mean that there is nothing to do and the platform-specific solutions will definitely work better. That said, Dropbox may not be totally wrong, but it's things about hiring what kind of pr
    • by Dog-Cow ( 21281 )

      About JSON: Dropbox has a website. Quite likely it uses a REST api that communicates using JSON. It would make little sense to provide a separate API for the use of mobile clients, but would make a lot of sense to reuse the existing API. You sound like an utter moron, and I hope I never have to interact with any software you had a hand in.

  • And let them use the language and tools they consider the best for their platform. You will have productive, and most importantly, happy developers.

    • by AHuxley ( 892839 )
      Thats the only way. Experts who understand the users, GUI, OS, CPU, GPU, memory on each side.
      Who know that the "OS" brand will never allow that amount of CPU to be accessed by an app.
      The GPU limitations.
      What the users expect from a GUI they use everyday as set by the OS brand.
      Who are ready for OS changes. Hardware changes.
      Who can keep each OS app working as it should.
      Who can get the best out of power saving limits on CPU/GPU so the GUI stays responsive on that OS.
      That needs really great code an
  • If you are developing an application that doesn't use lot of platform specific features, then it makes sense to go with a cross platform framework. Just don't try to build your own cross platform framework.
  • by 110010001000 ( 697113 ) on Wednesday August 14, 2019 @02:24PM (#59086882) Homepage Journal

    "By writing code in a non-standard fashion, we took on overhead that we would have not had to worry about had we stayed with the widely used platform defaults"

    What? Why did you write code in a "non-standard" fashion? I think the problem is that they are morons that depend on "frameworks" for everything.

    • by Livius ( 318358 )

      I found that part odd - I don't doubt that it means some additional complexity but there's no reason for any of it to be non-standard. Especially since there's enough standards that you can pick the one you like.

      • by Dog-Cow ( 21281 )

        What is the standard way to run code concurrently on iOS? How about Android? What are the preferred mechanisms for network communication? How do you handle background processing when your app isn't active?

        There's very little that's common between iOS and Android at the system level. If you try to commonize, you are fighting both platforms.

  • difficult to hire replacement senior engineers with relevant C++ experience who would be interested in mobile development... the mobile development community is very dynamic--new technologies and patterns emerge frequently and are adopted quickly. The best developers like to keep their skills up to date.

    So the org has to use whatever is "in" because everybody is chasing "in".

  • by MobyDisk ( 75490 ) on Wednesday August 14, 2019 @03:01PM (#59087018) Homepage

    Why did DropBox have so much trouble making a cross-platform C++ mobile application while video game studios makes cross-platform C++ video games so easily? The article is light on details, but I can make some guesses:

    1. Their mobile developers refused to learn C++. This sounds like a culture gap: they hired people who wanted to make a phone app because that's all the rage, but they weren't real coders. This is similar to the late 1990s when companies hired "web developers" who knew only HTML or the dreaded Visual Basic developers who had no grasp of computer science. Going even further back, it was the FoxPro and dBase developers.

    2. Dropbox designed their application inside-out. They wrote a C++ application with callbacks into Java/Swift, instead of a Java/Swift application with callbacks into C++. C++ is the lowest-common-denominator language and anything can call into it. But it is often difficult to call from C++ into other languages. Those languages expect all the callers to be using their runtime.

    3. Apple and Google intentionally made their platforms with lock-in in mind. Most major OSs are natively written in C and C++ so that any language can call into the OS. That is generally a feature. But Android's APIs are natively Java, so writing in anything lower-level than Java is a problem. They *want* it to be hard to port code to their platforms.

    4. Video games often have limited integration with the OS -- once you create a graphical window and open a network socket, the rest can be handled by your native code. But a mobile application might need to integrate with the "sharing" features of the OS, or the background service capabilities of the OS, or the bluetooth features.

    Overall, this article would not dissuade me from sharing code between OSs. But it is a cautionary tale about making sure the architecture is right, that you are sharing the right code, and that you don't hire computer pseudo-scientists who quit as soon as they have to write actual code.

    • by tlhIngan ( 30335 ) <slashdot.worf@net> on Wednesday August 14, 2019 @05:05PM (#59087400)

      3. Apple and Google intentionally made their platforms with lock-in in mind. Most major OSs are natively written in C and C++ so that any language can call into the OS. That is generally a feature. But Android's APIs are natively Java, so writing in anything lower-level than Java is a problem. They *want* it to be hard to port code to their platforms.

      Not quite true.

      Android uses Java because at the time, Java was a popular language for mobile phones. That's why there was J2ME profile. Of course, there weren't many mobile phone apps back then as carriers ruled the roost and made it hard to bring an app to a phone, plus each JVM was quirky with each phone so "write once run anywhere" was more of a joke when it came to phones. And the NDK was not available when Android came out, showing this heritage. They only added the NDK because the Dalvik JVM at that time was crap and did nothing but make things slower. The NDK uses standard JNI hooks so any competent Java coder could get settled in with Android development and NDK development easily.

      Apple used Objective C for iOS because their main OS (MacOS at the time) was developed in Obj-C, so all their frameworks and base OS came that way. Obj-C has direct C support - you can compile C code using an Obj-C compiler directly. So Apple went this route when they added app support. A competent Mac programmer could easily create iOS apps using the new UI toolkit, and like on the desktop, if they needed native code they just added it in directly inline or as a separate file to be linked in.

      Of course, that was then, now we have Swift and Kotlin, which change the game from compatibility to lock in.

      And the real reason is twofold - first, the amount of "core code" is probably shrinking - how much code does it take to access a cloud storage service nowadays? You could create a socket and handle the HTTPS connection yourself in core code, but that doesn't make much sense anymore since both OSes offer the same functionality in a library that's easy to call and use. The OS specific bits are OS specific and can never be shared. At some point it just makes sense to make it all native because the OS interfacing code is taking it all over.

      Second, well, iOS and Android developers are a dime a dozen. Just using native code for it all means you can easily hire cheap programmers for this job and leave the former app programmers working on the server end.

      • Would you really want "app developers" working on the servers? Just saying ...
      • by pjt33 ( 739471 )

        Android uses Java because at the time, Java was a popular language for mobile phones. That's why there was J2ME profile.

        I don't doubt that you're right, but the choice of target developer community seems odd to me. Smartphones have more in common with PDAs than feature phones, and while you could develop for PocketPC with Java (CDC/PP, not the ultra-limited CLDC/MIDP of feature phones), there wasn't a built-in JVM. I think most devs used C++.

        • It seems that they did not successfully attract most of old professional devs to embrace the new platform. Java was already famous (and infamous) enough to get more noob devs at that time.
    • Calling from C++ into Java is not difficult at all!
      Loading the JVM from the C++ side is actually the preferred way. Obviously that does not indicate who us calling whom.

  • By going back to standard toolkits, you don't have to depend on as much 'institutional' knowledge, and can outsource lots of coding, saving money (ha ha).

    • by AHuxley ( 892839 )
      Go full port :)
      The GUI will look ok again after some testing :)
      With todays fast CPU and GPU the GUI will be responsive.
      The hi res art work will always just fit in.
      A notch... ?
      Lens hole is where now?
    • If the software is once written and working, rewriting/porting it, is relatively easy.

  • Comment removed based on user account deletion
  • This is 100% in my confirmation bias zone :-)

    Example: We've been using React Native. It got us going really quickly and initially had a lot of advantages. It's good, as far as these things go. But I see a lot of effort going into nursemaiding the UI through stuff implemented by the UI framework in iOS which also obeys a hundred different UI settings of which the React code is entirely unaware and unresponsive. Larger or smaller text sizes, the 'bold' setting, reduced transparency, reduced animation mode

  • Easy solution: just drop Apple. Only a sliver of the market anyway, not worth the bother.

Real programmers don't comment their code. It was hard to write, it should be hard to understand.

Working...