Journal

Zero to App Store: a curious developer's journal

Three months of evenings and weekends to ship my first iOS app. SwiftUI, HealthKit, AVFoundation, and a lot of patience.

I had never shipped an app on the App Store.

I'd touched Swift, done tutorials, built small things that never left the simulator. But submitting a real project — with real users, a real product page, and real reviewers at Apple — never.

Souffle gave me the perfect excuse to take the leap.

Choosing the stack

From the start, I wanted to go fully native. No React Native, no Flutter, no abstraction layer between my app and the phone. If I was doing this, I was doing it to learn the actual Apple stack.

SwiftUI for the interface. SwiftData for local persistence. HealthKit to log mindfulness sessions in Apple Health. AVFoundation for audio. CoreHaptics for vibrations synchronized with the breathing rhythm.

And one non-negotiable rule: zero server. Everything stays on the user's iPhone. No account, no tracking, no remote database. You install it, you breathe. Full stop.

That choice simplified things in a lot of ways — no API to maintain, no GDPR to handle server-side, no infrastructure. The trade-off is that you're alone with the framework. When SwiftData does something weird, there's no backend to bail you out.

The noise

The problem I didn't see coming was audio.

Souffle offers 13 soundscapes — rain, forest, ocean, fireplace, brown noise, and more — plus a guided voice that tells you when to inhale and exhale, plus a session-end chime. On paper, simple. In practice, AVFoundation reminds you that audio on iOS is a discipline in itself.

The challenge: making all of it coexist without stepping on itself. Start a rain soundscape, layer the guided voice at the right moment, handle transitions when the phase changes, cleanly fade out the end chime without killing the ambient audio — all of that without creating a cacophony or audio glitches that break the whole experience.

I spent several evenings debugging cases where two sounds fired simultaneously, where the voice overlapped with itself, where the ambient volume didn't recover after the voice faded out. The kind of bugs that don't crash — which is worse, because they just sound wrong. And you can't write a unit test for "does this sound weird."

The solution ended up being a fairly strict audio channel management system, with priorities and crossfades between sources. Nothing revolutionary, but the kind of thing that takes patience and a lot of trial and error with headphones on.

Claude Code, my 11pm pairing partner

I coded Souffle evenings and weekends, often late. And often with Claude Code open alongside.

To be clear: I didn't ask an AI to generate an app for me. This isn't vibe coding. Claude Code, for me, was the senior friend who knows the Swift stack better than you and is available at 11pm when you're stuck on something stupid.

"How do I cleanly handle audio interruptions when the app goes to background?" — it would give me a direction, we'd discuss it, I'd adapt it to my context. "This MVVM pattern — is this the right place for this logic?" — we'd debate. Sometimes it was right, sometimes not. Like with a real colleague.

The gain isn't in the code it writes for you. It's in the hours you don't waste digging through documentation, hunting for an example on Stack Overflow, trying three approaches before finding the right one. When you're coding on your own time, those hours count double.

Design, my weak spot

I'm a developer. Design is not my strong suit. And Souffle reminded me of that.

Finding the right colors. The right spacing. The right font size. Making a screen readable without being empty, structured without being cluttered. I have a new respect for designers after this.

The dark theme with turquoise accents came together fairly quickly — it matched the zen mood of the app. But the layout, the visual hierarchy, the transitions between screens — I fumbled. A lot.

It's not the most beautiful app on the Store. I know that. But it's clear, it's functional, and it does the job. The design will improve with each version — it's on the roadmap, and this time I'll take the time to do it properly.

Submission

As I write this, Souffle is being reviewed by Apple. The app has been running on TestFlight for a few weeks — my father, a few close people, feedback, fixes.

The submission itself is a process in its own right. If you've never filled out an App Store Connect listing, picture an administrative form that asks for screenshots in three sizes, an age rating across seven steps, questions about third-party content rights, a privacy policy, promotional text, keywords, and a description that has to be both honest and compelling.

It's tedious. Not hard, but long. And every field you fill in reminds you that shipping an app isn't just writing code. It's a complete product — marketing, legal, support, communication.

I made the screenshots with Hotpot and a lot of iterations. I rewrote the description four times. I spent an hour on keywords. For a free breathing app, I didn't expect to spend that much time on everything that isn't code.

What I'm taking away

Shipping a first app — even small, even free, even imperfect — is a complete exercise. You touch everything: architecture, audio, persistence, system integration, design, marketing, distribution. In three months of evenings and weekends, I learned more than in some courses.

And the thing I didn't anticipate: the pride. Not pride in the code — there are parts I'd gladly refactor. The pride of watching my father open an app I built, start a session, and breathe.

The rest — Apple reviews, download stats, comments — will come. For now, I'm waiting for Apple's email and checking my inbox every hour.

I'll report back when it arrives.

— Pato


This post is part of a series about building Souffle. The previous article tells the personal story behind the app. The next one will cover the first user feedback and what this whole adventure taught me — beyond the code.