Overview
Exporting to iOS requires a Mac with Xcode installed and an Apple Developer account. The process involves code signing, provisioning profiles, and App Store submission.
Prerequisites
Required software
macOS computer
iOS export requires macOS. Virtual machines are not officially supported by Apple.
Install Xcode
Download Xcode from the Mac App Store (free)
Install command line tools
You can test on your own devices with a free Apple Developer account, but App Store publishing requires a paid account.
Creating iOS export preset
Go to Project > Export
Click Add… and select iOS
Configure preset settings
Basic configuration
# Essential iOS export settings
# Configured in the export preset
# App identifier (reverse domain notation)
Identifier : "com.yourcompany.yourgame"
# App name
Name : "My Game"
# Version
Version : "1.0.0"
# Build number (increment for each build)
Build Number : "1"
# Minimum iOS version
iOS Version : "12.0"
# Targeted device family
Targeted Device Family : 1 , 2 # 1=iPhone, 2=iPad
Code signing
iOS apps must be signed with certificates and provisioning profiles.
Creating certificates
Generate certificate request
Open Keychain Access on Mac
Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority
Enter email and name, save to disk
Create certificate in Apple Developer portal
Go to https://developer.apple.com/account
Certificates, IDs & Profiles > Certificates
Create iOS Development and iOS Distribution certificates
Upload certificate request
Download and install certificates
Provisioning profiles
For testing on your devices:
Register device UDIDs in Apple Developer portal
Create App ID matching your bundle identifier
Create Development provisioning profile
Download and install profile
For App Store distribution:
Create App ID in Apple Developer portal
Create App Store provisioning profile
Download profile
Configure in Godot export preset
Automatic signing
# In export preset
Automatically Manage Signing : true
Team ID : "YOUR_TEAM_ID" # From Apple Developer account
Automatic signing is simpler but requires Xcode. Manual signing gives more control.
Export process
Export Xcode project
Godot exports an Xcode project that you build with Xcode:
# Export from command line
godot --headless --export-debug "iOS" "builds/ios/"
# This creates an Xcode project in builds/ios/
Build in Xcode
Open project
Open the exported .xcodeproj file in Xcode
Select target
Choose your device or simulator from the target dropdown
Configure signing
Go to project settings > Signing & Capabilities
Select your team and provisioning profile
Build and run
Click the Play button or Product > Run (Cmd+R)
App icons
iOS requires multiple icon sizes:
# Configure in export preset
Icons :
iPhone 120 x 120 ( 2 x): "res://icons/icon_120.png"
iPhone 180 x 180 ( 3 x): "res://icons/icon_180.png"
iPad 152 x 152 ( 2 x): "res://icons/icon_152.png"
iPad 167 x 167 ( 2 x): "res://icons/icon_167.png"
App Store 1024 x 1024 : "res://icons/icon_1024.png"
All icons should be square PNG files without transparency or rounded corners. iOS applies the shape automatically.
Launch screens
Configure launch screen (splash screen):
# Storyboard launch screen
Launch Screen :
Type : "Storyboard"
Storyboard : "res://launch_screen.storyboard"
Background Color : Color ( 0 , 0 , 0 , 1 )
# Or use image
Launch Screen :
Type : "Image"
Image : "res://splash.png"
Background Color : Color ( 0 , 0 , 0 , 1 )
Capabilities and permissions
Required capabilities
# Enable in export preset under "Capabilities"
# Common capabilities
Camera Usage : true
Microphone Usage : true
Location Services : true
Push Notifications : true
GameCenter : true
In - App Purchase : true
Privacy descriptions
iOS requires descriptions for permission requests:
<!-- In Info.plist -->
< key > NSCameraUsageDescription </ key >
< string > This app needs camera access for photo features </ string >
< key > NSMicrophoneUsageDescription </ key >
< string > This app needs microphone access for voice chat </ string >
< key > NSLocationWhenInUseUsageDescription </ key >
< string > This app needs your location for nearby features </ string >
Configure in export preset:
Privacy :
Camera Usage Description : "App needs camera for photos"
Microphone Usage Description : "App needs microphone for chat"
Location Usage Description : "App needs location for features"
iOS plugins
Extend functionality with iOS plugins:
Native plugin example
// MyPlugin.swift
import Foundation
@objc public class MyPlugin : NSObject {
@objc public func showAlert ( _ message : String ) {
DispatchQueue. main . async {
let alert = UIAlertController (
title : "Alert" ,
message : message,
preferredStyle : . alert
)
alert. addAction ( UIAlertAction ( title : "OK" , style : . default ))
if let window = UIApplication.shared.windows. first ,
let rootVC = window.rootViewController {
rootVC. present (alert, animated : true )
}
}
}
}
Use from GDScript:
var my_plugin
func _ready ():
if Engine . has_singleton ( "MyPlugin" ):
my_plugin = Engine . get_singleton ( "MyPlugin" )
my_plugin . showAlert ( "Hello from iOS!" )
Screen orientation
# Configure in export preset
Supported Orientations :
Portrait : true
Portrait Upside Down : false
Landscape Left : true
Landscape Right : true
# Change at runtime
DisplayServer . window_set_orientation ( DisplayServer . SCREEN_LANDSCAPE )
TestFlight
Test your app with beta testers:
Archive app
In Xcode: Product > Archive
Upload to App Store Connect
Window > Organizer > Distribute App > App Store Connect
Configure TestFlight
In App Store Connect, add beta testers and submit for review
Distribute to testers
Once approved, testers receive TestFlight invite
Publishing to App Store
Preparing for submission
Create app in App Store Connect
Prepare metadata
App name and subtitle
Description and keywords
Screenshots (required sizes for each device)
App icon (1024x1024)
Privacy policy URL
Build release version
Create archive in Xcode with App Store provisioning profile
Upload to App Store Connect
Use Xcode Organizer or Transporter app to upload
App Review guidelines
Complete app App must be fully functional, not a demo or beta.
Accurate metadata Screenshots and descriptions must match actual app.
No crashes Thoroughly test to ensure stability.
Privacy compliance Include privacy policy and comply with data regulations.
In-App Purchases
Implement IAP for monetization:
var store
func _ready ():
if Engine . has_singleton ( "InAppStore" ):
store = Engine . get_singleton ( "InAppStore" )
store . request_product_info ([ "com.example.product1" ])
func purchase_product ( product_id : String ):
store . purchase ({ "product_id" : product_id })
Game Center
Integrate Game Center for leaderboards and achievements:
var game_center
func _ready ():
if Engine . has_singleton ( "GameCenter" ):
game_center = Engine . get_singleton ( "GameCenter" )
game_center . authenticate ()
func post_score ( score : int , leaderboard : String ):
game_center . post_score ({ "score" : score , "category" : leaderboard })
func unlock_achievement ( achievement_id : String ):
game_center . award_achievement ({ "name" : achievement_id })
Use Metal Metal is the default graphics API on iOS for best performance.
Optimize for battery Limit frame rate and reduce background processing.
Test on real devices Simulator doesn’t reflect actual device performance.
Use mobile renderer Select Mobile renderer for better performance on iOS devices.
Device-specific code
func _ready ():
if OS . get_name () == "iOS" :
# iOS-specific code
print ( "iOS version: " , OS . get_version ())
print ( "Device model: " , OS . get_model_name ())
# Get safe area (for iPhone X notch)
var safe_area = DisplayServer . get_display_safe_area ()
# Adjust UI for safe area
adjust_ui_for_safe_area ( safe_area )
Troubleshooting
Code signing issues
No valid provisioning profiles
Ensure provisioning profile matches bundle ID and is not expired.
Install certificates in Keychain Access and ensure they’re valid.
Verify Team ID matches your Apple Developer account.
Build errors
# Clean build folder
rm -rf ~/Library/Developer/Xcode/DerivedData
# Reset provisioning profiles
rm -rf ~/Library/MobileDevice/Provisioning \ Profiles
# Re-download from Apple Developer portal
App Store rejection common causes
Crashes or bugs
Incomplete functionality
Misleading screenshots
Missing privacy policy
Guideline violations
Incomplete app information
Next steps
Android Export for Android devices
Web Export for web browsers
Desktop Export for desktop platforms