Can confirm. When I don’t cut mine for an extended period of time bc I’m lazy it looks pretty bad.
@will-lumley
Mainly a senior iOS engineer, but love to dabble in web development and robotics/embedded-systems in my spare time. Father to four amazing children, and husband to a beautiful wife. Checkout my stuff: https://lumley.io http://github.com/will-lumley/
Can confirm. When I don’t cut mine for an extended period of time bc I’m lazy it looks pretty bad.
I went down a couple of dead ends before finally arriving on the ESP32, so all in all it took about 3 weeks.
But only just taking into account the current approach on the blog, it took me about about 1 week.
My old garage remote died, so instead of replacing it I turned the whole thing into a HomeKit-powered smart garage opener using an ESP32, a relay, and about $20 of parts.
It’s fast, fully local (no cloud), and way more fun than buying a new remote.
How I built it 👇
lumley.io/blogs/smart-...
let's express gratitude to the amazing people who selflessly shared their priceless wisdom with us: @danielchooper.bsky.social, Jinkai, @useyourloaf.com, Tjeerd in 't Veen, @jacobstechtavern.com, Bruno Valente Pimentel, Alfonso Tarallo, @massicotte.org and @will-lumley.bsky.social
Hard agree. Combine deserved a graceful evolution, not quiet abandonment. Even a small set of first-party bridging tools or async-friendly operators would’ve gone a long way toward easing the transition.
My talk from ServerSide is up!
Fair question! And a common gotcha I've had with AsyncStream.
In this case it’s fine, as each call to stream() creates its own independent AsyncStream/Continuation pair, and the actor fans out values to all registered continuations when send(_:) is called.
So yeah it’s multi-subscriber safe :)
Why make this?
Because observing an @Observable class from a SwiftUI view is easy, but doing the same from another ViewModel got messy fast. Without @Published, you’re left juggling Tasks and AsyncStreams just to stay in sync.
🚀 New blog post!
AsyncCombine: Because Async Code Shouldn’t Be Ugly
I brought back Combine’s sink, assign, and CombineLatest - but built powered by Swift Concurrency.
Observing @Observable from another ViewModel shouldn’t be painful.
Here’s how I fixed it 👉 lumley.io/blogs/async-...
so i wrote a thing about stubbing URLSession based on a 'trick' i discovered the other day jellystyle.com/2025/09/stub...
iOS Dev Tip 💡
Easily monitor the device’s thermal state to optimize performance during overheating.
→ learnandcodewithenid.com
Making this argument and then hanging the entire load on TRY is fucking hilarious:
💡Starting with iOS 18.0, you can create mesh gradients in SwiftUI using MeshGradient.
→ learnandcodewithenid.com
FaviconFinder by @will-lumley.bsky.social is awesome!
github.com/will-lumley/...
Thank you for the shoutout @weijianduan.bsky.social! I’m really glad it’s managed to help you :)
There is a convenient brightness(_:) modifier in #SwiftUI that can be used to adjust the intensity of colors in our views. We can lighten the colors by passing it values from 0 to 1 or darken them using negative values:
nilcoalescing.com/blog/AdjustT...
1517, Martin Luther
it’s forbidden in their culture but a vacuum cleaner wants nothing more than to eat it’s own cord
Why I 💛 the web.
#macOS menu bar app that shows how full the ISS urine tank is in real time. 🛰️🚽
Yurnining to check this out.
github.com/Jaennaet/pIS... #Swift
*click* React Native. *click* Flutter. *click* .....SwiftUI. *click* GTK. Easy. *click* ......Qt6.
How embarrassing! Maybe it’s just an issue on my machine then 💀
CMD+Space doesn't bring up Spotlight anymore and this has ruined my opinion on macOS and life.
How so?
Completion > perfection
With #swiftlang It's easy to forget that the diff between a point-free and pointed styles of function argument passing is not just syntactic but semantic. It's normal to consider these to be equivalent:
1. [1, 2].map(String.init)
2. [1, 2].map { String($0) }
But we shouldn't forget that: 1/4
Do you know about the take function for the Optional type? It takes the value if it is not nil and toggles the variable to nil.
https://buff.ly/3Zin2Wv
I've always just used GPT-4o, but will give o1 a try after this. Keen to see the difference.
A problematic little #swiftlang pattern I often see is "unwrap-then-nullify" for optional values that hold some temp state. This oft comes up when dealing with local caches or scrollOffsets or in-flight tasks, etc. Forgetting to nullify a value to "reset" state is a common mistake. Use take method.