Office Hours Recap - December
From sleep-tracking hardware to SwiftUI rewrites, here’s what came up in December’s session.
I held Hotwire Native Office Hours last week at a special time for our friends in Australia, and it ended up being one of the most fun, wide-ranging sessions we’ve had all year. We dug into everything from Bluetooth sleep trackers to tab reloading strategies to whether going “fully native” is actually worth it.
Here’s a recap with the highlights and the lessons you can apply to your own apps.
A real-world Bluetooth integration with Hotwire Native
Adam Pallozzi kicked things off with a deep dive into a feature from SleepHQ: a pulse-oximeter ring that streams data through the phone overnight. It’s one of the most complex Hotwire Native integrations I’ve seen, a native Bluetooth service working alongside a Rails UI.
But there’s one issue Adam hasn’t been able to figure out just yet, iOS keeps killing the process during long background sessions, breaking the Bluetooth connection.
We talked through a few possible approaches:
Enabling the “Acts as a Bluetooth LE accessory” background mode
Using background processing or silent push notifications to keep the app alive
“Playing audio” to keep the web view from sleeping
This last one is interesting. Have you ever locked your phone to see audio playing on your Lock Screen? Even though you weren’t actually listening to anything?
Turns out, this is a trick hack to keep the web view alive! If done correctly, with all the right background modes, continuously playing audio can sometimes leave the web view alive indefinitely. Of course, it isn’t documented, and definitely not recommended, but it is an interesting idea for this scenario.
It was a great reminder that Hotwire Native doesn’t magically eliminate all native challenges. But it gives you flexibility to mix native services with a mostly Rails-driven UI. All five steps of the Bluetooth connection processes were rendered with HTML!
The tab refresh problem after authentication
Shawn asked one of the classic Hotwire Native questions: What’s the best way to refresh tabs after someone logs in or signs up?
Right now we have a few options:
Call
load()again on theHotwireTabBarControllerIdeally, iterate through each
Navigatorand manually reload themSadly,
HotwireTabBarController(yet?) doesn’t expose that
Add a “stale” flag so the tab refreshes the next time it appears
Adam shared how Sleep HQ tackles this by reloading the entire path configuration when users switch between “patient” and “clinician” modes. It works, but it’s heavy-handed. On Android, there’s an additional constraint: you simply can’t have an unlimited number of tabs.
For Jumpstart Pro, we’ve moved away from path configuration for tabs entirely. Instead, we send a dynamic JSON structure down to a bridge component, the same approach I outlined in my authentication deep dive. It gives you control without rebuilding the whole navigation stack.
“Do you have a starter kit for new apps?”
Jesse asked whether there’s a Rails + iOS + Android template that people can use as a starting point.
And I’ve tried… many times. Six, at least. Templates are great until they aren’t! They fall out of date the moment Rails or Hotwire or Xcode moves forward.
The pattern that has consistently worked for me is:
Keep a repo with multiple branches representing different “starting points”
Write generators that you run after creating a new Rails app
This gives me 90% of the value of a template without locking into something brittle.
Going “fully native” vs staying with Hotwire Native
I also shared a little experiment I’ve been working on: I rewrote the hiking app from my book in pure SwiftUI. The goal was to compare the experience head-to-head.
Here’s what I learned:
Visually, the difference is tiny, in many cases you couldn’t tell which is which
The native version requires significantly more code
Error states and loading transitions are easier to customize natively, but not enough to justify the effort unless you truly need it
Mixing in native screens when necessary (e.g., Bluetooth, camera, biometrics) is still the sweet spot
In other words: if you’re building an app whose UI comes from Rails anyway, Hotwire Native continues to be the fastest path, even if you know SwiftUI well.
We also talked about custom loading and skeleton screens. You can do this by inflating JavaScript-driven views early, or by putting the whole app inside a Turbo Frame remote and swapping in real content after it loads. Adam shared a clever technique where he checks whether a page is cached before showing the skeleton, avoiding the “flash” when navigating back.
A great way to wrap up the year
This session had everything I love about office hours: real problems, real apps, and everyone openly sharing what’s worked (and what hasn’t). Huge thanks to Adam for the Bluetooth demo, to Shawn and Jesse for great questions, and to everyone who joined from far-off time zones.
The next session is scheduled for January 8, 2026. I hope to see you there!





