Friday, 24 July 2026

How to Build Unity Games for iOS: Xcode Setup, Player Settings, and App Store Submission

iOS builds are more complicated than Android builds. Not dramatically more, but there is one constraint that catches every Windows developer off guard: Xcode is only available on macOS, so if your development machine does not run macOS, you cannot build an iOS application locally. You need either a Mac or Unity Build Automation, which handles the Xcode step in the cloud.

That aside, the Unity side of the setup is straightforward. The hard parts are almost always Apple-specific — provisioning profiles, signing certificates, bundle identifiers that have to match exactly across three different places, and Xcode's occasional tendency to refuse to trust a connected device for no obvious reason. None of those are Unity problems. They are Apple problems.

This guide covers the full pipeline: installing iOS Build Support, configuring Player Settings correctly, running on a physical device for testing, signing for the App Store, and fixing the errors that show up on every first iOS build. It pairs directly with the Android Build guide from this series — same structure, iOS-specific details throughout.



What You Need Before Starting

  • A Mac running macOS. Xcode only runs on Mac. An M1/M2/M3/M4 Mac Mini is the cheapest viable option if you are buying specifically for iOS development — they run Xcode without any issues and are significantly faster than older Intel Macs for IL2CPP builds.
  • Xcode 15 or later. Unity recommends Xcode 15 or later for iOS development. Apps submitted to the App Store must be built with Xcode 16.0 or later and the iOS 18 SDK. Install Xcode from the Mac App Store — it is free but large (around 15GB).
  • iOS Build Support module installed through Unity Hub.
  • An Apple ID for local device testing (free). An Apple Developer Program membership ($99/year) for App Store distribution.
  • A physical iPhone or iPad for testing. The iOS Simulator in Xcode runs on your Mac but does not test actual GPU performance, touch input, or device-specific behavior accurately enough to replace real hardware.

If you are on Windows and cannot access a Mac, Unity Build Automation can build iOS applications for you in the cloud. You still need to register for an Apple Developer account, generate certificates and provisioning profiles through the Apple Developer portal, and upload your credentials to Unity Build Automation. That workflow is worth knowing about but is more advanced than a local build — for a first iOS build, a Mac is the significantly simpler path.


 

Part 1: Installing iOS Build Support

  1. Open Unity Hub.
  2. Go to the Installs tab.
  3. Click the gear icon next to your Unity version and select Add Modules.
  4. Check iOS Build Support.
  5. Click Install and wait for the download.

Unlike Android, iOS Build Support has no sub-modules to check — there is no separate SDK or NDK to worry about. Apple's toolchain lives entirely in Xcode. The Unity module just adds the ability to generate an Xcode project from your Unity project. Xcode then handles the actual compilation.

After installation, confirm it worked by opening Unity and going to File > Build Settings. iOS should now appear in the platform list. If it is missing or shows "Install with Unity Hub," the module did not install correctly — go back to Hub and try again.

Part 2: Switching Platform to iOS

  1. In Unity, go to File > Build Settings.
  2. Select iOS from the platform list.
  3. Click Switch Platform.

This reimports your assets for iOS — same process as Android, same warning about it taking a while on larger projects. After the switch, the iOS icon appears next to scene files in the Project window confirming the active platform changed.

Part 3: Player Settings That Matter

Open through Edit > Project Settings > Player, then select the iOS icon tab.

Bundle Identifier

This is the most important iOS-specific setting and the one that causes the most pain when it is wrong. The bundle identifier is the unique ID for your app across Apple's entire ecosystem — it must match exactly between Unity, Xcode, and the Apple Developer portal. If any of the three disagree, the build fails or the app cannot be signed.

Format: com.yourcompany.gamename — same reverse domain notation as Android's package name, same rules: lowercase, no spaces, globally unique for App Store distribution.

Set this before doing anything else. Changing it mid-project is possible but requires updating it in multiple places simultaneously, which is how mismatches happen.

Signing Team

This is your Apple Developer Team ID. You can leave it blank for local device testing with a free Apple ID, but it must be set for any App Store build. It appears as a dropdown once you have signed into Xcode with your Apple ID — set it in Unity Player Settings to match what Xcode will use, or let Xcode manage it automatically by checking "Automatically manage signing" in the Xcode project settings.

Target iOS Version

The minimum iOS version your app supports. Setting it lower means more devices can install it; higher lets you use newer iOS features. For most games in 2026, iOS 15 or 16 as the minimum covers the vast majority of active iPhones while still giving access to modern APIs. Check Apple's App Store analytics for current device distribution if you want data to back the decision.

Architecture

Set to ARM64. All iPhones and iPads from 2017 onward use 64-bit ARM processors. There is no reason to support ARMv7 for new projects — Apple dropped 32-bit app support in iOS 11. ARM64 only.

Scripting Backend

IL2CPP is the only option for iOS — Mono is not supported on iOS due to Apple's restrictions on just-in-time compilation. This is already the default. You cannot accidentally use Mono on iOS; Unity will not let you.



Part 4: Generating the Xcode Project

Unity does not compile your game directly into an iOS app. Instead, it generates an Xcode project, and then Xcode builds that project into the final application. This two-step process is important to understand because it means you will sometimes need to make changes in Xcode rather than in Unity.

  1. In Build Settings, click Build (not Build and Run — we will get to that).
  2. Choose an output folder. Create a new folder called something like "iOSBuild" outside your Unity project folder.
  3. Unity generates the Xcode project files in that folder. It does not install anything to a device yet.
  4. Navigate to that folder in Finder and open the .xcodeproj file. Xcode opens the generated project.

If you use Build and Run instead of Build, Unity generates the project AND tells Xcode to compile and install it to a connected device in one step. Build and Run is faster once everything is set up correctly. Use Build first until you have confirmed the Xcode project generates without errors.

The Replace vs Append Dialog

Every subsequent build to the same output folder shows a dialog asking whether to Replace or Append the existing Xcode project.

  • Replace — completely overwrites the Xcode project. Use this during normal development. Any manual changes you made to the Xcode project are lost.
  • Append — merges Unity's new output into the existing Xcode project, preserving manual changes you added. Use this if you have edited the Xcode project directly to add frameworks or capabilities that Unity does not handle automatically.

Most beginners should always choose Replace until they have a specific reason to edit the Xcode project directly.

Part 5: Testing on a Physical Device

With a Free Apple ID (No Developer Program)

  1. Open the generated .xcodeproj in Xcode.
  2. Connect your iPhone or iPad via USB.
  3. In Xcode, go to Signing & Capabilities and sign in with your Apple ID if prompted.
  4. With a free Apple ID, Xcode creates a personal team that allows you to install apps on up to 3 devices with a 7-day certificate validity. The app will stop working after 7 days and needs to be reinstalled.
  5. Select your connected device from the device dropdown at the top of Xcode.
  6. Press the Play button (or Cmd+R) to build and install.
  7. The first time, your iPhone will show a prompt about trusting the developer — go to Settings > General > VPN & Device Management and trust your Apple ID there.

The 7-day limit is annoying during active development but works fine for quick tests. The Apple Developer Program ($99/year) removes the limit and enables App Store distribution.

With an Apple Developer Program Account

Log into your Apple Developer account at developer.apple.com, register your device's UDID, and create a Development provisioning profile for your bundle identifier. In Xcode, under Signing & Capabilities, either let Xcode manage signing automatically (simplest) or manually select the provisioning profile you created. The certificate validity extends to one year rather than seven days.



Part 6: App Store Submission

Getting to the App Store requires a few steps beyond just building correctly.

Archive the Build in Xcode

  1. In Xcode, set the target device to Any iOS Device (arm64) — not a specific connected device.
  2. Go to Product > Archive.
  3. Xcode builds the app and adds it to the Archives list in the Organizer window.

Upload to App Store Connect

  1. In the Xcode Organizer, select the archive and click Distribute App.
  2. Choose App Store Connect and follow the wizard.
  3. Xcode validates and uploads the build to App Store Connect.

TestFlight First

Before submitting for App Store review, test through TestFlight. Any build uploaded to App Store Connect is automatically available for TestFlight testing with external testers. Testing with real users on TestFlight before App Store submission catches device-specific bugs that neither the Unity editor nor Xcode's simulator will surface.

App Store review typically takes 24 to 48 hours for a new app with no prior rejections. Apple reviews both the app's functionality and its metadata — screenshots, description, and privacy disclosures. Rejections almost always come with an explanation and are fixable.

Common Errors and How to Fix Them

Error: "No profiles for [bundle identifier] were found"

Cause: The bundle identifier in Unity Player Settings does not match what is registered in the Apple Developer portal, or no provisioning profile exists for this identifier.

Fix: Confirm the bundle identifier matches exactly — including case — across Unity, Xcode, and the Apple Developer portal. If using automatic signing, let Xcode create the profile. If using manual signing, create the profile at developer.apple.com and download it.

Error: "IL2CPP C++ code builder is unable to build C++ code. In order to build C++ code for Mac, you must have Xcode installed."

Cause: Xcode is installed but its Command Line Tools are not configured, or Xcode is installed in a non-standard location.

Fix: Open Terminal and run sudo xcode-select --switch /Applications/Xcode.app to point the system to the correct Xcode location. Also open Xcode once and accept the license agreement — it is required before any command-line tools work.

Error: Build succeeds but app crashes immediately on device.

Cause: A script or plugin has a runtime error that does not surface in the editor, or a missing capability (like Push Notifications or Camera access) causes an immediate termination.

Fix: Connect the device to Xcode, go to Window > Devices and Simulators, select your device, and open the device log while reproducing the crash. The actual exception appears there. For missing capabilities, add them under Signing & Capabilities in the Xcode project.

Error: "Untrusted Developer" when opening the app on device.

Cause: The signing certificate is from a free Apple ID and has not been trusted on this device yet.

Fix: On the iPhone, go to Settings > General > VPN & Device Management, find your Apple ID under Developer App, and tap Trust.

Error: App Store submission rejected for privacy reasons.

Cause: The app uses a system API (camera, microphone, location, contacts) without including the corresponding privacy usage description string in Player Settings, or without declaring data collection in App Store Connect's privacy nutrition label.

Fix: In Unity Player Settings > Other Settings, fill in every usage description string for APIs your app uses. In App Store Connect, complete the App Privacy section accurately before submission. Apple's rejections here are specific — they tell you exactly which API triggered the issue.



iOS vs Android Build: Key Differences

Area iOS Android
Build machine requirement Mac required for local builds Windows, Mac, or Linux
Build output Xcode project, then .ipa via Xcode APK or AAB directly from Unity
Scripting backend IL2CPP only — Mono not supported Mono for dev, IL2CPP for release
Signing for device testing Free Apple ID, 7-day certificate Debug keystore auto-generated, no expiry
Store distribution fee $99/year Apple Developer Program $25 one-time Google Play fee
Review process Manual review, 24-48 hours typical Largely automated, hours to days
Primary graphics API Metal (Apple's API, only option) Vulkan or OpenGL ES

Best Practices

  • Set the bundle identifier before your first build. Changing it later means updating it in Unity, Xcode, and the Apple Developer portal simultaneously — missing any one causes signing failures.
  • Use automatic signing in Xcode during development. Switch to manual signing only when you need specific provisioning profiles for distribution.
  • Test on at least two physical devices before App Store submission — an older model and a current one. Performance that looks fine on an iPhone 15 can be unacceptable on an iPhone XR that your players still use.
  • Archive builds in Xcode using the Any iOS Device (arm64) target, not a connected device. Archiving to a specific device creates a build that cannot be distributed.
  • Use TestFlight for beta testing before App Store submission. It finds real-device bugs that nothing else catches.
  • Fill in all privacy usage description strings in Player Settings before building. Missing them causes App Store rejection, and adding them requires a full rebuild and resubmission.
  • Keep your Apple Developer certificates backed up. Certificate expiration mid-submission cycle is a preventable headache.

What Comes Next

Getting the build pipeline working is the foundation. Once you have a device build running, the next iOS-specific considerations are performance profiling using Xcode's Instruments tool (far more detailed than Unity's Profiler for GPU-side issues on Metal), implementing iOS-specific features like Game Center achievements and leaderboards through Unity's Services, and setting up automatic builds using Unity Build Automation or a CI system like GitHub Actions so you are not manually triggering Xcode builds every time you need a test build.

The Mobile Optimization guide from this series covers the Unity-side performance work. The GitHub Actions guide teased at the end of the Git tutorial covers the automation side. Both are worth reading once this build pipeline is stable.

Next Topics To Learn

No comments:

Post a Comment

How to Use ElevenLabs for Game Development: AI Voice Acting, NPC Dialogue, and Sound Design

Most indie games ship without voice acting. Not because developers do not want it, but because hiring voice actors is expensive, scheduling ...