Skip to main content
Tutorials

Unity iOS Build on Windows: Xcode Project to iPhone and ipa

Last updated

A Unity iOS build on Windows can happen entirely on one PC. Switch to iOS, set Player Settings and use “Build” to export the Xcode project. Then open the export folder in VS Code, run doctor and press F5 to compile the IL2CPP code and install it on your iPhone. Check frame rate and memory with kxdevice, and build a Release .ipa for the App Store, with no copying to a Mac. Menu differences between Unity 6 and 2022 are noted along the way. You need an Apple Developer account, an iPhone, a USB cable and KXBuild installed.

How do you switch Unity to the iOS platform?

Open the project in Unity and go to File > Build Profiles (File > Build Settings in Unity 2022 and earlier). Select iOS on the left and click “Switch Platform”. The first switch reimports assets, which takes a while for large projects.

“Build And Run” calls Xcode on the local machine, so it doesn’t work on Windows. This tutorial uses only “Build”.

Which Player Settings must you set?

Click “Player Settings” in the Build Profiles window, or go to Edit > Project Settings > Player, and switch to the iOS tab. The settings below directly affect installing on a device and submitting to the App Store. In Unity 6, check Override Default Bundle Identifier before you can edit Bundle Identifier.

Location Setting Recommended value
Other Settings > Identification Bundle Identifier Matches the App ID registered in your developer account, for example com.example.mygame
Other Settings > Identification Version The version shown on the App Store, for example 1.0.0
Other Settings > Identification Build The build number. Each upload to App Store Connect needs a higher one than the last
Other Settings > Identification Signing Team ID Your developer account’s Team ID
Other Settings > Configuration Scripting Backend IL2CPP, the only one iOS supports
Other Settings > Configuration Architecture ARM64
Other Settings > Configuration Target SDK Device SDK. A project exported with Simulator SDK can’t be installed on a device
Other Settings > Configuration Target minimum iOS Version The oldest iOS version you want to support. The default is fine too
Other Settings > Configuration Camera Usage Description Required if you use the camera
Other Settings > Configuration Microphone Usage Description Required if you use the microphone
Other Settings > Configuration Location Usage Description Required if you use location

Usage descriptions are written into the exported project’s Info.plist. If the game uses the camera, microphone or location without a description, it crashes as soon as it makes the call, and App Review rejects it.

Put the .p12 certificate and .mobileprovision provisioning profile for signing in the keychain folder. During development, use an Apple Development certificate and a Development provisioning profile that includes this iPhone’s UDID. For how to get and place them, see iOS code signing on Windows.

How do you export the Unity Xcode project?

Click “Build” in the Build Profiles window and choose an empty folder, such as D:\u\mygame. Use a short path for the export folder. The project Unity exports nests deeply, and a deep path easily runs into path-too-long errors on Windows.

While testing, you can check “Development Build” for more complete logs on errors and a connection to the Unity Profiler. Remember to uncheck it before your production build.

After the export, the folder contains Unity-iPhone.xcodeproj. If the project uses plugins with iOS dependencies, such as Firebase or Google Mobile Ads, the folder also has a Podfile. Run pod install once in the export folder, which creates Unity-iPhone.xcworkspace.

1cd D:\u\mygame
2pod install

For more on CocoaPods, see Develop iOS apps with CocoaPods on Windows.

How do you open the export in VS Code and run doctor?

In VS Code, open the export folder D:\u\mygame with File > Open Folder…. The KXBuild view lists its project and targets. The app target is Unity-iPhone. The other one, UnityFramework, is a framework it depends on and is compiled along with it.

The first time you open it, run doctor. It checks what the build needs and fixes anything missing. Use either of these.

  • VS Code extension. In the title bar of the KXBuild view, open the ··· menu and run Doctor (fix environment).
  • Command line. Run the command below in the export folder.
1kxbuild doctor .\Unity-iPhone.xcodeproj

How do you test the build on your iPhone?

Connect the iPhone with a cable, unlock it and tap Trust in the Trust This Computer prompt, then turn on Developer Mode in Settings > Privacy & Security > Developer Mode. The iPhone restarts once. For drivers and iPhone settings, see Set up your device.

Select the iPhone in the KXBuild view and press F5. KXBuild builds, signs, installs and launches the game, then attaches the debugger. The first compile of the C++ code generated by IL2CPP takes a while, and later builds are incremental. The first time you debug on a given iOS version, KXBuild also downloads its device symbols. It’s a few GB, but only once.

While the game runs, output from Debug.Log and the like appears in the KXBuild Console channel of the VS Code Output panel, and the build log in the KXBuild channel. Open the Output panel with Ctrl+Shift+U and switch channels from the dropdown at the top right.

Each kind of code uses its own debugger.

  • Native code (Objective-C plugin code in the export folder). Set breakpoints in VS Code. See Run and debug.
  • C# scripts. Use Unity’s own debugger. Write them in Unity as usual and export again after changes.

To reinstall without recompiling, use KXBuild: Run in the title bar of the KXBuild view. It installs the output of the last build and launches it.

After C# changes, Append or Replace?

After changing C# scripts, scenes or assets, Build again in Unity to the same folder. When the folder exists, Unity asks whether to Append or Replace.

Choice When to use it
Append Day-to-day iteration. Updates what Unity generates and keeps your changes to the exported project
Replace After upgrading Unity, or when the exported project has build errors you can’t explain. The whole folder is regenerated and manual changes are lost

After Replace, run pod install again if there’s a Podfile, then run doctor once more. After exporting, go back to VS Code and press F5. KXBuild recompiles only what changed.

For native changes you want to keep, such as extra Info.plist keys or build settings, write them in at export time with a Unity PostProcessBuild script so Replace doesn’t lose them. For one-off changes, edit the exported project directly with the Property List Editor and Project Settings Editor.

How do you check frame rate and memory on the device?

Sample frame rate, CPU and memory on the device with kxdevice to get numbers close to what players see. Install a Release build before measuring.

1kxbuild build .\Unity-iPhone.xcodeproj -c Release -t Unity-iPhone --install
2kxdevice instruments sysmon -i 1

sysmon prints CPU usage continuously. For dropped frames, memory growth and hot functions, use fluidity, allocations and stackshot. See Performance profiling for the full table and usage. Unity’s built-in Profiler is better for script and rendering timings, and the two work well together.

How do you build a Unity Release .ipa?

Before submitting, make sure Build in Player Settings is higher than in your last upload, and that the keychain folder has an Apple Distribution certificate and an App Store provisioning profile. If you changed Player Settings, export again.

Use either of these.

  • VS Code extension. Run KXBuild: Build for App Store (.ipa) from the Command Palette or the project’s right-click menu.
  • Command line. The target is always Unity-iPhone. Run the command that fits your export folder.

For an export folder without a Podfile, run this.

1kxbuild build .\Unity-iPhone.xcodeproj -c Release --export app-store -t Unity-iPhone

For an export folder with a Podfile where you’ve already run pod install, run this.

1kxbuild build .\Unity-iPhone.xcworkspace -c Release --export app-store -t Unity-iPhone

--export app-store signs with the Apple Distribution certificate and App Store provisioning profile in the keychain folder, whatever certificate the project is set to use. If it reports that no App Store profile was found, put the App Store .mobileprovision in keychain, along with the Distribution .p12 and its password in password.properties.

When the build finishes, the .ipa is in the build folder of the export folder. Upload it to App Store Connect with Appuploader on Windows. When processing finishes, it appears on the TestFlight page. Send it to testers first, then submit it for review. See Release and App Store submission. From then on, every Unity iOS build on Windows is two steps: Build to the same folder in Unity, then build the App Store .ipa in VS Code.

FAQ

What if you get “scheme or target not found”?

Pass the app target on the command line. The app target in a Unity export is Unity-iPhone. On the command line, pass -t Unity-iPhone.

What if you get “file name too long” or “file not found”?

Move the export folder to a short path such as D:\u\mygame and Build again.

What if the build can’t find Firebase or other dependencies?

Run pod install in the export folder and build Unity-iPhone.xcworkspace.

Why does the game quit right after launch?

Usually a usage description is missing. First check that the usage descriptions are filled in, then look at device logs and crash reports. See Run and debug and Troubleshooting.

Does Unity’s “Build And Run” work on Windows?

No. “Build And Run” calls Xcode on the local machine. On Windows, use “Build” to export the project, then press F5 in VS Code to build, install and launch it.