Thursday, October 25, 2018

Native Mobile apps for iOS and Android; Writing it twice doesn't have to cost 2x

This post inspired by René Wiersma on Twitter:



As (I think I have) mentioned previously, my team is responsible for the company's Mobile Applications (and supporting cloud/on-premise services they connect to).

We need to support both iOS and Android as equals - in almost all cases we'll ship new features for both iOS and Android simultaneously, so the problem of developing for both of these different platforms keeps coming up; we've been doing this for the last 4-5 years.

We're not using any cross platform tools, so how do we do it? Simple, we write the app twice - once for each platform. For iOS we use Xcode and Swift (older code being ObjC) and for Android we use Android Studio and Kotlin (older code being Java).

Note: a key overall goal here from day one has been to try keep the code structurally similar, so that when you're fixing a bug on one platform, it's easy to find the corresponding piece of code to fix on the other platform. There is a tension here though against using the different abilities of each platform.

Original plan: One developer creates a major feature for a platform, another creates that same major feature for the other platform in parallel

Note: When I say "whole feature" I'm talking about a significant chunk of work - at least a month's worth.

We thought at the time that this would work, and perhaps the following might happen:
  • Each developer could work (and up-skill) on their preferred platform
  • Devs could work for a longer time without context-switching which would be good for productivity
  • We thought this would be OK as each dev would code-review the other's code, and they would both be involved in design reviews.

It was awful. I felt it took more than 2xtime/cost and generated technical debt like crazy..
  • Both devs would arrive at the same problems, and both would come up with designs to solve them. Usually these designs were different. This caused a whole lot of discussion and back-and-forth arriving at a consensus. The thing was - in almost all cases either design would have worked fine, and this discussion wasn't ultimately productive.
  • The devs didn't code review each-other as strictly as perhaps they should have, and when they did, their code had diverged enough that they simply reviewed it for correctness and didn't want to spend additional time going back over it and bringing it into line with the other platform.
  • And besides - if we need to align two diverged code-bases, whose code is the right code to align with?

Next plan: One dev creates a minor feature for a platform, then another dev does it for the other platform on a delayed basis; the feature is mostly complete by the time the second dev starts

We sort of fell into this due to devs coming free from other tasks at different times, but after the previous bad experience, we decided to make a deliberate go at this.
Note: our "minor feature" here is about 2-3 weeks or more. We simply could not use the delayed approach at the "major feature" level as it would have added so much time to the final delivery date that we wouldn't have been able to ship both platforms together on time.

This was only a little better. I felt it took about 2x time/cost
  • We thought the delay would prevent the "two people designing the same thing at the same time" problem and be more efficient. This did turn out to be true, BUT
  • The second developer burned a significant amount of time having to go back and learn how the first developer had done everything
  • Because the second developer didn't have the original context, when they had to make a different choice due to a platform difference, they didn't fully understand the code/design and would be more likely to make bad choices
  • The second developer ended up writing structurally quite different code just due to personal preference, which is a nasty trap for maintenance in future
  • This is terrible for testing. It makes sense for a tester to pick up the feature on both platforms at the same time, so they can check for consistent behaviour, etc.

Take 3: One developer creates a small sub feature for a platform, then another developer does it for the other platform after the first is pretty much done

The idea here was to try and minimise the bad effects caused by the large delay of the previous approach. We aimed for sub features being around 3 days or less worth of work, but sometimes up to a week.

This was better again, but still not great. I felt it had about 1.8x time/cost
  • I wasn't sure what would happen with designs, but it turns out even a small delay stops two people clashing trying to design the same thing in different ways, which was good.
  • The smaller delay meant that the second developer didn't have as large a chunk of work to catch up on
  • When the second developer needed the original context, it was relatively fresh in the mind of the first dev, so better discussions could be had
  • Testing waited til the second dev finished, but that was usually only a couple of days
  • BUT, the second dev still doesn't fully understand the problem in the same way the first dev did, so they still burn time coming up to speed constantly
  • ALSO, the second dev ends up using a different style/structure which hurts maintenance down the line. This is a big deal

Take 4: One developer creates a small sub feature for a platform, then that same developer creates it again for the other platform.

The idea was to try address the "second dev missing context and coming up to speed" problem.
Now we're getting somewhere. I feel this is about 1.5x cost overall
  • This means all the devs must learn to work on both platforms. If you're the kind of place that wants specialist iOS-only and Android-only developers you may not like this. Personally, I think pigeonholing people like that is terrible in any environment (Don't get me started on frontend vs backend developers), but hey, my team is small - perhaps when you have 50 devs you need to silo them like that, who am I to say?
  • This *is* effective; if it's the same dev doing both platforms, then they inherently understand the problem equally both times, and nobody else has to second-guess their decisions. Seems obvious, doesn't it.
  • BUT, when the dev would do the feature for the second platform, they would sometimes structure their code differently out of trying to better fit the other language/platform, or simply because it was a different week and they felt differently. We still had the maintenance pain down the line. Ouch.

Fifth time lucky: One developer creates a small sub feature for a platform, then that same developer ports the code in as literal a way as possible.

Goal: Stop the code diverging as much due to the devs being creative when writing the feature for the second.

Process: Write your small sub-feature for a platform, then open File.swift on one monitor and File.kt on the other, and go through function-by-function and line-by-line; Copy paste and then fix the errors and tweak the code.
The code inside each function doesn't have to match perfectly, but structural similarity is key here.

This takes discipline, but it is the best way we have discovered so far. It feels like it gets the cost/time down to about 1.3x
  • To quote a team member: "Porting code is boring", so that's a downside
  • Boring though it may be, porting code like this is really fast and often easy and safe. Things don't get missed nearly as much.
  • MAJOR Upside: If your code is in the same-named files, with the same-named methods in the same order, then when you make a fix on one platform it's very very easy to make that exact change safely on the other platform
  • Kotlin and Swift are much more similar than ObjC and Java, so now that we've moved to the newer languages this process is a lot easier than it used to be.

Conclusion

So here you have the recipe:
  • Break your tasks down into as small as possible sub-features
  • Have ONE dev do the sub-feature on one platform
  • Have the SAME dev do a "boring" port of that code over to the other platform. Don't be clever about it!
  • Enjoy :-)
Personally, I feel this is quite good. I've spent a good chunk of time using Xamarin and while the "porting code" cost is zero there, it has it's own problems and overheads. I feel like writing your app in Xamarin is about a 1.2x cost compared to writing a single-platform app in either native Swift or Kotlin, so to be able to write both native swift and kotlin apps with a 1.3x overhead seems pretty darn good to me! Note: the cost ratios are purely subjective based on my experience writing code in these various ways, and observing other team-members doing it too.
Note: We have definitely looked at various cross-platform tools, but found them all lacking:
  • Web-based (either PWA or cordova-type): Seriously evaluated and for what we wanted, we couldn't get good enough performance and nice enough UI
  • Xamarin: Seriously evaluated and found it to be really buggy, and also quite an additional burden to learn not only how the UI works (UITableViewController etc) but the quirks and oddities of how those things project into C#.
  • Flutter: Played around - maybe promising in future, but I think it's too early to depend on yet
  • React Native: Only read about it; Personally I can't get past the JavaScript. Ugh. Some people say that even for a single-platform app react native is more productive than Swift or Kotlin, and if this is true (while still maintaining the level of quality and performance we want) then it could be very compelling. It's on the list to investigate soon

24 comments:

Unknown said...

Any thought on Kotlin Native for sharing business logic ?

Ben Snider said...

Replying to Unknown: I actually gave a talk about this recently. Find some slides here:
https://www.slideshare.net/BenjaminSnider1/isomorphic-kotlin-121242772

Unknown said...

I've read some blog posts on kotlin native (maybe 6 months ago?) but I recall when I did that the iOS support was really incomplete. If we had to write a bridge between some UI code in swift and some "logic" in kotlin/native that would defeat the point, so I'd only consider it viable if you could write the whole iOS app in k/n.

Perhaps this will be viable one day - that could be cool - but then also you couldn't use Xcode anymore, and so you end up in a similar space that Xamarin is in - where instead of just having xcode build, sign and package your app, everything is going through buggy wrappers and interfaces. I'm not sure how much of a win it'd be.

velraj said...

The information is good. I read this type of good article only. Good job.
Mobile Testing Training in Chennai
Mobile App Testing Training
Mobile Testing Training in Tambaram
Mobile Testing Training in Adyar
Manual Testing Training in Chennai
Drupal Training in Chennai
Photoshop Classes in Chennai
Mobile Testing Training in Chennai

Anonymous said...

Cross-platform applications developes using Xamarin are beneficial to maximize code re-use and deliver a high-quality native experience on all of the main mobile platforms including iOS, Android and Windows Phone.

Aishwarya said...

Somebody necessarily help to make severely posts I might state. This is the first time I frequented your website page and to this point? I surprised with the research you made to create this particular post extraordinary. Well done admin..
Mobile App Development Company In Chennai
Android App Development Company In Chennai
Android Application Development Company In Chennai
Mobile App Development Company In India

Anonymous said...

The article is so informative. This is more helpful for our
selenium training in chennai
selenium online courses best selenium online training
selenium testing training
selenium classes
Thanks for sharing

yaklibber924 said...

You made some respectable points there. I looked on the internet for the difficulty and found most individuals will associate with with your website. online gambling casino

Vengatesh said...

This is really helpful and informative, as this gave me more insight to create more

ideas and solutions for my plan.keep update with your blog post.

Website Design Company in Bangalore
Website Development Company in Bangalore

Amit said...

Thanks for posting this info., its is very helpful for all of us.keep update with your blogs.


Ecommerce Website Design Company in Bangalore
SEO Company in Bangalore
ERP Software Companies in Bangalore
CRM Software in Bangalore

Wxit Consultant Services said...

Thank you for sharing your thoughts and knowledge on this topic. This is really helpful and informative.

If you want to make custom website & application you can contact us on our Mobile App Development Company and Android App Development Company and grow your business also than touch with Search Engine Optimization Company anytime.

sharan said...

very good post!!! Thanks for sharing with us... It is more useful for us...
Microsoft Windows Azure Training | Online Course | Certification in chennai | Microsoft Windows Azure Training | Online Course | Certification in bangalore | Microsoft Windows Azure Training | Online Course | Certification in hyderabad | Microsoft Windows Azure Training | Online Course | Certification in pune

John Smith said...

this information is very useful for me iPhone app development company

Unknown said...

Thanks for this amazing post.
It is very much helpful in my business named Widle Studio which is based in Florida, United States. Our Flutter App Development Agency is the serving customers with creative solution.

rajmohan1140 said...

Learned a lot of new things in this post. This post gives a piece of excellent information.

Java Training in Chennai

Java Course in Chennai

John Steve said...

I hope I can find a Native mobile app builder that be easily used to build mobile apps rather than coding. However, coding apps is a skill that not many can achieve.

Erma Winter said...

I would like to thank you for the efforts you had made for writing this wonderful piece of writing.

Read the Blog: React Native App Development
Cost To Develop Ecommerce Mobile App
Full Stack Web Development Tools

harley said...

Yes, Nowadays mobile application is an Important one, This blog is more informative. Thank you For sharing your knowledge About react native app development company.

daisoftware said...

That's indeed a very detailed list of blog commenting websites.

on demand mobile app development

John Bell said...

Well explained article. To support native app development I would also like to share, Native mobile app development is comparatively more secure, more interactive, intuitive and tends to have fewer bugs during development. This shows the scope of native mobile app development. A debt of gratitude is in order for sharing this - Top Mobile app development company in the USA, in order to do business by developing a new native mobile app.

Rahim Ladhani said...

Thanks a lot for sharing this amazing blog with us. Please keep sharing such a great piece of an article so we can get more knowledge about this type of topic. Know What is the Advantage of the Xamarin App development Platform?

Technogiq IT Solutions said...

Hi, writer has done great job, I really thank you. ios app development services

Jessica morris said...
This comment has been removed by the author.
Lucid Outsourcing said...

Thanks for sharing valuable information about Native iOS and Android Mobile Apps. If you are looking for a Mobile App Development Company In India then you can go with Lucid Outsourcing Solutions. They have a team of experts in the Design and Development of Native Mobile Apps.