App Store Publishing Guide: From Xcode Archive to Review
8 min read

Publishing an app on the App Store is a separate job from writing the code: account, signing, store record, artwork, privacy declarations, test distribution and review. None of the steps is hard, but when you do not know their order and how they depend on each other, they cost you days. This guide walks through the path in sequence, from "my app runs in Xcode" to "my app is live on the store".
Fees, review times and required screenshot sizes change over time. That is why I give no numbers here; always check the current values on Apple's own pages and in the fields App Store Connect shows you at that moment.
1. Apple Developer Program Membership
A free Apple account is enough to run your app in the simulator and on your own device. To publish on the store and to use TestFlight you need the paid, yearly Apple Developer Program membership. You enrol through the Apple Developer app or the website, and the process includes identity verification.
There are two kinds of membership: individual and organisation. With an individual membership your own name appears as the seller on the store. With an organisation membership the company name appears, but you must prove your legal entity and obtain a D-U-N-S number, which lengthens the process. Approval may not be immediate, so apply before the app is finished.
2. Bundle ID and Signing
Every app has a unique bundle identifier in reverse-domain form, for example com.companyname.appname. Once you have uploaded the first build you cannot change it, so choose it properly from the start.
Certificates, App IDs and provisioning profiles used to be the most time-consuming part. Today, for a solo developer, it comes down to this: select the target in Xcode, open Signing & Capabilities, tick "Automatically manage signing" and pick your team. Xcode registers the App ID, creates the certificate and manages the profiles itself. Manual signing only becomes relevant with a CI server or a larger team.
Look at the version numbers on the same screen. Version is what users see (1.0.0), Build is an internal number that has to increase with every upload. You cannot upload a second build with the same build number for the same version.
3. The App Store Connect Record
In App Store Connect, create a new app in the Apps section. You are asked for the platform, app name, primary language, bundle ID and SKU. The app name must be unique across the store; if the name you want is taken you cannot create the record, so it makes sense to reserve the name early. The SKU is an internal code only you see.
If you plan a paid app or in-app purchases, you have to accept the paid apps agreement in the Business section and enter banking and tax details. For a free app this step is not required. If you distribute in European Union countries, you are also asked to declare whether you are a trader under the EU Digital Services Act (DSA).
4. What the Store Page Needs
These are the fields you fill in on the version page:
- Screenshots. App Store Connect states which device sizes are required, and that changes over time. If the app also runs on iPad, iPad screenshots are requested too. Screenshots must show the app's real screens.
- Description, keywords, subtitle, category.
- Support URL. Required. It must be a page that opens and offers a real way to get in touch.
- Privacy policy URL. Required. It should live at a public, permanent address.
- App privacy details. The section shown on the store as the "privacy nutrition label". You declare which data types you collect, whether they are linked to the user's identity and whether they are used for tracking. Data collected by third-party SDKs you ship (analytics, ads, crash reporting) is your responsibility as well.
- Age rating. You fill in a questionnaire and the result is calculated automatically. User-generated content and social features raise the rating.
- Encryption declaration. To avoid being asked on every upload, you can add the
ITSAppUsesNonExemptEncryptionkey toInfo.plistwith the value that fits your app.
I described how much time these items took for my own app in shipping LevelUpStudy to the App Store. The short version: write them down at the start of development, not at the end.
5. Archive and Upload
In Xcode, choose Any iOS Device as the run destination rather than a simulator, then Product > Archive. When the archive finishes, the Organizer window opens. Follow Distribute App > App Store Connect > Upload. Xcode signs the build and uploads it.
The build does not show up immediately after the upload; it goes through processing on Apple's side, and you get an email when that is done. If a purpose string is missing or an icon is invalid at this stage, you receive an email describing the problem and the build may never appear in the list.
6. TestFlight
Once processed, the build appears in the TestFlight tab. There are two kinds of testers:
- Internal testers: people on your App Store Connect team. They get the build without waiting for a review.
- External testers: invited by email or through a public link. The first build goes through a short beta review.
TestFlight builds expire after a limited period. The real value is that you try the app on real devices with store signing. Notifications, purchase flows and deep links can behave differently in the simulator.
7. Submitting for Review
On the version page, select the build and fill in App Review Information: contact details, notes and, if the app requires sign-in, a working demo account. If the reviewer cannot sign in, they cannot look at the rest of the app and the submission is rejected.
This is also where you pick the release option: automatically after approval, manually when you decide, or on a specific date. Choosing manual release for a first version lets you time the announcement yourself.
Common Mistakes: The Most Frequent Rejection Reasons
The full rules are in the App Review Guidelines. In practice these come up most often.
Accounts can be created but not deleted
Symptom: the rejection message says no account deletion option could be found. Any app that lets people create an account must let them initiate deletion from inside the app; "send us an email" is not enough. Fix: put a visible delete option in the settings screen and really delete the data on the server.
import SwiftUI
struct DeleteAccountButton: View {
let deleteAccount: () async throws -> Void
@State private var isConfirming = false
@State private var errorMessage: String?
var body: some View {
Button("Delete My Account", role: .destructive) {
isConfirming = true
}
.confirmationDialog(
"Your account and all your data will be permanently deleted.",
isPresented: $isConfirming,
titleVisibility: .visible
) {
Button("Delete Permanently", role: .destructive) {
Task {
do {
try await deleteAccount()
} catch {
errorMessage = "The account could not be deleted. Please try again."
}
}
}
}
.alert("Error", isPresented: .constant(errorMessage != nil)) {
Button("OK") { errorMessage = nil }
} message: {
Text(errorMessage ?? "")
}
}
}The server side is covered in Firebase Auth and account deletion, and Task and async in the async/await guide.
Missing purpose strings
Symptom: the app crashes the moment you access the camera, photo library, location or microphone, or you get a missing purpose string warning after the upload. Fix: add a description to Info.plist for every protected resource you use. The text has to say what the data is used for; an empty sentence like "Camera access is required" is a rejection reason too.
<key>NSCameraUsageDescription</key>
<string>We use the camera so you can take a profile photo.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We access your photos so you can choose a profile photo from your library.</string>Broken links and placeholder content
Symptom: the rejection message says the app is incomplete. The cause is usually a support or privacy page that does not open, "Lorem ipsum" text, an empty tab, a button labelled "coming soon" or a test server that was down during the review. Fix: open every link on a real device before submitting, remove unfinished features from the build and make sure your backend stays up throughout the review.
Crashes and mismatched declarations
A single crash during review is enough for a rejection. A force-unwrapped optional is one of the most common crash causes, and the habits from the post on optionals and guard let pay off directly here. The second large group is mismatches: screenshots that do not reflect the app, a privacy declaration that does not match what the app actually collects, or a third-party social login offered without the equivalent privacy-focused login option the guidelines ask for.
If you are rejected, do not panic. You can reply to the review team in the messages section of App Store Connect, ask for clarification, fix the issue and resubmit.
After Approval
Once approved, the app goes live either on its own or when you press release, depending on the option you chose; it can take a while to appear in every country. From then on it is maintenance:
- Watch crash reports and usage data in Xcode Organizer and App Store Connect.
- Reply to user reviews from App Store Connect.
- Every update means a new version number and a new review. The phased release option for updates keeps a bug from reaching everyone at once.
- Remember to renew your membership; when it lapses, your apps can no longer be downloaded from the store.
Frequently Asked Questions
Do I need a Mac to upload an app to the App Store?
Yes. Signing and uploading the build requires Xcode, and Xcode requires macOS. Without a Mac of your own, cloud Mac services or a CI service are an option, but a real Mac makes debugging much easier.
How long does review take?
There is no fixed duration and it varies from period to period. Plan with the possibility that the first submission gets rejected and a second round is needed.
If I am rejected, is my app blocked permanently?
No. A rejection means that submission needs fixing. You resolve the issue and resubmit, and if you believe the decision is wrong you can appeal.
Can I start with an individual account and move to a company later?
Apple allows converting an individual membership to an organisation and transferring apps between accounts. The conditions can change, so read the current guidance before you start.
Related Posts
SwiftUI First App: A Step-by-Step Guide for Beginners
Build your first SwiftUI app from an empty Xcode project to the simulator: App, View, VStack, @State, List and TextField in a working to-do list.
SwiftUI @State, @Binding and @Observable: Data Flow Guide
When to use @State, @Binding, @Observable, @Bindable and @Environment in SwiftUI, how they map to ObservableObject, with a decision table and common bugs.
Swift Struct vs Class: Value and Reference Types Explained
Learn the difference between struct and class in Swift with runnable examples: copying, mutating, let, ===, inheritance, deinit and how to choose.