Blog

Thoughts on software development, mobile apps, and building products and sometimes nothing in particular at all

Blog post: Search & Filter with Debouncing
May 19, 2026
5 min

Search & Filter with Debouncing

SwiftUI Patterns

Searching without debouncing fires API calls on every keystroke. Here's how to implement efficient search with task cancellation.

Read more
Blog post: Displaying Relative Dates
May 16, 2026
4 min

Displaying Relative Dates

SwiftUI Patterns

SwiftUI makes relative date formatting effortless. Show "2 minutes ago" instead of timestamps with a single modifier.

Read more
Blog post: Pull-to-Refresh with .refreshable
May 13, 2026
5 min

Pull-to-Refresh with .refreshable

SwiftUI Patterns

The .refreshable modifier adds native pull-to-refresh with minimal code. Here's how to implement it with async/await and last-refresh timestamps.

Read more
Blog post: ContentUnavailableView for Empty States
May 10, 2026
4 min

ContentUnavailableView for Empty States

SwiftUI Patterns

iOS 17 introduced ContentUnavailableView for showing empty states, errors, and search results. Here's how to use it effectively.

Read more
Blog post: Building Robust Lists: Loading & Error States
May 7, 2026
5 min

Building Robust Lists: Loading & Error States

SwiftUI Patterns

Every list needs to handle loading, success, empty, and error states. Here's the pattern that covers all four with clean, maintainable code.

Read more
Blog post: Modern SwiftUI Patterns
May 4, 2026
4 min

Modern SwiftUI Patterns

SwiftUI Patterns

SwiftUI has matured significantly. Here's what modern SwiftUI code looks like and the patterns we'll cover in this series.

Read more
Blog post: Actor Isolation in Unit Tests
May 1, 2026
5 min

Actor Isolation in Unit Tests

Testing Mastery

Actors provide data isolation, but testing them requires understanding how actor isolation affects your test code. Here's the pattern.

Read more
Blog post: Cache Behavior Testing
Apr 28, 2026
5 min

Cache Behavior Testing

Testing Mastery

Caching adds complexity to async code. Here's how to test cache hits, misses, and expiration with injectable TTLs and deterministic timing.

Read more
Blog post: Testing TaskGroup Operations
Apr 25, 2026
5 min

Testing TaskGroup Operations

Testing Mastery

TaskGroup lets you run multiple async operations concurrently. Here's how to test result ordering, partial failures, and concurrent execution.

Read more
Blog post: Testing Async/Await Methods
Apr 22, 2026
5 min

Testing Async/Await Methods

Testing Mastery

XCTest fully supports async/await. Here's how to write clean, reliable tests for your async code with mock services and error propagation.

Read more
Blog post: Building Testable Service Layers
Apr 19, 2026
6 min

Building Testable Service Layers

Testing Mastery

A service layer coordinates multiple dependencies. Here's how to design one that's easy to test with injected payment, email, and notification services.

Read more
Blog post: Verifying Interactions with Spy Mocks
Apr 16, 2026
5 min

Verifying Interactions with Spy Mocks

Testing Mastery

Your test passes, but did the right methods get called with the right arguments? Spy mocks let you verify interactions, not just outcomes.

Read more
Blog post: Mock vs Stub vs Fake vs Spy
Apr 13, 2026
6 min

Mock vs Stub vs Fake vs Spy

Testing Mastery

You've heard these terms thrown around. Here's what they actually mean, when to use each, and practical examples for iOS testing.

Read more
Blog post: Repository Pattern for Testable ViewModels
Apr 10, 2026
5 min

Repository Pattern for Testable ViewModels

Testing Mastery

The Repository pattern separates data fetching from your ViewModel, making both easier to test and maintain.

Read more
Blog post: Testing ViewModels with @Published
Apr 7, 2026
6 min

Testing ViewModels with @Published

Testing Mastery

Your ViewModel fetches data directly from URLSession. You can't test loading states, error handling, or verify the right endpoints are called.

Read more
Blog post: In-Memory File Systems for Tests
Apr 4, 2026
5 min

In-Memory File Systems for Tests

Testing Mastery

Build the in-memory file system that makes your cache tests fast and deterministic. No disk I/O, no cleanup, instant operations.

Read more
Blog post: Abstracting File System Access
Apr 1, 2026
5 min

Abstracting File System Access

Testing Mastery

Your image cache writes to disk. Tests create real files, run slowly, and leave artifacts behind. Abstract FileManager with a protocol.

Read more
Blog post: InMemoryKeyValueStore Pattern
Mar 29, 2026
5 min

InMemoryKeyValueStore Pattern

Testing Mastery

An in-memory store gives you complete isolation between tests—no cleanup required. Build the mock that makes UserDefaults testing deterministic.

Read more
Blog post: Why UserDefaults.standard Breaks Your Tests
Mar 26, 2026
5 min

Why UserDefaults.standard Breaks Your Tests

Testing Mastery

Your test suite passes. Then you run it again. Now it fails because the previous run left data behind. Abstract storage with a protocol.

Read more
Blog post: DateProviding: Control Time in Tests
Mar 23, 2026
5 min

DateProviding: Control Time in Tests

Testing Mastery

Build the mock that makes time-based tests deterministic. Test subscription expiration, 7-day reminders, and any time-dependent logic reliably.

Read more
Blog post: Testing Time-Dependent Code
Mar 20, 2026
5 min

Testing Time-Dependent Code

Testing Mastery

Your subscription check passes today. Tomorrow it fails. Tests using Date() directly are inherently flaky—inject time as a dependency.

Read more
Blog post: Building Mock HTTP Clients
Mar 17, 2026
5 min

Building Mock HTTP Clients

Testing Mastery

You've got the HTTPClient protocol. Now build the mock that makes your network tests fast, deterministic, and reliable.

Read more
Blog post: Decoupling Network Code
Mar 14, 2026
6 min

Decoupling Network Code

Testing Mastery

Your tests make real HTTP calls. They're slow and flaky. Extract URLSession's interface into a protocol for fast, deterministic testing.

Read more
Blog post: Protocol-Based Dependency Injection
Mar 11, 2026
6 min

Protocol-Based Dependency Injection

Testing Mastery

Instead of depending on concrete types, depend on protocols that describe capabilities. Design focused protocols and injection patterns for testable code.

Read more
Blog post: Refactoring Singletons for Testability
Mar 8, 2026
5 min

Refactoring Singletons for Testability

Testing Mastery

AnalyticsService.shared. AuthManager.shared. Every singleton call is a hidden dependency. Extract, conform, inject, mock—the four-step pattern.

Read more
Blog post: Why Testable Code Matters
Mar 5, 2026
5 min

Why Testable Code Matters

Testing Mastery

If code is hard to test, it's often because of design problems. Hidden dependencies, tight coupling, and side effects kill testability.

Read more
Blog post: Managing Multiple Subscriptions
Mar 2, 2026
5 min

Managing Multiple Subscriptions

Concurrency Deep Dive

One cancellable slot, multiple subscriptions? Only the last one completes. Learn Set, Dictionary, and UUID patterns for tracking Combine subscriptions.

Read more
Blog post: The Missing Cancellable Problem
Feb 27, 2026
5 min

The Missing Cancellable Problem

Concurrency Deep Dive

Your Combine subscription vanished before receiving anything. Learn why AnyCancellable must be stored and patterns for managing multiple subscriptions.

Read more
Blog post: Timer Subscriptions and Memory
Feb 24, 2026
5 min

Timer Subscriptions and Memory

Concurrency Deep Dive

Timer publishers never complete on their own. Learn why they're especially prone to retain cycles and how to manage their lifecycle properly.

Read more
Blog post: Combine Retain Cycles: [weak self] Matters
Feb 21, 2026
5 min

Combine Retain Cycles: [weak self] Matters

Concurrency Deep Dive

Your object never deallocates. The deinit never prints. A strong self capture in your Combine sink created a retain cycle.

Read more
Blog post: Structured vs Unstructured Concurrency
Feb 18, 2026
5 min

Structured vs Unstructured Concurrency

Concurrency Deep Dive

Task vs async let vs TaskGroup. When to use each, their trade-offs, and why structured concurrency should be your default choice.

Read more
Blog post: Unstructured Task Leaks
Feb 15, 2026
6 min

Unstructured Task Leaks

Concurrency Deep Dive

You tap Cancel but the task keeps running. Your polling service outlives the view. Learn to track and cancel unstructured tasks properly.

Read more
Blog post: Safe Financial Systems with Actors
Feb 12, 2026
6 min

Safe Financial Systems with Actors

Concurrency Deep Dive

Building actor-based systems that correctly handle reentrancy. Patterns for transactions, reservations, and rollbacks.

Read more
Blog post: Actor Reentrancy: State Changes During Await
Feb 9, 2026
5 min

Actor Reentrancy: State Changes During Await

Concurrency Deep Dive

Actors protect against data races, but not against time. How state can change across await points and why your balance went negative.

Read more
Blog post: Building Responsive Search with Debouncing
Feb 6, 2026
5 min

Building Responsive Search with Debouncing

Concurrency Deep Dive

Stop firing API calls on every keystroke. Implement debounced search with proper task cancellation to prevent race conditions.

Read more
Blog post: Task Cancellation: The Cooperative Contract
Feb 3, 2026
5 min

Task Cancellation: The Cooperative Contract

Concurrency Deep Dive

You call task.cancel() but nothing happens. Swift's cancellation is cooperative—your code must check and respond.

Read more
Blog post: Lock Ordering and Circular Dependencies
Jan 31, 2026
5 min

Lock Ordering and Circular Dependencies

Concurrency Deep Dive

Two locks, two threads, wrong order. How circular dependencies cause deadlocks and patterns to prevent them.

Read more
Blog post: Deadlocks: Sync to Same Queue
Jan 28, 2026
5 min

Deadlocks: Sync to Same Queue

Concurrency Deep Dive

Your app freezes with no crash log. Learn to identify and fix the two most common deadlock patterns: queue reentry and lock ordering.

Read more
Blog post: DispatchQueue.main vs @MainActor
Jan 25, 2026
4 min

DispatchQueue.main vs @MainActor

Concurrency Deep Dive

When to use the classic GCD approach versus Swift's @MainActor annotation. Trade-offs, mixing them, and common gotchas.

Read more
Blog post: Main Thread Violations: The Silent Crasher
Jan 22, 2026
4 min

Main Thread Violations: The Silent Crasher

Concurrency Deep Dive

That purple Xcode warning about publishing changes from background threads? Here's why it matters and how to fix it.

Read more
Blog post: Thread-Safe Collections in Swift
Jan 19, 2026
4 min

Thread-Safe Collections in Swift

Concurrency Deep Dive

Swift's Dictionary and Array aren't thread-safe. Here's how to wrap them with serial queues, concurrent queues with barriers, or actors.

Read more
Blog post: Race Conditions: When Threads Collide
Jan 15, 2026
4 min

Race Conditions: When Threads Collide

Concurrency Deep Dive

A shopping cart that loses items. Why unsynchronized access to shared state causes unpredictable bugs and how to fix them with serial queues.

Read more
Blog post: Concurrency Bugs Every iOS Dev Should Know
Jan 13, 2026
3 min

Concurrency Bugs Every iOS Dev Should Know

Concurrency Deep Dive

Kicking off a series on iOS interview prep with a look at concurrency bugs, testing patterns, and SwiftUI—plus practice projects to sharpen your skills.

Read more
Blog post: Practice Projects & Setup Guide
Jan 10, 2026
3 min

Practice Projects & Setup Guide

SwiftUI Fundamentals

How to set up and explore the iOS-Practice projects. Project structure, running tests, and suggested learning order.

Read more
Blog post: Cold Starts Improved 15x When I Re-Wrote My Lambda in Go
Jan 9, 2026
5 min

Cold Starts Improved 15x When I Re-Wrote My Lambda in Go

Building Border Times

How I cut my iOS app's splash screen time by rewriting critical Lambda functions from TypeScript to Go—and the architectural patterns that made it possible.

Read more
Blog post: Mastering SF Symbols Rendering Modes in SwiftUI
Nov 23, 2025
5 min

Mastering SF Symbols Rendering Modes in SwiftUI

SwiftUI Snippets

Discover the three powerful SF Symbols rendering modes—multicolor, palette, and monochrome—and learn when to use each for beautiful, colorful icons.

Read more
Blog post: Don't Get Stuck at the Border This Thanksgiving: A Planning Guide
Nov 19, 2025
4 min

Don't Get Stuck at the Border This Thanksgiving: A Planning Guide

Border Times Tips

Avoid holiday border chaos with Border Notices, community-verified crossing times, and smart planning tips for Thanksgiving week.

Read moreRead on Medium
Blog post: Create a Pulsing "Live" Indicator in SwiftUI
Nov 16, 2025
3 min

Create a Pulsing "Live" Indicator in SwiftUI

SwiftUI Snippets

A simple, reusable animation for real-time status indicators. Perfect for showing live data updates without being distracting.

Read moreRead on Medium
Blog post: Why Your 40th App is the One That Finally Prints
Nov 13, 2025
12 min

Why Your 40th App is the One That Finally Prints

Learnings from Building in Public

After 2.5 months building Border Times, I'm starting to understand why it takes dozens of attempts to find success. It's not about luck—it's about mastering five different disciplines at once.

Read moreRead on Medium
Blog post: Border Times iOS App Now Available
Oct 18, 2025
5 min

Border Times iOS App Now Available

Building a Small-Scale Online Business

We built an app because waiting at the border really sucks. Download Border Times on iOS and join thousands of border crossers saving time and sanity.

Read moreRead on Medium
Blog post: They say the best business ideas start with solving a personal problem!
Sep 25, 2025
4 min

They say the best business ideas start with solving a personal problem!

Building a Small-Scale Online Business

From border crossing frustrations to launching border-times.com - how personal problems become business solutions.

Read moreRead on Medium
Blog post: Protection from advertisements
Sep 17, 2025
6 min

Protection from advertisements

Building a Small-Scale Online Business

The internet feels like an advertising scheme.

Read more
Blog post: Status Tracker
Nov 18, 2024
8 min

Status Tracker

Part 2

In part two we cover updating the status tracker to have updatable state. We also swap out the titles to have a description of a state, rather than the progress state.

Read more
Blog post: Status Tracker
Nov 18, 2024
8 min

Status Tracker

Part 1

Make a customizable status tracker with SwiftUI.

Read more
Blog post: How close is AI to replacing your job?
Nov 15, 2024
2 min

How close is AI to replacing your job?

Is llama3.1 ready for your job?

Read more
Blog post: Markdown files with AWS
Nov 14, 2024
2 min

Markdown files with AWS

How to avoid .md files not being served.

Read moreRead on Medium
Blog post: Collapsable Indicator
Nov 13, 2024
5 min

Collapsable Indicator

Build a collapsable indicator in pure SwiftUI.

Read moreRead on Medium

Let's work together

Professional discovery, design, and complete technical coverage for your ideas

Get in touch