Skip to content
ExponaBLOG
SWIFT, SWIFTUI & IOS APPS · DAY 068 / 100

Publishing to the App Store in Swift, SwiftUI & iOS Apps

From archive to release.

Expona Admin8 min read

Publishing to the App Store in Swift, SwiftUI & iOS Apps

You've spent weeks building a polished iOS app in Swift and SwiftUI, but shipping to production means navigating Apple's App Store review process and release infrastructure. Getting from a working build on your Mac to users worldwide involves several critical steps: signing certificates, archiving your build, beta testing via TestFlight, and finally releasing through App Store Connect with optional phased rollouts.

We'll walk through each phase with practical examples so you can confidently move your app from development to the hands of real users.

Signing — Automatic Signing with Your Team

Code signing is how Apple verifies that your app came from you and hasn't been tampered with. When you're publishing to the App Store in Swift, SwiftUI & iOS Apps, automatic signing handles most of the certificate management for you—but understanding what's happening under the hood prevents headaches later.

In Xcode, select your project, then choose your target. Under the Signing & Capabilities tab, you'll see Automatically manage signing. Check that box and select your team from the dropdown. Xcode will then:

  • Create or retrieve your signing certificate (a private key stored in your Keychain)
  • Generate or fetch a provisioning profile tied to your App ID and team
  • Embed that profile in your build

For team development, this is crucial. Each developer needs their own signing certificate, but they all share the same provisioning profile. If automatic signing is disabled and someone manually creates certificates, you'll run into conflicts where one dev's certificate doesn't match another's.

Here's a real scenario: Your team is two developers working on a travel booking app. Developer A creates a Certificate Signing Request (CSR) in Keychain and uploads it to Apple Developer. Developer B does the same. Now when Developer B pulls the latest code and builds, Xcode complains because the provisioning profile expects Developer A's certificate. The fix is straightforward—enable automatic signing, and Xcode handles certificate creation and profile updates for each team member.

One more thing: ensure your team member roles are set correctly in App Store Connect. Go to Users and Access and confirm that developers have at least the Developer role. If someone is stuck as Marketer, they won't be able to initiate a build upload.

Archive and Upload — Product → Archive, then Distribute to App Store Connect

Once signing is in place, you're ready to build a release candidate. This is where we move from development builds on your simulator or device to a signed, optimized build ready for App Store review.

First, ensure your app's version and build number are incremented. Open your project settings, select your target, and check the General tab. For a major release, bump the version (e.g., 1.0.0 → 1.1.0). For a patch or beta, increment the build number (e.g., build 5 → build 6). These must always increase; App Store Connect rejects uploads with duplicate or lower numbers.

Next, set your build configuration to Release and your destination to Any iOS Device (arm64). If you leave it on a simulator or your personal device, you'll get an error when uploading. Then go to Product → Archive. Xcode compiles your code, strips out debug symbols, and creates an archive file (.xcarchive).

After archiving, the Organizer window opens automatically. You'll see your archive listed with its version, build number, and creation date. Click Distribute App. You'll be presented with distribution options:

  • App Store Connect — Direct upload for review and release (what we want)
  • Ad Hoc — Signed build for testing on registered devices without App Store
  • Development — For testing only; won't work on devices outside your team
  • Enterprise — For large organizations with in-house distribution

Select App Store Connect and proceed. Xcode will prompt you to sign the archive (it uses your automatic signing identity). Then it uploads the build to App Store Connect, which validates the signature and parses your app's metadata. The entire upload typically takes 2–5 minutes depending on your app size and internet speed.

Once uploaded, check App Store Connect. Go to your app, then TestFlight tab. You should see your new build listed under Builds with a status of Processing. Apple's systems are scanning your binary for crashes, compliance issues, and other problems. This usually completes within an hour.

TestFlight — Internal and External Testers Before Release

TestFlight is your safety net. It lets you distribute beta versions to testers before submitting for App Store review, catching real-world bugs and UX issues that slip past your own testing.

Once your build finishes processing, you have two tester groups:

Internal Testing: Available to anyone with an account in App Store Connect. This includes developers, QA, designers, and product managers. Add testers under App Store Connect → Users and Access → Testers (Internal). They can install the beta via TestFlight immediately after the build is released to internal testing.

External Testing: Available to up to 10,000 testers outside your organization. You create a group (e.g., "Friends & Family", "Beta Wave 1"), add their email addresses, and generate a public link. External testers can then join via email invitation or a public link without needing an App Store Connect account. This is how you get feedback from real users in your target market before going live.

Here's a practical workflow from a travel app we shipped: After archiving, we released the build to internal testing first. Our team used it for 48 hours to spot any crashes or obvious bugs. Once confident, we created an external testing group of 50 travel bloggers and early access customers. They tested for a week, reported issues via the TestFlight feedback form, and we iterated. On day 7, we fixed the last batch of bugs, created a fresh build, and released that to external testers for final sign-off. Only then did we submit for App Store review.

TestFlight tracks crash logs, session replays, and user feedback. Every tester has the app's crash data automatically uploaded to App Store Connect. You can view these in Analytics → Crashes. If a tester reports "the login screen freezes when I paste text", you can often correlate that with a specific crash log and stack trace.

One critical tip: TestFlight builds expire after 30 days. If you're doing a long beta cycle, you'll need to upload fresh builds periodically to keep the beta available to testers.

Release — Phased Release to Roll Out Gradually

You've tested thoroughly, fixed the critical bugs, and now you're confident in your build. It's time to submit for App Store review and then release to users.

First, go to your app on App Store Connect and click Prepare for Submission. You'll fill in metadata: app description, keywords, support URL, privacy policy, and screenshots. Make sure everything is accurate and your privacy policy is a real URL, not a placeholder. Apple reviewers check this carefully.

Then scroll to Build and select your build. At the bottom, you'll see Release Type. Choose Automatic (releases as soon as review is approved) or Manual (you trigger the release later). For most apps, Automatic is fine, but if you want to coordinate release timing with a marketing campaign, choose Manual.

Now submit for review. Apple's reviewers typically process your app within 24–48 hours. They test core functionality, check for compliance with App Store Review Guidelines (no private APIs, no crashing, no deceptive behavior), and verify your app doesn't do anything it claims it doesn't do.

Once approved, if you chose Manual release, you can trigger the release whenever you want. Go to App Store → Your App → Version Release → Release This Version. Your app is now live for all users on the App Store.

But here's where phased release comes in. Instead of releasing to 100% of users immediately, you can roll out gradually. When you release, toggle Phased Release to On. iOS will automatically increase the percentage of users who see the update over 7 days: day 1 at 1%, then escalating to 100% by day 7. This is invaluable for production safety.

Why use phased release? If your update has a critical bug affecting a small percentage of users, you catch it on day 1 or 2 when only 5–10% of users have updated. You can then roll back, fix the bug, and re-release. Without phasing, a bad update hits 100% of users instantly and damages reputation.

Real example: A ride-hailing app released a new version that broke the payment flow for users with certain credit card types. With phased release at 5%, the team noticed a spike in crashes within hours. They paused the rollout, investigated, fixed the card validation logic, and released a new build. The damage was contained to a small subset of users rather than millions.

Common Mistakes

  • Forgetting to increment the build number: App Store Connect rejects uploads with duplicate or lower build numbers. Always increase it, even for TestFlight betas.
  • Submitting with "Any iOS Device" not selected: Archiving from a simulator or personal device produces an archive that Xcode won't let you upload. Always select Any iOS Device (arm64).
  • Leaving automatic signing disabled: If your team has mixed automatic and manual signing, some developers get certificate mismatches. Pick one approach and stick with it.
  • Not testing the phased release timeline: If you release a phased update and then immediately release a second update, the first one may not finish rolling out. Coordinate releases to avoid confusion.
  • Ignoring TestFlight crash logs: Many teams skip external testing or don't review crash data. This is how production bugs slip through.
  • Updating privacy policy after submission: Changing your privacy policy after submitting for review requires a new submission. Make sure your privacy policy is finalized and live before you submit.

Key Takeaways

  • Enable automatic signing in Xcode and ensure your team members have the correct roles in App Store Connect to avoid certificate conflicts.
  • Always increment your version or build number before archiving, and always archive from Any iOS Device (arm64), not a simulator.
  • Use TestFlight's internal testing group for quick team validation and external testing to gather real-world feedback before App Store review.
  • Submit for App Store review with finalized metadata and privacy policy, then use phased release to roll out gradually and catch production issues early.
  • Monitor crash logs and user feedback throughout your beta and release phases; use phased release to mitigate damage if a critical bug slips through review.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles