<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="tim4tech.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="tim4tech.github.io/" rel="alternate" type="text/html" /><updated>2026-09-23T21:34:35+00:00</updated><id>tim4tech.github.io/feed.xml</id><title type="html">💭 by tim</title><subtitle>opinions, bike stories, mobile development</subtitle><entry><title type="html">micgrw 🌱 - 2025 State of the Union</title><link href="tim4tech.github.io/micgrw/mobile/development/2025/12/10/micgrwSOTU25.html" rel="alternate" type="text/html" title="micgrw 🌱 - 2025 State of the Union" /><published>2025-12-10T08:18:47+00:00</published><updated>2025-12-10T08:18:47+00:00</updated><id>tim4tech.github.io/micgrw/mobile/development/2025/12/10/micgrwSOTU25</id><content type="html" xml:base="tim4tech.github.io/micgrw/mobile/development/2025/12/10/micgrwSOTU25.html"><![CDATA[<h6 id="️---8-minutes">⏱️ - 8 minutes</h6>

<p>As we round out the end of the year, I wanted to take a second and recap the current state of micgrw as well as detail what I will be working on in the future!</p>

<h2 id="since-launch-">Since Launch 🚀</h2>

<p>After a whirlwind of last minute changes, new microgreen types, and press (crazy, right?), I was able to hit my self-imposed and pseudo-random launch date of September 6th! Since then, 48 users from all over the world have signed up and grown microgreens using micgrw. I’m thankful for these early users and their valuable testing and I am excited to deliver more features to make the growing process easier.</p>

<p>I’ve only shipped one update since September: support for liquid glass/iOS 26 and some bug fixes that severely impacted usability. Beyond that, I was pretty burnt out from the effort it took to get the app on the App Store and needed a break. Recently, I’ve gotten back in the game though and so here’s what I’m working on!</p>

<h2 id="push-notifications-">Push Notifications 🔔</h2>

<p>One of the missing features from launch that bothered me the most was push notifications. There are many cases where a little awareness could mean life or death for the little greens and any good app should have a thoughtful approach to giving you that nudge. I’ve actually had the app-side infrastructure set up to make notifications possible for a while. However, since micgrw has been so focused on the app half of things, I did not have the necessary backend in place to send the notifications.</p>

<p>After thinking through different approaches, I have the following plan to add notifications to micgrw.</p>

<h4 id="1-lenient-timing-notifications">#1: Lenient Timing Notifications</h4>

<p>To begin, there’s a class of notifications that don’t require a user be notified at an exact time. For example, when germinating a tray of greens, it is more than sufficient to ping the user to check the greens towards the end of the expected blackout period. The timing of ending the germination phase and beginning leaf development already has enough wiggle room between temperature, green type, moisture conditions, and more that sending this notification within a couple of hours is more than sufficient.</p>

<p>The service that sends this notification is fairly easy to design and low cost to run: a Cloud Function that will check a list of notifications that are queued on a regular interval (every couple of hours?), scheduled by a cron job, checking if each is ready to be sent to the user’s device.</p>

<p><img src="/images/2025-12-10-micgrwSOTU25/notification_arch.png" alt="example soak notification" style=" width:auto; max-width:100%; border-radius:20px; box-shadow:0 14px 38px rgba(0, 0, 0, 0.16); display:block; margin:0 auto 28px;" /></p>

<p>Why a separate notification queue instead of just introspecting the grow model itself? I want to allow users to have granular control over which notifications they choose to receive in avoidance of a common sub-par experience: apps that bombard you with notifications you don’t want. Keeping this separate queue is a convenient way of tracking whether or not to send a notification. If the service relied on checking the grow model, it would then also need to hunt down the users notifications preferences and check whether or not to fully push the notification. With the separate notification queue, the service knows that if there is a notification scheduled, it is free to fire away, no need to check any other models. Separation of concerns!</p>

<h4 id="2-precise-timing-notifications">#2: Precise Timing Notifications</h4>

<p>The next class of notifications I intend to add are those that must be sent at a reasonably precise time. An example of this would be a notification that a batch of seeds is nearly done soaking. Given the soak process is around 8 to 12 hours, getting a nudge that the seeds are almost ready to be trayed would prevent over-soaking, which can lead to mold or poor germination rates.</p>

<p><img src="/images/2025-12-10-micgrwSOTU25/notification_example.png" alt="example soak notification" style="max-height:120px; width:auto; max-width:100%; border-radius:20px; box-shadow:0 14px 38px rgba(0, 0, 0, 0.16); display:block; margin:0 auto 28px;" /></p>

<p>The architecture of this could take multiple approaches. On the one hand, I could keep things drop-dead simple (<a href="https://en.wikipedia.org/wiki/KISS_principle">KISS</a> anyone?) and just crank the cron job to 11, say running it every hour or even every half hour. Given how cheap Cloud Functions are to run, this isn’t actually that terrible of an approach but I don’t love it, primarily because it feels sloppy 😅. However, the benefits of implementing a more precisely scheduled notification mechanism might not overcome the cost of designing and building a different service. I will figure this out closer to implementation. 🫡</p>

<h4 id="3-on-device-notifications">#3: On-Device Notifications</h4>

<p>There is a sneaky third type of notification that needs consideration: on-device notifications for actions that require near-immediate action. The primary example of this would be the sanitization process. Soaking seeds in an agent like hydrogen peroxide, vinegar, or bleach is an action that takes minutes at most. Scheduling a push notification doesn’t really make sense because the user should barely be leaving the app during this process, let alone be far enough away to need prompting by a notification.</p>

<p>The solution here, at least on the iOS side, is a live activity not so different from the built-in Apple timer app. I actually worked on this over the summer but had to set it down in favor of more pressing core features. I’ll be excited to get it working though, the soak/sanitize process is the most disappointing part of the grow flow in my mind and I would like to make it easier to understand the sequence of events as well as capture more detail for later analysis.</p>

<h2 id="android-support-">Android Support 🤖</h2>

<p>The other large chunk of work is making an Android version of micgrw. I’m no stranger to making iOS and Android apps with feature parity, but micgrw being a personal project changes the rules a bit about how and when this gets done. So here’s the plan…</p>

<h3 id="overall-options">Overall Options</h3>

<p>micgrw for iOS is a native SwiftUI app, an intentional choice. I am a strong believer that native apps are more valuable than their cross platform friends; the experience native apps deliver matches the OS, there are less strange UI side-effects, and performance is nearly always better. I don’t intend to back down on this front, so cross-platform UI frameworks like React Native (gross), Flutter (admittedly cool), and Kotlin Multiplatform Compose (also cool) are reasonably out of micgrw’s picture.</p>

<p>However, I’m just one guy and writing two full apps with full duplicate UI, logic/business, and data layers is also out of touch from a feasibility standpoint. A plan to share some of the codebase is critical to realize bringing an Android app to the Play Store.</p>

<h3 id="specific-stipulations">Specific Stipulations</h3>

<h5 id="feature-depth-and-the-argument-against-parity">Feature Depth and the Argument Against Parity:</h5>

<p>One of the main concerns I’ve had with starting an Android app (spoiler: I’ve already started but there’s A LOT of work to go) is this: it doesn’t help to have an app for each platform if the feature set for those apps don’t benefit their users. Do I think micgrw is a helpful tool when added to the microgreen growing process? Yes! Do I think other users who aren’t dogmatically engrained in building micgrw get as much value as me? No! I would like to solve this dichotomy, ideally before putting in 2x work across both apps. I think that while a lot of the structure is in place, there are many ways I could manipulate the very data-driven nature of micgrw to be more informative and useful for beginning growers, while still providing “power growers” with useful insights into their process. In my mind, it makes sense to iron these kinks out on iOS once before building them in the Android sphere.</p>

<h5 id="living-in-the-golden-age-of-swift-and-waiting-to-take-advantage">Living in the Golden Age of Swift (and waiting to take advantage):</h5>

<p>As discussed above in the “Options” section, I want to stay away from cross-platform UI frameworks, but that doesn’t mean I can’t reuse code at all. I could go super low-level and rewrite the business/data layer I have in iOS in something like C, but I’m a modern man and writing C just isn’t exciting in my free time unless it is being flashed to some embedded device. However, an exciting and incredibly recent development is Swift releasing <a href="https://www.swift.org/blog/nightly-swift-sdk-for-android/">Swift for Android</a> which is exciting for a guy who has a ton of Swift logic he wants to load into the Android world. This library being in early infancy has challenges though and I’m concerned that I’ll spend more time fiddling with build environments than actually building the apps at this point.</p>

<h5 id="staying-sane-">Staying Sane 🧘:</h5>

<p>Mental stamina is a bit like an aquifer: sometimes it’s being charged, sometimes it’s static and seasonal, and sometimes it drains at a rate that surpasses refill (a very western US analogy I know). The wall I hit after launch was tough, it was frustrating to not only be burnt out on my own project, but to go to work and struggle to focus and perform there. While the personal frustration is just that, being unable to perform at my day job puts a damper on my whole livelihood. In essence, whatever micgrw development I do next must fit in the constraints of keeping mind and body happy. This looks like a lot of things: making microgreen video content for variety sake, getting out on my bike more, taking breaks when needed, and making sure that whatever work I’m doing is “fun” so that it feels like less of a burden.</p>

<h3 id="outcomes">Outcomes</h3>

<p>Overall, the most likely outcome is the following: I will focus on dialing in the existing feature set + notifications, move my architecture in a direction that will play nicely with Swift for Android, and preserve my joy for micgrw development. In time, Swift for Android will be ready for production usage and my architecture will be prepped and ready. This will allow me to get the business/data layer of the iOS app “for free” on Android, and the UI will follow easily! I had originally promised Spring 2026 as the timeline for this work, I’m not sure if that is still realistic.</p>

<h1 id="in-parting">In Parting</h1>

<p>Thanks for reading my rambling summary of the future of micgrw, if you have thoughts Twitter is a great place to blast them at me and I’d be excited to hear what they are. Anyway, go grow some microgreens, have a salad, and I’ll see you in 2026!</p>]]></content><author><name></name></author><category term="micgrw" /><category term="mobile" /><category term="development" /><summary type="html"><![CDATA[⏱️ - 8 minutes]]></summary></entry></feed>