RSSTracker Retrospective
Mounir Nessim
Over the last few months, I’ve undertaken a fairly substantial programming project: writing a cross platform mobile app with Kotlin Multiplatform. Up until now, I have done some relatively small projects, like my Chess Picker Go webapp, or my small Music Theory API and Demo in C#. I’ve hopped languages a ton and had a relatively hard time committing to something. Then again, as a hobbyist, I’ve been lucky not to have to commit to anything. I have a day job that pays the bills, so I’m free to try out all kinds of goofy programming languages without worrying too much about the job market.
That being said, there’s always the idea in the back of my mind that I might one day like to try to apply for developer jobs. I landed on mobile as a niche to target for a few reasons:
- Real tangible outcomes
- Prevalence of mobile devices
- No JavaScript!
- Something totally new for me to learn
I now have a relatively functional mobile app that works on Android and iOS, as well as a pretty stable Rust backend that polls about 200 RSS feeds and stores articles. It was a long and winding journey to get here, and I plan to write a handful of posts to reflect on the process. In this post, I want to talk about some of the broad, high level challenges I faced.
KMP vs Flutter
I knew from the outset that I wanted to build a cross platform app. The two major options for this were React Native or Flutter. I’ve done a bit of React for web before, and quickly ruled that out. Flutter was a breath of fresh air in many ways, and quite delightful. So how did I end up using the much less mature Kotlin Multiplatform?
While I enjoyed Flutter, especially how much it “just worked,” I found my code
quickly getting disorganized. State management was a particular pain point. I
started with StatefulWidget before eventually moving over to Riverpod, but I
found refactoring to be a nightmare. Was this my own fault? Certainly.
Nevertheless, I began to look into KMP as a possible alternative. I knew Kotlin
was the preferred Android development language, so I figured even though KMP is
young, it’s probably still useful to know for Android.
It turns out that state management is far more intuitive in Kotlin with the
remember functions, built-in ViewModel classes and other features.
Additionally, Kotlin gave me a lot more friction. Gradle is an absolute
nightmare to deal with, but it caused me to slow down and actually seek out
resources to better understand what was going on.
The Compose UI framework is also super easy to use and intuitive, much like Flutter. I’m certainly no UI wizard, but I found it generally pretty easy to translate ideas and concepts over from Flutter to Compose. Even more new and young than KMP itself is shared UI with KMP across iOS and Android. Nevertheless, I decided to go for it. It felt like a bit too much to learn SwiftUI as well, but I might consider it in the future.
Newsapi.org
From the beginning, I wanted to basically track the news and have users get updates when there are new results. The idea came from my dad, who wanted me to help set up updates for research related to a particular health condition that a family member has. While it’s quite simple to set up a Google alert, it gave me an idea for a project.
As I was learning the basics and getting an MVP going, I turned to newsapi.org as a quick and easy way to get the actual news results. I knew that using it in production would probably cost a bit of money, but I figured I’d cross that bridge when I got there. Well, before long I got there, and I realized that the minimal production plan with newsapi.org costs a whopping $449 per month. That is absolutely a nonstarter.
After looking around at other APIs, I didn’t find anything that fit my budget and my needs. Eventually, I took the plunge and wrote a custom backend to poll a bunch of RSS feeds to get articles. It was quite a sidequest in this journey, maybe worthy of a dedicated post. In the end, though, I wrote a backend in Rust that polls 200ish feeds every 15 minutes for new articles. At time of writing, my database has about 65,000 articles in it. It also rotates out articles every 30 days, as my infrastructure is not unlimited.
While it worked out in the end, it was certainly a big obstacle that nearly derailed this whole project.
Apple
One big surprise that I probably should have seen coming was the need for Apple hardware in order to build and test for iOS. I’ve done some cross compilation between Windows and Linux for various things, and I foolishly just assumed that there was some way to do so for iOS. Well, it turns out there is not. There are some options like using cloud compute solutions, but I decided to just take the plunge and buy a MacBook Air.
It turned out to be a good decision overall, not just for access to Xcode for building. MacOS is much closer to Linux than I realized, which brought with it a lot of comfort for setting up my environment. Apple silicon chips are also quite impressive. I’m not a hardware geek, per se, but it has been pretty impressive what a MacBook Air can accomplish.
I also purchased a used iPhone 13 SE for $80 to test on an actual device. It’s a lot of investment for what is ultimately a hobby project, but the MacBook has basically become my main device for everything outside of gaming. I found several Apple specific bugs only by testing on an actual iPhone.
What’s Next?
As with many hobby projects, it’s tough to get across the finish line. Fortunately, in this case there is a clear goal: getting the app on Google Play and the Apple App Store. Unfortunately, that’s easier said than done. My current hurdle is getting enough closed testers on Android (it turns out most people I know are on iPhones!). There are a million extra features that I could add, as well as lots of improvements, no doubt. I feel it’s time to move on from this project, though. I’ll continue to try to get it across the finish line, write a few more posts about the experience, then simmer on some new ideas.