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.