A hopeful shift
I believe there is still “some” degree of innovation in both Android and iOS platforms with each release. However, software companies can’t seem to keep the pace, and not all developers know what’s new, as I mentioned on my Futuro até quando? blog post.
The mobile applications market has stagnated. The competition reached a point where even multi-million dollar companies or highly funded startups hardly have a chance to have their apps discoverable in the app stores, let alone achieve the top 10 of most downloaded apps.
The return of investment for most companies in regards to their mobile apps is probably low, especially when such apps do not take full advantage of what mobile brings to the table. As my former lead Rui Teixeira once told me, “mobile apps are now a commodity”, meaning that apps are part of a product’s offering but not really the core of their strategy.
A cross-platform solution
The current state of the industry has led to an increasing number of companies adopting cross-platform solutions, and my current employer is no exception. As a result, I have now worked in react native for two months.
I can see some interesting technical benefits (fast refresh, testing tools) in our current solution, and how it seems to fulfil every business’s dream of “Write once, run anywhere” even though that’s not what Facebook endorses.
My little experience with React Native has shown me that some transitions between screens were not always consistent between platforms. That some screen states were hard to manage because the state was reused in previously closed screens, and some react hooks made things harder than they were supposed to be. Plus, there were situations where certain HTML elements could have (and had) properties that only existed in one of the platforms.
To be fair, the first two issues were probably an implementation problem and not a react native limitation. But it shows how easy it is to go over fundamental mobile constraints when you develop and test in one platform but deploy for several at the same time. I dreaded moments of “it works on android but not iOS”, but to be honest, in a “component-oriented” project, once these were implemented and properly tested, issues tended to be quite rare.
In regards to the user experience, the UI had to be considerably toned down and made blander to ship a less platform focused and more “generic” UI. You would argue that React Native enables us to have a dedicated UI for each platform, but if that were a requirement, you probably wouldn’t have adopted React Native in the first place.
The same applies to the argument that you can leverage the native modules and import native code. React Native indeed provides a way for you to do it, but I would argue most teams will try to use existing 3rd party React Native libraries that offer the same functionality since most projects will not have access to native engineers that can implement that native code. Plus, let’s not forget the cost of its maintenance in the long run.
Adopting React Native also brings the possibility of hiring full-stack developers to work on the mobile world. However, the resulting product will most certainly have an impact on your app’s user experience because not all these developers know the constraints and expected usability that a mobile environment requires.
A choice to be made
Budget, hiring, maintenance, long term strategy and the nature of the product itself, matter more than any opinion you can read on the internet or hear in the corridors of your office.
I am sure cross-platforms solutions like React Native, have its place in the market, and a lot of companies would do a right decision by adopting it, but I don’t think it is the solution for the future and to some extent even the present, of a lot of mobile apps. But for the sake of it:
Cross-platform is a valid option if either:
- Your app is just an extension of a bigger product offering;
- Your app is only used a couple of times a month;
- You need to hit the market on all platforms as soon as possible.
When it comes to native, it should be preferred if either:
- Your app is used every day;
- Your app has a complex, elaborate and dedicated user experience;
- Your app is at the core of your product offering (ex: Monzo, Todoist, Uber)
- You have high technical requirements (ex: performance, app size, etc.).
As a user, ask yourself. Can you tell the difference in experience between native and cross-platform apps? Probably not when it comes to Facebook apps, but I wonder about all the others.
A Xamarin experience
Debuted in 2011, Xamarin sits near PhoneGap, React Native and so many others in the fight between native and cross-platform. Although that is technically correct, there is a significant distinction to be made.
Old school Xamarin was cross-platform in the infrastructure and business logic but not in the UI layer. For the UI layer, you would have to know the Android Framework and C#, which meant that as an android developer, I was not able to develop an iOS app. Cross-platform UI became possible only later on with the arrival of Xamarin.Forms.
This distinction between UI and business logic is an important detail because it enabled unusual team structures.
In the second year of my first professional experience, back in 2014, I was assigned to develop a mobile app for a client. This client wanted to distribute an app to its partners as quickly as possible, without spending time creating a middleware that could serve as an intermediary between its .NET core product and the app.
Xamarin was a great solution because it enabled us to reuse domain knowledge and import .NET business logic assemblies into our app. This integration made even more sense when the client’s developer joined the project to work solely on the business rules in the language he was the most experienced with, C#.
This structure made us architect the app in a clear separation between the android app (UI layer) and its business logic (a C# assembly). As the only person knowledgable of the Android Framework, I worked solely on the UI layer, the client’s developer on the business layer with vanilla C# and our intern, a CS graduate, would implement the local database in SQLite.
Xamarin was great because in theory, if the company decided to develop an iOS app the next year, it could merely plug in the business logic assembly and only implement the UI layer.
Unfortunately, it wasn’t all just bells and whistles. In the long run, we experienced many of the issues described by Pixplicity in their great Why we are not cross-platform developers blog post.
A new hope
Kotlin and Kotlin Multiplatform SDK have recently revived the cross-platform debate, with JetBrains promising the following:
Kotlin Multiplatform Mobile (KMM) is an SDK that allows you to use the same business logic code in both iOS and Android applications.
On another blog post:
The Android and iOS versions of an application often have a lot in common, but they can also differ significantly – especially in terms of their UI (…). At the same time, the application’s business logic, (…), is often identical. That’s why it’s natural to share some parts of an application across platforms while keeping other parts completely separate.
With KMM, you can (…) use a single codebase for the business logic of iOS and Android apps and write platform-specific code only where it’s necessary, to implement a native UI or when working with platform-specific APIs.
KMM has the same premise as Xamarin but with a key difference. There is a separation of concerns not only at a logical level but at a technological level as a whole. The business logic codebase can be imported in native projects, leveraging the best of both native and cross-platform worlds.
But more interesting than that, it is possible to initiate this transition to KMM incrementally and over time, by starting with a few business logic unit tests or small domain modules. The continuous and incremental migration from Java code to Kotlin without stopping development and deployment was, in my opinion, one of the reasons why businesses let Android developers proceed with the change from Java to Kotlin.
A glimpse into the future
By watching the past Kotlin 1.4 Online event, and later the iPhone 12 announcement and how “incredible” 5G will be, I have started to imagine how all of these technologies could come together.
Old are the days where iOS developers would mock Android developers for having to support so many form factors. The iOS devices landscape is becoming more diversified, and with it, greater care in usability is necessary.
New forms of interaction like Virtual Reality and Augmented Reality, are now becoming possible in low-end devices and companies are starting to look into these to push innovation in their products.
And so, I believe KMM can play a vital role in the future of mobile.
I envision a near future where most android and iOS projects will migrate their business logic and infrastructure to KMM. This migration would generate a new type of developer called Kotlin Mobile Developer.
Provided they know about the mobile environment and constraints, these developers would be responsible for implementing all the “mobile backend” in pure Kotlin. They would be responsible for:
- Defining the mobile domain model;
- Implementing the business logic;
- Implementing the network layer;
- Implementing the database layer and all its syncing algorithms;
- Managing the continuous integration and deployment of the app;
- Dealing with Security concerns;
- Defining all common interfaces/protocols for native platforms to implement in case of need to access specific platforms APIs;
Front-facing developers (Android and iOS) would then work closer to the design and research team and becoming even more specialised in providing a stellar user experience, leveraging all that native code has to offer. They would be responsible for:
- Implementing all the user interface;
- Creating more efficient and delightful animations;
- Exploring and incorporating VR and AR;
- Implementing accessibility;
- Leveraging the speed of internet connection like 5G to create new experiences.
- Implement the specific interfaces/protocols defined by the Kotlin Mobile Developers in case of need to access platform-specific APIs.
With this structure, each company now has the advantage of being able to hire developers that are familiar with vanilla Kotlin to develop a big part of their mobile apps. Whether they have a backend background, are interns or only computer science graduates, KMM removes the requirement of years of experience in one of the mobile platforms, further increasing the pool of possible candidates. As a consequence, the demand for both Android and iOS developers would become considerably lower.
Both Android and iOS developers would then work closely with Kotlin Mobile Developers in negotiating high-level APIs (interfaces and protocols) and domain objects that both UIs would use. This preliminary work would give the chance to mock these APIs on the frontend while the “mobile backend” is in development.
In parallel, this shift could also create a wave of fully implemented mobile .jar
s and Framework
s available for any 3rd parties to use. This shift would enable smaller companies without access to Android and iOS developers, to get one step closer to publishing their mobile apps, by outsourcing the UI layer to an external agency.
Final thoughts
A KMM solution brings back the parity issue between apps, which is one of the strongest arguments in favour of cross-platform UI tools. If this is an absolute requirement on your part, then it seems it is (or will be) possible to import KMM code into any frontend applications, including projects in React Native and Flutter.
So if in the lifetime of your project, you decide to move to a cross-platform UI solution, this migration will not require changing the infrastructure. In that case, the transition could be faster, safer and more focused given that the mobile “backend” is already complete.
KMM is not yet final, and there is a significant risk in adopting if your app is crucial to your business. There are a few signs from different companies moving to a KMM approach (Netflix included) which give me hope that a part of this vision will become true.
For the past months, I have been trying to figure out what will the mobile world look like in the near future. I have become depressed with the developer communities obsession with new architectures, companies betting more on cross-platform UI tools and an impenetrable app market.
But Kotlin Multiplatform brings me hope. A hope that there will be a higher focus on what matters.
The user experience.
PS: A special thank you to Luca Nicoletti for reviewing this article.