A little different this week. I shipped my first iPhone app to TestFlight.
The app is called Deep Prayer (display name: Quiet Time Helper). It’s a voice-first prayer journal — dictate a prayer, and the app transcribes it on-device, finds matching Bible verses, structures the prayer into ACTS (Adoration, Confession, Thanksgiving, Supplication), and generates a short personal devotional. It runs on iOS 26+ with Apple’s SpeechAnalyzer for transcription, a Hono API on Railway, and Claude Haiku 4.5 doing the prayer processing.
Here’s the thing: I’ve never written a line of Swift before this project. I’ve lived in TypeScript for years. The entire iOS toolchain — Xcode, provisioning profiles, App Store Connect, Fastlane — was foreign country to me. And yet the first TestFlight build is live, the app has 35 Swift files, a real design system, and I’m about to start adding beta testers.
The only reason any of that was possible is a stack of Claude Code skills, MCP servers, and CLIs that quietly turn Claude Code into an expert iOS developer. Three of them did the heaviest lifting.
1. Paul Hudson’s SwiftUI + Swift Concurrency skills
My first pass at building Deep Prayer was rough. I had an implementation plan, I had Claude Code, and I started building — but I was hitting Swift bugs constantly. Runtime crashes (a classic Swift 6 concurrency SIGTRAP on the main thread when AVAudioEngine.installTap ran from a sync nonisolated method), architectural mistakes, sloppy SwiftUI view composition. The pattern was obvious: generic Claude Code outputs for Swift were subtly wrong in ways that only show up when you run the code.
This makes sense when you think about it. Swift’s LLM training data is way sparser than web frameworks. Swift 6 strict concurrency shipped in 2024 and the rules are unforgiving. SwiftUI changes meaningfully every year at WWDC, and most of the blog posts and Stack Overflow answers in any LLM’s training set are for older versions of the language. Generic “I know Swift” is not the same as “I know the Swift you’re actually writing today.”
I went looking for Swift skills and found Paul Hudson’s. Paul runs Hacking with Swift and has been teaching Swift longer than most people have been writing it. He released a set of Claude Code skills that encode modern SwiftUI patterns and Swift 6 concurrency rules, plus a companion skill for Swift Testing.
npx skills add https://github.com/twostraws/swiftui-agent-skill
npx skills add https://github.com/twostraws/swift-concurrency-agent-skill
After installing, I re-wrote my implementation plan to explicitly invoke each skill at the right moments — SwiftUI Pro when building views, Swift Concurrency Pro when touching async code or actor isolation, Swift Testing Pro when adding unit tests. Then I restarted the project from scratch.
Example use: "Use SwiftUI Pro to build the RecordingView. The start method needs to be async because installTap runs on a background thread and we can't block the main actor."
What it’s helped with: The second pass was night and day. My code now passes Swift 6 strict concurrency on the first or second try. @Observable view models, proper @MainActor boundaries, correct use of async let and TaskGroup — all of it flows. For a first-time iOS developer, having Paul’s skills loaded feels like pair-programming with him in the next chair. I wish I could thank him in person.
2. Sentry’s XcodeBuildMCP
XcodeBuildMCP is the foundation of my iOS loop. Sentry maintains it, and it gives Claude Code the ability to build, run, and UI-automate iOS apps directly against the simulator — without me ever opening Xcode or typing an xcodebuild command.
brew tap getsentry/xcodebuildmcp
brew install xcodebuildmcp
Enable the UI automation workflow in .xcodebuildmcp/config.yaml:
schemaVersion: 1
enabledWorkflows: ["simulator", "ui-automation"]
With that in place, Claude Code gets a full suite of tools for driving the simulator: build_sim, install_app_sim, tap, swipe, type_text, screenshot, record_sim_video, and more. My workflow for new features has become almost conversational: I describe what I want in plain English, Claude Code writes the SwiftUI, builds, installs on the simulator, taps through the flow to verify, reads the logs when something breaks, and fixes it in the same loop.
Example use: "Add a depth toggle to the settings screen. Build it, install on the simulator, tap through to settings, toggle the switch, screenshot the before and after."
That prompt is a full development task from description to visual verification, and Claude Code executes the entire thing without me lifting a finger. It writes the view, the view model, the binding, builds the project, deploys to the simulator, drives the UI, and shows me the result as an inline image.
XcodeBuildMCP also has a record_sim_video tool that records MP4 walkthroughs directly from the simulator — which is exactly how I built the walkthrough video for this post’s LinkedIn companion. No QuickTime, no manual screen recording, just a tool call.
A few tips I learned the hard way:
- Set the scheme and simulator once per session. Use
set_selected_schemeandset_selected_sim_idat the start so every subsequent build command uses them automatically. - Turn on
INCREMENTAL_BUILDS_ENABLED=true. The first cold build is slow, but incremental rebuilds after that are close to instant. - Simulator only. XcodeBuildMCP can build and run on the simulator but not on physical devices. Physical device deploys still go through Xcode — I use it for testing audio recording, which the simulator can’t do well.
What it’s helped with: Shipped 35 Swift files without ever typing an xcodebuild command. My QA loop — write code, build, launch, tap through, verify, fix — used to be the slowest part of iOS development for me. Now Claude Code owns it end-to-end.
3. Rudrank Riyam’s App Store Connect CLI + skills
The moment you’ve built a working iOS app, the next wall is distribution. App Store Connect is a maze of API keys, provisioning profiles, build numbers, TestFlight testers, screenshot specs, and review submissions. The traditional escape hatch for all of this is Fastlane — a Ruby toolchain that’s powerful but takes a half-day to set up and another hour every time something breaks.
Rudrank Riyam built a better version for the AI era: asc, a Go binary with 60+ commands covering builds, code signing, TestFlight, screenshots, crash triage, and App Store submissions. It’s agent-native — JSON-first output, predictable flags, structured errors. Paired with his App Store Connect CLI Skills for Claude Code, it becomes the entire iOS release workflow as a set of slash commands.
brew install rudrankriyam/tap/asc
npx skills add https://github.com/rudrankriyam/app-store-connect-cli-skills
asc auth init --key-id <KEY_ID> --issuer-id <ISSUER_ID> --private-key <path-to-.p8>
After that, shipping a new TestFlight build looks like this:
Example use: "Ship a new TestFlight build of Deep Prayer and assign it to the internal testers group."
Claude Code loads the relevant skill, bumps the build number in ios/project.yml, runs xcodegen generate to regenerate the Xcode project, archives the app with xcodebuild archive, exports and uploads via xcodebuild -exportArchive (which auto-uploads to App Store Connect), then calls asc to assign the build to testers. Zero manual steps in the browser.
The first time I watched Claude Code ship a build end-to-end — from git pull to “build is processing in App Store Connect” — I actually laughed. The entire iOS release process, which I had been dreading for weeks, was about 90 seconds of watching tool calls fly by.
What it’s helped with: Replaced Fastlane entirely. Zero Ruby. The build number is always correct, the signing config is always right, and I never have to remember which submenu in App Store Connect has the “assign to testers” button. If Apple ever does a UI refresh and moves things around, Claude Code won’t care — it’s talking to the API directly.
Honorable mentions
Three tools did the heavy lifting, but the full iOS stack has more to it. A few I’d call out for anyone building their first app:
- Iron-Ham’s XcodePreviews plugin — captures SwiftUI Preview snapshots in 3-4 seconds and hands them to Claude Code as images. Claude Code can see its own UI output and iterate on visual design without a full build-install-launch cycle.
- dpearson2699’s ios-security skill — Keychain, CryptoKit, biometric auth, Secure Enclave, and App Transport Security patterns. Run before your first App Store submission.
- Arize Phoenix — self-hosted LLM observability on Railway. Every prayer generation in Deep Prayer is traced end-to-end so I can debug why a specific response was slow or wrong.
- promptfoo — 17 golden test cases (10 prayer, 4 devotional, 3 suggestion) running as evals on every PR, with traces exported to Phoenix. Regression protection for an LLM pipeline that changes weekly.
Full tool list with install commands is in docs/TOOL-SETUP.md in the Deep Prayer repo.
The meta-point of all of this: with the right skills, the right MCP servers, the right CLIs, and a clear vision of what you want to build, the domain you start in barely matters anymore. A TypeScript developer who’d never written Swift shipped a real SwiftUI app to TestFlight in a couple of weeks. That still blows my mind a little.
Thank you to all the open source creators whose work I leaned on — Paul Hudson, the Sentry XcodeBuildMCP team, Rudrank Riyam, Iron-Ham, and many others whose skills I didn’t have room to cover here. The fact that you share this knowledge freely is the reason people like me get to build things like this.
If you’re curious to try Deep Prayer, I’m opening TestFlight to beta testers this week. Reach out and I’ll add you.