macOS CI on a budget
Have you ever dreamed of having your very own macOS CI? Perhaps a free one would be beyond your wildest imagination. What if I told you that, with a little effort, it is possible?
I'm a native iOS developer and formerly a strong opponent of any non-native development. However, as the new frameworks arrived, they’ve completely redefined what cross-platform development is. Of course, I’m talking about the React Native and the Flutter frameworks. In this article, I want to share my own experience with the full cycle of development of two apps. Both developed from scratch to the final release using these frameworks. In the end, I’ll offer some thoughts and conclusions about these technologies from my perspective.
To make this article easier to read, I broke it up into three parts. This part goes over the reason I’ve started this “experiment” and my first ever React Native experience. Part two goes over my experience with Flutter and it’s pros and cons. In part three I will compare these two frameworks based on my own experience and we will discuss what platform to chose in different scenarios. Without further ado, let’s get started!
As part of my Indie developer career, I have a bunch of apps: one of them is a Weekly Schedule Planner for students. This application is quite popular among students, but one crucial part was missing. Within my role as a native iOS developer, I was unable to make any production quality app for the Android platform, so I started my own journey. My goal was to find all possibilities to deliver my application to the Google Play Store and seek a future solution.
As a native developer, my first thought was to learn the Android native development and create a second native app. The problem with this solution is that, as an Indie developer, I can't afford to spend that much time developing and maintaining two applications. In turn, I started to look for alternatives. Luckily at this point, I stumbled upon the React Native, which had a ton of buzz around it. At the time, Flutter was already available as the early beta, but the technology was very little known. On the other hand, React Native was a much more mature and industry-proven framework, so I decided to give it a try. The plan was to develop an Android version of my class timetable application using the React Native. I even thought about replacing the native iOS version with this cross-platform solution, this wasn’t the case unfortunately.
Please note that everything mentioned in this article reflects solely my personal experience with these platforms. Your experience may vary depending on your needs, contexts, and backgrounds.
As a brief overview, React Native is the technology that uses real native components on both platforms and controls them using JavaScript code. Thus, you only write your code using JavaScript once for both platforms. Yet, you can still write and call the native code from the JavaScript counterpart using the appropriate wrappers. So when you utilize a button component somewhere in your JavaScript code, it creates the native Android button on the Android and the native iOS button on iOS. That's what React Native is in a nutshell.
I decided to start my journey with React Native by taking a random top-rated Udemy course to obtain an overview of the technology. I accomplished it in roughly a week. The initial impression was pretty good, and the technology was quite promising in meeting my needs, so I decided to start development.
And that's when it got serious. First, I’d like to talk about the problems. The initial setup was painful. Even recently, during the transition to a new computer, it was a mess. If you don't have previous experience in this area, you can spend a whole day just trying to figure it out.
After the initial setup, the second thing that shocked me was the number of dependencies that React Native had: to be exact, more than 500. This is the reality in the JavaScript world. It was interesting regarding all these dependencies that I haven't faced any problems with them so far.
When the painful setup was done, it was time to start a real development. As I started to recreate my iOS application, everything went smoothly until I started to work on the navigation.
React Native has no official built-in navigation. Just pause and think about it for a second. You have to use a third-party solution for this. I’d separate the existing React Native navigation libraries into two types. Some libraries recreate the navigation by imitating it. The most prominent library of the first type is react-navigation. At the time I was working on my application, this one was the recommended way to go. And secondly, there are wrappers for the real native navigation and most prominent library for this is react-native-navigation.
I started with the first one, but soon enough I encountered many problems. Most of them related to application performance, so I decided to switch to a more advanced react-native-navigation library. The setup for this one isn’t as trivial as importing a dependency. Fortunately, they provide nice documentation for the library. After the switchover, the development process started to shine once again.
From an architectural point of view, the most common way to develop a React Native app is Redux. I used it in my app, and it plays well with the React Native.
The last, but not least of my struggles involved the debugging. It works, but it’s uncomfortable. The main pain point is that you need to use the Chrome debugger to do this. There are some third-party solutions to make debugging more convenient. Even so, you still need to have an application, other than the IDE, to debug.
For a complete picture, I’d like to mention the arduous process of updating the React Native version. This is a real problem, you need to literally diff your version and a new one and manually update everything. Secondly, stability and performance aren’t as good as they can be with a native application, but in most cases, they’re quite acceptable.
Apart from the problems above, everything was smooth. Even without previous experience with React and JavaScript, development took no more time than I would’ve spent in my professional native field. The hot reload works nice. The downside is you still need to support it in your navigation stack; otherwise, you’ll end up on the initial screen of your app each time you reload. I also managed to find all the third-party libraries I needed, which was great.
Overall, I had a positive experience with React Native and fulfilled my goals, even taking into account all the difficulties.
As mentioned before, this is just the first part of this article. In the next part, I will write about my experience with Flutter, it’s pros and cons and why I chose it over React Native.
Have you ever dreamed of having your very own macOS CI? Perhaps a free one would be beyond your wildest imagination. What if I told you that, with a little effort, it is possible?
Microtask, Future or postFrameCallback, which one should I use?