After years of publishing on Medium, I’ve decided to add a proper blog to this site. It felt right to have a space that’s fully mine — no algorithm, no paywall, just writing.
What this blog is about
My focus is Apple platform development: Swift, SwiftUI, the frameworks that ship with every new iOS and macOS release, and the product thinking that goes into building apps that feel human.
I’ll write about things I’m learning, patterns I find useful, and mistakes worth documenting. Occasionally I’ll share notes on design and the philosophy behind building things that matter.
A taste of what’s coming
Here’s a Swift snippet to kick things off — a clean way to debounce an async task using Task:
import Foundation
actor Debouncer {
private var task: Task<Void, Never>?
private let duration: Duration
init(duration: Duration) {
self.duration = duration
}
func schedule(_ operation: @escaping @Sendable () async -> Void) {
task?.cancel()
task = Task {
try? await Task.sleep(for: duration)
guard !Task.isCancelled else { return }
await operation()
}
}
}
// Usage
let debouncer = Debouncer(duration: .milliseconds(300))
// Inside a view model
func onSearchQueryChanged(_ query: String) {
Task {
await debouncer.schedule {
await self.performSearch(query)
}
}
}
Swift’s structured concurrency makes this pattern much cleaner than the old DispatchWorkItem approach. The actor ensures safe access to the stored task, and Task.sleep(for:) uses the modern Duration type introduced in Swift 5.7.
A note on Shiki
The code block above is highlighted at build time using Shiki, which means zero client-side JavaScript for syntax highlighting. The theme automatically adapts to your system’s light or dark mode preference.
More posts coming soon.