iOS automation with Appium runs exclusively on macOS. There is no way around this — Xcode, which Appium relies on through WebDriverAgent, is macOS-only software. If your CI infrastructure is Linux-only, you need a macOS agent for iOS tests. This lesson covers the full setup from Xcode installation through running your first session against a Simulator and a real device.
Install Xcode
Install Xcode from the Mac App Store. It is large (10–15 GB) and takes time. After installation:
# Accept the Xcode license
sudo xcodebuild -license accept
# Verify installation
xcode-select -p
# Should return: /Applications/Xcode.app/Contents/Developer
# Install command line tools if needed
xcode-select --installCheck the Xcode version:
xcodebuild -versionAppium's XCUITest driver has a minimum Xcode version requirement — check the driver's release notes. At the time of writing, Xcode 15+ is recommended.
iOS Simulators
Xcode ships with several Simulator runtimes. To see what's installed:
xcrun simctl list devices availableTo install additional runtime versions, open Xcode → Settings → Platforms and download the iOS versions you need.
Starting a Simulator via command line
# List all devices with their UDIDs
xcrun simctl list devices
# Boot a specific Simulator
xcrun simctl boot "iPhone 15 Pro"
# Open the Simulator app (required to see the UI)
open -a Simulator
# Shutdown
xcrun simctl shutdown "iPhone 15 Pro"
# Erase all content (clean state)
xcrun simctl erase "iPhone 15 Pro"Installing an app on a Simulator
xcrun simctl install booted /path/to/MyApp.appNote: .app bundles (not .ipa) are used for Simulators. An .ipa is a signed archive for real devices. If your build system only outputs .ipa, extract the .app from inside it:
unzip MyApp.ipa -d extracted/
# The .app bundle is at extracted/Payload/MyApp.appAppium capabilities for a Simulator
XCUITestOptions options = new XCUITestOptions();
options.setPlatformVersion("17.2");
options.setDeviceName("iPhone 15 Pro");
options.setApp("/absolute/path/to/MyApp.app");
IOSDriver driver = new IOSDriver(new URL("http://127.0.0.1:4723"), options);The deviceName must match the Simulator name exactly as shown by xcrun simctl list devices. Appium will boot the Simulator if it is not already running.
Real device setup
Real iOS devices require more configuration because Apple's code signing must be satisfied.
Prerequisites
- An Apple Developer account (free accounts work with limitations; a paid $99/year Developer Program membership gives full access)
- Xcode signed in to your Apple ID: Xcode → Settings → Accounts → Add Apple ID
- The device UDID
Find the device UDID
Connect the device via USB. Open Xcode → Window → Devices and Simulators. The UDID is shown next to the device name. Copy it.
Alternatively:
xcrun xctrace list devicesCreate a provisioning profile for WebDriverAgent
Appium installs its own automation agent (WebDriverAgent) on your real device. WDA must be signed with a valid certificate. The simplest way:
- Open Terminal:
open $(appium driver doctor xcuitest --extra-capability wdaLocalPort 2>/dev/null || find ~/.nvm ~/.npm -name "WebDriverAgent.xcodeproj" 2>/dev/null | head -1 | xargs dirname)
Or find it directly:find / -name "WebDriverAgent.xcodeproj" 2>/dev/null | head -1 - Open
WebDriverAgent.xcodeprojin Xcode - Select the
WebDriverAgentLibandWebDriverAgentRunnertargets - Under Signing & Capabilities, set your Team to your Apple ID
- Change the Bundle Identifier to something unique (e.g.,
com.yourname.WebDriverAgentRunner) - Build the target once to verify signing works
Appium capabilities for a real device
XCUITestOptions options = new XCUITestOptions();
options.setUdid("00008101-001A2B3C4D5E6F78"); // exact UDID
options.setPlatformVersion("17.2");
options.setApp("/absolute/path/to/MyApp.ipa");
options.setXcodeOrgId("ABCDE12345"); // your Team ID from developer.apple.com
options.setXcodeSigningId("iPhone Developer");
IOSDriver driver = new IOSDriver(new URL("http://127.0.0.1:4723"), options);Granting permissions via simctl
Pre-granting permissions on a Simulator avoids dialog interruptions during tests:
# Grant location permission
xcrun simctl privacy booted grant location com.example.myapp
# Grant camera permission
xcrun simctl privacy booted grant camera com.example.myapp
# Reset all permissions (use before a clean test run)
xcrun simctl privacy booted reset all com.example.myappAppium's appium-doctor check for iOS
appium-doctor --iosCommon red flags and fixes:
| Issue | Fix |
|---|---|
| Xcode not found | Install from App Store, run sudo xcodebuild -license accept |
libimobiledevice missing | brew install libimobiledevice |
ios-deploy missing | brew install ios-deploy (required for real devices) |
carthage missing | brew install carthage (needed for older WDA builds) |
Choosing between Simulator and real device
Use a Simulator for daily development, CI regression, and anything that does not require hardware. Use a real device for:
- App Store sign-off testing
- Face ID / Touch ID flows (even then, the Simulator can mock the result)
- Push notification delivery verification
- In-app purchases
- NFC-dependent features
- Accurate memory and battery behaviour