Skip to content
xcross
Documentation menu

FAQ

Common questions about xcross - supported hosts, Apple accounts, devices, plugins, iOS versions and where credentials live.

Short answers to the questions that come up most often. Anything not covered here is probably in Troubleshooting or the Architecture deep dive.

Do I need a Mac or Xcode installed?

No. xcross runs natively on Windows and Linux and never installs or executes Xcode or macOS. You do need a complete Xcode.xip archive once, downloaded from https://xcodereleases.com/ with an Apple ID, because that archive is the only legal source of the iOS SDK and frameworks. xcross sdk install extracts the iOS subset from it with its own pure-Dart xar, pbzx and cpio readers.

Why is there no release or AOT output?

Flutter’s gen_snapshot for iOS AOT only runs on macOS hosts - Dart does not cross-compile an iOS AOT executable from Windows or Linux. Debug (JIT) runs don’t need it, which is exactly what xcross targets. Release/AOT output still needs Flutter’s macOS toolchain.

Which iOS versions are supported?

Launching with xcross requires iOS 17 or later on the device. iOS 17 replaced the old debug-launch path with CoreDevice over an encrypted RSD tunnel, and that is the path xcross implements. xcross flutter run reads the device OS version and refuses to install onto anything older.

Does it work in WSL?

Yes. xcross runs in WSL like on any other Linux host - you only have to hand the iPhone through to the Linux side, because WSL has no USB stack of its own. Attach the device with usbipd-win, then run xcross setup and the rest of the flow inside WSL exactly as documented.

Running natively on Windows or Linux stays the simplest option, since no device forwarding is involved at all. What xcross never needs is macOS - there is no macOS VM and no remote Mac anywhere in the pipeline.

Does a free Apple ID work?

Yes. xcross auth --apple-id you@example.com works with a free Apple account. xcross talks to Apple’s Developer Services directly to register the device, request a certificate, and issue a provisioning profile. If you have an App Store Connect API key instead, use xcross auth --issuer-id <uuid> --key-id <id> --private-key /path/to/AuthKey.p8. When both are saved, a valid Apple ID session takes precedence over the API key.

Is my Apple password stored anywhere?

No. xcross auth performs the login handshake locally and persists only the resulting Developer Services session token.

What does xcross tunnel do, and why does it need elevation?

It mounts the Developer Disk Image and starts the pymobiledevice3 RSD tunnel - the encrypted QUIC/TUN tunnel iOS 17+ requires for developer services. Creating the TUN interface needs an Administrator PowerShell on Windows or root on Linux. Run it once per device reconnect.

Can I use xcross in CI?

Partly, and with caveats. Device selection is non-interactive if you pass -u <UDID>; without it, an interactive terminal shows a numbered device picker. Apple ID login prompts for a password and a 2FA code on a terminal, so an App Store Connect API key is the better fit for unattended runs. xcross tunnel still needs an elevated shell and a physically connected iPhone.

What about CocoaPods plugins?

Swift Package Manager iOS plugins are supported on both Windows and Linux; their native code is compiled against the extracted Darwin SDK into Frameworks/libFlutterPluginsGenerated.dylib and registered by the generated runner. Plugins that provide only a CocoaPods podspec are currently skipped with a warning - prefer plugin releases that include ios/<package_name>/Package.swift.

Does it support Compose Multiplatform?

Not yet. xcross currently supports Flutter applications only.

Is the extracted Apple SDK redistributable?

No. The Xcode.xip archive is used only as SDK input, and the extracted iOS SDK stays on your machine. Don’t redistribute it. Each developer should download their own archive from https://xcodereleases.com/ and run xcross sdk install once.

How do I use multiple iPhones?

With several devices connected, an interactive terminal shows a numbered device picker. Pass -u <UDID> to target one directly, which is also what you want for CI or piped runs. -d <id-or-name> selects flutter-style by device id or name, and --usb / --wifi / --device-connection narrow discovery. In VS Code, set "args": ["--udid", "<UDID>"] on the xcross launch entry - re-running xcross ide vscode preserves those args.

Where is configuration stored?

Under %APPDATA%\xcross on Windows and $XDG_CONFIG_HOME/xcross (usually ~/.config/xcross) on Linux. That is where the Developer Services session and App Store Connect credentials live, and where the ADI attestation libraries are cached in an adi-libs subdirectory. On Windows x64 and Linux x86_64 those libraries are downloaded automatically from the Apple Music APK on first use; on other architectures, extract the matching APK slice yourself and pass --adi-library-dir.

Do I have to re-run setup after every reboot?

xcross setup and xcross sdk install are one-time steps per machine and per Xcode archive. xcross tunnel is the recurring one: run it once per device reconnect, from an elevated shell.

Still stuck?

Check Troubleshooting for the common failure modes and their fixes, and re-run the failing command with -v to get the full tool output. If that doesn’t resolve it, open an issue at https://github.com/arxdeus/xcross/issues with the verbose log, your host OS, and the device iOS version.

ESC