Blog
Engineering Notes
Build notes, architecture decisions, and the occasional hard-won lesson from shipping native iOS, Android, and server-side Swift.
All articles
- Server-Side Swift
Google Cloud Swift SDK: What It Means for Vapor and Hummingbird
Google now ships an official Swift SDK for Google Cloud: async, Sendable and one package per service. It is also a 0.x release labelled GA, with a Swift 6.2 floor and gaps in coverage. Here is how to call it from Vapor, and what a Swift 6.0 deployment must change first.
Ben Van Aken11 min read - iOS for Business
Staff Augmentation When AI Writes the Code: You're Buying Judgement, Not Headcount
Coding agents now sit inside Xcode and Android Studio, so why rent engineers? Because writing code got cheap and reviewing, integrating and shipping it did not. What the evidence says, and how to structure and evaluate an engagement around judgement.
Ben Van Aken10 min read - iOS for Business
Android Developer Verification: What Is Enforced and Who Owns Your App
Android developer verification has been enforced in four countries since September 30, 2026 and is due to expand globally in 2027. For most Play apps the registration is already done. Who owns the developer account and the signing key decides whether you can keep shipping.
Ben Van Aken10 min read - iOS for Business
Rebuild or Patch?
Agents make a rewrite look cheap in week one. The app you have is a pile of edge cases, which is why it is still in the store. How we decide, using only products we own.
Ben Van Aken4 min read - Server-Side Swift
Swiftly-CMSKit Early Beta
Swiftly-CMSKit is a headless CMS for Vapor, published early. The repository says it is not ready for production. Here is what the 26 modules cover, and what we have not done with it.
Ben Van Aken4 min read - Server-Side Swift
Vapor 5 Migration: Preparing a Vapor 4 App Before the Guide Exists
Vapor 5 is in beta and there is no migration guide yet. Most of the move is finishing the async migration, which Vapor 4 already supports. Here is what to change now, and what to leave alone.
Ben Van Aken10 min read - Case Study
Swiftly Workspace ERP
Swiftly Workspace is our ERP: native clients for iOS, macOS and tvOS, a Vapor server, and Claude in the task flow. Version 1.5, still being built, with one commit figure we are willing to print.
Ben Van Aken4 min read - Architecture
Swift on Android in 2026: A Real Option Beside Flutter, React Native and KMP?
Swift 6.3 shipped the first official Swift SDK for Android. It shares Swift logic with a Kotlin app, not your SwiftUI screens. That makes it a rival to Kotlin Multiplatform rather than to Flutter or React Native, and a real option for teams that already have a Swift iOS app.
Ben Van Aken11 min read - Server-Side Swift
Which AI Agents Visit Your Site?
Which AI agents visit your site is a breakdown, not a hit count. Training, AI-search indexing, a person asking an assistant, and a forged user agent are different events. SwiftlyBotKit records the split.
Ben Van Aken5 min read - Server-Side Swift
Invoices in Pure Swift
Swiftly-PDFKit draws invoices, quotes and delivery notes from a Swift document model. The layout is the published part. The decision to send the PDF is still a person's.
Ben Van Aken4 min read - iOS for Business
How to Read an App Development Quote
An app development quote with one number and no lines under it is not comparable to anything. What to look for in 2026: platform, review, ownership, and the costs the number leaves out.
Ben Van Aken4 min read - Server-Side Swift
Vapor vs Hummingbird in 2026: Choosing a Server-Side Swift Framework
Vapor 4, the Vapor 5 beta and Hummingbird 2 are closer than the old forum threads suggest. The real choice is how much you want decided for you, how far ahead you are planning, and where the service will run.
Ben Van Aken11 min read - iOS for Business
AI Act Article 50: What It Means for the AI Features in Your App
AI Act Article 50 has applied since August 2, 2026. What it asks of an app with a chatbot, generated images or AI summaries, the one narrow grace period that ends on December 2, and where an app that calls someone else's model sits.
Ben Van Aken11 min read - iOS for Business
Who Owns Your App?
Who owns your app is two questions. Google's is about who may update an Android package. The one that matters when you hire builders is whose accounts, keys and repository the app lives in.
Ben Van Aken4 min read - Case Study
How We Built FeedbackKit
FeedbackKit lives inside someone else's app, so it could not pick one UI toolkit and call that a platform. The public SDKs, the native admin app, and what we are willing to say about how it was built.
Ben Van Aken4 min read - Architecture
Multi-Provider AI Architecture for Apps: Don't Marry One Model Vendor
Model vendors retire models on published dates and can change behaviour without changing the ID. What WWDC26's Foundation Models opening standardised, what it left to you, and the gateway architecture that makes a model switch a config change.
Ben Van Aken12 min read - iOS for Business
Native or Cross-Platform? How to Choose in 2026
A coding agent will draft a second screen in an afternoon. That does not tell you whether to keep one UI toolkit or two native apps. How we choose, with FeedbackKit as the example we can actually show.
Ben Van Aken5 min read - iOS for Business
Apple's New EU App Store Terms: Which Distribution Route Fits Your App
Apple's unified EU terms took effect on October 1, 2026. The headline cut is four points on in-app purchase. The real decision is which payment and distribution route to lock in for a year, and for many business apps the answer is none of them.
Ben Van Aken11 min read - SwiftUI
Testing Handoff When You Cannot Automate It
Part 9 closes our Apple Continuity series. There is no automated way to test a device-to-device Handoff, and that absence is a finding rather than a gap in our research. What you can still test purely, a DEBUG arrival seam that proves routing and not transport, the six-condition manual smoke test, and the full list of what nine parts could not settle.
Ben Van Aken11 min read - SwiftUI
Continuity Camera and the Features With No API
Part 8 of our Apple Continuity series. Continuity Camera import is one AppKit menu item whose absence is completely silent, and the webcam half breaks on a hard-coded device type or a discovery session read once at launch. Shared with You cannot carry private content at all, and iPhone Mirroring cannot be detected from inside an app.
Ben Van Aken11 min read - SwiftUIFeatured
Universal Clipboard: The Continuity Feature You Already Shipped
Part 7 of our Apple Continuity series, and the uncomfortable one. Universal Clipboard rides on Handoff, is opt-out, and is already running in your app: a plain UIPasteboard.general.string on a screen full of someone else's data is a cross-device transfer. iOS has localOnly. macOS, by Apple's own sentence, has no opt-out at all.
Ben Van Aken11 min read - SwiftUI
What Must Never Cross a Handoff
Part 6 of our Apple Continuity series. An NSUserActivity is a publishing decision, and three of its four eligibility flags publish somewhere you did not intend: isEligibleForPublicIndexing reaches Apple's global Spotlight indexes, webpageURL is what a device without your app follows, and a stale activity keeps advertising a record the user has already left.
Ben Van Aken11 min read - SwiftUI
Sending Handoff to the Right Window
Part 5 of our Apple Continuity series. Arriving in the app is not the same as arriving in the right window. SwiftUI picks the scene for a continuation in four documented steps, and it matches on a property most Handoff tutorials never set: targetContentIdentifier.
Ben Van Aken9 min read - SwiftUI
How Big Should a Handoff Payload Be in 2026
Part 4 of our Apple Continuity series. Apple's current NSUserActivity reference publishes no payload size. The same activity can name the on-screen entity for Siri and Apple Intelligence, so send an identifier and let the other side load the content. The 2016 figure of 3 KB survives only as a historical footnote.
Ben Van Aken15 min read - SwiftUIFeatured
Where Handoff Actually Arrives on iOS and macOS
Part 3 of our Apple Continuity series. On iOS, a scene-adopted app receives Handoff in scene(_:continue:) and never in the app delegate. The three app-delegate Handoff methods carry an availability upper bound of 26.0; the scene and AppKit equivalents carry none. With the fetch technique behind those figures, the three-callback set, and a snippet that proves which seam fires in your app.
Ben Van Aken10 min read - SwiftUI
Your First NSUserActivity: Handoff in Swift
Part 2 of our Apple Continuity series: the smallest Handoff that works end to end. Build the activity, declare NSUserActivityTypes in every receiving target, advertise and receive it in SwiftUI. The same Team ID plus a declared type is the entire gate.
Ben Van Aken8 min read - SwiftUIFeatured
Apple Continuity Is Three Different Contracts
Part 1 of our Apple Continuity series. Continuity is not one feature but a family with three postures: opt-in with an API, opt-out and already running with your data, and no API at all. Almost every mistake we found came from applying one posture's rule to another's feature.
Ben Van Aken8 min read - Testing
The XCUITest Speed-Ups We Measured and Dropped
Part 11 of our XCUITest series, closing the performance arc. Three optimisations that look large on paper and measured small: caching provisioning per class (2.1 percent of setUp), keeping the session across relaunches (under 1 percent) and seeding fixtures once per class (inside the noise). How to price a candidate before building it, what actually makes result bundles large, and ten rules for UI-test performance.
Ben Van Aken10 min read - Testing
Animations Off and Parallel Simulators: Measured XCUITest Speed-Ups
Part 10 of our XCUITest series. Where XCUITest's wait-for-idle time comes from (not activate()), how to disable SwiftUI and UIKit animations from inside the app under a UI-testing launch argument without persisting anything, how to measure the effect with a pre-registered ABA run, and how to split a suite across parallel simulator clones by shared state. Measured at minus 7.70 percent and minus 20.0 percent, with do's and don'ts.
Ben Van Aken12 min read - Testing
Negative Waits: The Seconds Every Green XCUITest Run Burns
Part 9 of our XCUITest series. XCTAssertFalse(x.waitForExistence(timeout: 4)) spends four seconds on every passing run; waitForNonExistence spends one poll. A guide to the waits whose cost does not depend on the app: how to find them in the result bundle, how short each can safely be, how to prove a shortened wait can still fail, and the positive waits that never succeed. With do's and don'ts.
Ben Van Aken10 min read - Testing
The Launch-and-Login Tax: Per-Class App Lifecycle in XCUITest
Part 8 of our XCUITest series. When 84 percent of a test's setUp is launching the app and logging in, launching once per class is the first optimisation to consider. How to implement it in XCTest, how to prove the app is reset between tests, which classes must stay per-method, and how to skip wrong-device tests before the launch happens. Measured at minus 31.9 percent across 23 classes, with do's and don'ts.
Ben Van Aken11 min read - Testing
Measuring an XCUITest Suite Before You Speed It Up
Part 7 of our XCUITest series, and the start of the performance arc. A practical guide to measuring a UI-test suite before optimising it: which four numbers to collect, how to get a run that can be reported, how to read outcomes from the result bundle, when a before/after comparison is valid, how to confirm which build you measured, and why macOS runs cannot be left unattended. With do's and don'ts for each step.
Ben Van Aken10 min read - Testing
Diagnosing a Red XCUITest: Environment, Order, and Process
Part 6 of our XCUITest series. Stale binaries, simulator contention, automation-mode timeouts and dead hosts; the ten-step diagnosis order that stops you blaming the product; the process that keeps a suite honest; and the ten lines to keep if you keep nothing else.
Ben Van Aken7 min read - Testing
Oracles and Isolation: When a Green XCUITest Proves Nothing
Part 5 of our XCUITest series. A login smoke test that was vacuous for its entire life, Bool helpers that hid a live product defect, skips that report green, a restored session that donates the wrong identity to every later class, and the rules that fix each one.
Ben Van Aken7 min read - Testing
XCUITest Mechanics: Waits, Hittability, and Platform Traps
Part 4 of our XCUITest series. Why a leg's wall-clock is its query count times 19 seconds, why activate() inside a poll costs a minute, why isHittable is not visibility, the tap that landed on another app, and the iPad, iPhone and macOS traps that name the wrong subsystem.
Ben Van Aken12 min read - Testing
SwiftUI Accessibility Identifiers: Why Your Stamp Never Surfaces
Part 3 of our XCUITest series. Container ids overwrite their children, the Button authoring form decides what iOS publishes, a macOS Table is an Outline, menus keep their names on title, and a dozen other measured reasons a stamped identifier never reaches the tree.
Ben Van Aken7 min read - Testing
Designing an XCUITest Harness the App Cooperates With
Part 2 of our XCUITest series. One base class, two byte-identical lanes, structural assertions next to AI-vision contracts, a double-gated --uitesting launch argument, and the hidden-button trick that opens any seeded record in a lazy Table.
Ben Van Aken9 min read - TestingFeatured
Where UI Tests Belong in a SwiftUI App
Part 1 of our XCUITest series. The five-layer pyramid we test a production SwiftUI app with, why Apple forces the Swift Testing and XCTest split, the millisecond-cheap source-scanning guards, and seven shapes of coverage that cannot fail.
Ben Van Aken6 min read - SwiftUIFeatured
On-Device Translation with Apple's Translation Framework (The Session You Can't Keep)
A TranslationSession is only valid inside the closure that hands it to you. That single constraint decides the batching, the caching and the shape of every object around it.
Ben Van Aken10 min read - SwiftUIFeatured
Tracking ScrollView Offsets in SwiftUI (Three Ways That Actually Work)
The PreferenceKey snippet everyone copy-pastes silently reports a frozen 0.0. The coordinate space isn't why. Here's the fix, plus scrollPosition(id:) and onScrollGeometryChange.
Ben Van Aken11 min read - SwiftUI
Building an In-App Feedback Loop for Your SwiftUI App
Feedback scattered across App Store reviews, email and TestFlight isn't a collection problem. It's a loop problem. Here's how to build the loop in SwiftUI.
Ben Van Aken7 min read - iOS for Business
iOS App Security for Businesses: What Actually Protects Your Data
iOS gives you strong defaults and then stops. Where the platform's guarantees end and yours begin: Keychain and the Secure Enclave, App Attest, ATS and pinning, data-at-rest protection classes, privacy manifests, why jailbreak detection is not a control, and what auditors actually ask.
Ben Van Aken10 min read - iOS for Business
Why Mobile App Development Matters for SMEs (and When It Doesn't)
"Every business needs an app" is a sales pitch, not an answer. What mobile actually changes for a small or mid-sized business, what drives the cost, and how to tell whether you're one of the companies that shouldn't build one.
Ben Van Aken11 min read - Architecture
Scaling Swift Projects With Modular Packages
Seven local packages, one Vapor binary, four public domains. What splitting a Swift project into modules actually buys you, the rule that makes it work, the bug it did not prevent, and when not to bother.
Ben Van Aken11 min read - SwiftUI
SwiftUI vs UIKit: A 2026 Answer, Not a 2020 One
Six years on, this is not a choice between two frameworks. It is a ratio, and every app we ship has both in it. What SwiftUI still does badly, how to bridge in both directions, and how to pick per project.
Ben Van Aken12 min read - Architecture
MongoDB and SwiftUI: The Decision First, Then the Wiring
Swift and MongoDB are not alternatives. But there is a real decision hiding behind that search. Here's when Mongo beats Postgres for a Swift backend, why the old SwiftUI shortcuts are gone, and the wiring that still works.
Ben Van Aken12 min read - SwiftUI
The Swift Logger API, End to End
Unified logging is the best-documented Apple API that almost nobody uses properly. Subsystems, the privacy rules that redact your strings, signposts, pulling logs off a device, and why the server wants a different Logger entirely.
Ben Van Aken13 min read - iOS for Business
From Prototype to App Store: A Realistic Timeline
The real sequence from an idea to a live listing: discovery, prototype, MVP, TestFlight beta, App Review, launch. Honest durations for each stage, what actually causes rejections, and the admin that has to start weeks before you think it does.
Ben Van Aken9 min read - iOS for Business
Apple vs Android for Business: How to Choose a Device Fleet
Not a flamewar. How Android and iOS genuinely differ as software, which platform gives you more accessible support, which app store is actually safer, and how to pick the right devices for a company fleet. Written by a studio that ships on both.
Ben Van Aken9 min read
No articles match your search
Try a different word, or clear the search.