The Pursuit of the Cross-Platform Holy Grail. Part 1: Ionic

Kajetan
Level Up Coding
Published in
9 min readDec 28, 2020

--

Ionic column capital
Ionic capital | Photo by Yusuf Dündar on Unsplash

This is the first part of a series about finding the best cross-platform application development framework. The legendary Holy Grail to which you can pour wine once and then drink it anywhere. Today I’ll discuss the pros and cons of Ionic. I’ll try to be objective, but the amount of my time that this framework has wasted will make it difficult.

About me

I have been developing native Android applications since 2012. Until 2017 in Java, from 2017 in Kotlin. As part of my side projects, I also write Python scripts and websites, mainly in React with TypeScript. For several years, I have been testing various cross-platform technologies that would save me time and at the same time give me access to a new market. Although I know the Swift language well, I don’t feel like creating two native applications

About the series

Photo by James Coleman on Unsplash

I came up with the idea of the series after noting thoughts and experiences from experimenting with many multi-platform frameworks. I noticed that several points are not usually discussed. Secrets that aren’t shared by marketers and developers, but important enough to rethink the choice of a technology to use in your project. As it took a long time to collect them in one place, I decided to share them and hopefully save your time and help with making that decision.

The goal of the title pursuit is to find a framework that will first of all run on Android and iOS. Support for desktop software and websites would be an added advantage.

Each cross-platform framework works beautifully on all declared platforms… at conferences. This is the biggest problem you’ve probably realized, too. Displaying “Hello world from platform X” is not a big deal. And I don’t think anyone is falling for it anymore. I think that even in assembly language one could create such a cross-platform program. The problems start when we want to use such a framework at work, in a real project, on production. Access to native functions is a problem. API, databases, storage access, camera, microphone, decent control over the view, performance. These are the real challenges faced by this software.

Therefore, while testing various frameworks, I decided to write real, relatively complex apps that would use some of the platform-specific functions. Let’s go together on a journey in search of the Cross-Platform Holy Grail.

The Sweet Beginning

Photo by Paweł Czerwiński on Unsplash

I used the variant of Ionic with React and TypeScript. I tested the native builds mainly on Android. As it turned out later, it was probably the worst possible combination. But no spoilers.

The beginning with Ionic turned out to be very pleasant. I quickly built a sample application and launched it on the website and Android. Everything looked beautiful and seemed like a modern, native app. Aside from a few aspects of the Android app, I’ll come back to later.

As for performance, it was satisfactory, although at a later stage of work, when connecting to the database, dynamically loading content, and, above all, opening the soft keyboard, the application started to run quite slowly. After all, it’s just a website and JavaScript. I didn’t expect it to be blazingly fast.

Ionic has a lot of ready-made, nice-looking and consistent components. Styling is also much easier as we have CSS and/or SCSS at our disposal. This is definitely a big plus. Unfortunately, sometimes things can get problematic due to Shadow DOM.

One advantage over native programming is the ease of font management and creating visual themes. Other pros are hot reloading and the mighty chrome://inspect, which offers much more possibilities than the native application debugger. Generally, these are features of any framework based on web technologies.

As for the language (in my case, TypeScript), it doesn’t differ much from Kotlin and Swift, so it’s quite friendly to write in. The only downside (compared to native development) I experienced was the problem with refactoring and the lack of other smart tools. But I realize this is an IDE (Visual Studio Code) issue, so I am leaving this only as a note for folks thinking about switching from IntelliJ IDEA/Android Studio. However, I suppose that this point doesn’t apply to WebStorm.

The Forgiving Middle

Photo by Lenny Miles on Unsplash

The work was lightning fast and enjoyable. Until I started implementing platform-specific features. I could write an entire article just about that. if…else blocks checking the platform on which the application is running on is probably not the “write once run anywhere” idea. But I forgave Ionic. I saved a lot of time creating layouts. It’d take much. much longer to do it natively. Moreover, twice if I’d like to support iOS and up to three times if I’d also like a website. I thought to myself, “In return, I could spend A LITTLE more time on other things.”

So I focused on prototyping the website, hoping that adding Android and iOS support would take a few working days at most. After all, how long can it take to add the right plugins and implement simple interfaces, right? Well, that was a huge mistake of mine.

When I’ve almost finished my beautiful application in Ionic, it was time to come back to the topic of its implementation on the Android platform. Piece of cake. Connect the appropriate database management system, external storage handling, and other fundamental functions.

Additionally, there were a few things that had to be corrected. They didn’t work well from the very beginning but I trivialized them.

I’m ignoring the fact that the generated application in Ionic used Java. It was 2019, so two years after Kotlin was announced as the official language, nevertheless, I totally get that migration could be unprofitable. On the other hand, conversion mostly comes down to clicking one button in the IDE. Nevermind.

The first thing to fix was AndroidX, or rather its lack. As far as I can understand Java, I do not understand why the Ionic team did not give up the deprecated Support library. Similar to the migration to Kotlin, this also requires selecting only one option in the IDE.

The second feature of the application to fix was… black navigation and status bars. That’s too much… I remembered the first Android app that I started writing back in 2012. A lot has changed in this regard since then. First, you could set your own color, and now you can make it completely transparent.

The last thing is downright bizarre. The default Ionic application… cannot be closed with the back button. I’m not joking. You have to press the home button to exit the application written in Ionic. I don’t know how the Android team at Ionic could have missed that. As a side note, the code that manages the back button well in a WebView-based application looks like this:

override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}

And in Java:

@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}

To my eye, it doesn’t require expertise or a lot of time. If it’s not a bug but a feature, someone can enlighten me.

According to this thread, they still have this problem at the end of 2020.

The Bitter End

Photo by Dan-Cristian Pădureț on Unsplash

A few weeks later…

Plugin for writing and reading files from the SD card. It’s buggy. It creates files in an unknown location and gives you absolutely no control. Permissions issues on new Androids. A few days of searching failed to bring a solution. Probably this thread is related.

I also failed to fully connect the database on Android. But that was already the hopeless stage, so maybe by spending another few days it’d eventually work out.

Finally, let me summarize the three most important problems of the Ionic.

The Android application is generated. While this may be an advantage for web developers, programmers experienced with native development will feel that their hands are tied. It means that you can’t even easily fix the few basic functions I mentioned before. Sooner or later you’ll have to synchronize the project, and it’ll remove manually entered changes. The only solution I’m aware of is to write your own plugin. Plugin for closing the application? Plugin for making the status bar colored or transparent? Let’s respect each other’s time, alright?

Shadow DOM. The entire DOM is hidden behind Ionic abstraction. PERHAPS there would be nothing wrong with that. If only this abstraction layer was working properly and allowed full (though supervised, if you wish) control over DOM, HTML, and CSS. However, it’s not so. When I was working on the application, for example, it was impossible to programmatically scroll the page to the given element. The Ionic interface was buggy and direct access was blocked. For a developer, there is probably nothing worse than not having control over your own program. Especially in the name of something that doesn’t work. You can take a look at what others think about introducing shadow DOM to Ionic here.

In the introduction, I wrote that React, TypeScript, and Android is the worst combination for working with Ionic. Now I’ll explain why. In the beginning, Ionic supported only Angular. Consequently, most of the documentation is written for this framework. Moreover, there are plugins that are exclusive to Angular. There is no alternative. When I was writing the application, support for React was very poor. It was the same with Android. You can see at first glance, that iOS is the priority of the Ionic team. Poor React Support + Poor Android Support = Developer On His Own.

Rage Quit

No. It was too much. I wasted a few months on a framework that turned out not to be cross-platform at all. The only thing that worked was the website. Worst of all, the developers of Ionic took the programmers’ control over the project, treating them as kids, which led to the “all or nothing” approach. Were it not for those absurd errors, my application would probably already be released on Google Play and the Apple Store. But in this case… I chose the “nothing” option. I started removing Ionic from this React project. I even wrote a Python script for that. It’s available on GitHub by the way.

I decided to keep ReactJS (which is a great library), add Material-UI (which is another great library) and manually write Android and iOS apps to display this website.

I’ll write about stand-alone ReactJS as well as React Native as cross-platform technologies in the next parts of the series about the pursuit of the cross-platform Holy Grail.

Conclusions

Whenever something bad happens to me or I waste far more time than I should, I think to myself “at least I have a new experience.” It’s no different this time. I’m grateful to Ionic for changing my approach to application development and implementation of frameworks, libraries, etc. Now I’m much more skeptical and don’t take anything on faith, assumptions, and “it’ll all be okay” attitude. While working with other frameworks, I FIRST created the simplest prototypes of all functions (especially native ones). Only after that, I continued to work on the details.

Honest note

As I said in the beginning, I was working on the application in 2019. Perhaps by then, some of the things had already been fixed (although the forum threads mentioned earlier indicate something else). It’s also worth highlighting that some of these problems belong to Cordova/Capacitor. But Ionic doesn’t work without Capacitor, so it’s natural to put them together. Cordova itself won’t be included in this series of articles. With all due respect to this technology, while it can be an interesting base for other frameworks, it’s rather of little use on its own.

Afterword

If you find this article interesting and helpful, leave a 👏 and consider sharing your thoughts in the comments. Any kind of feedback will be appreciated.

What’s next

--

--