Alternatives to Auto-UDID Detection in iOS Simulator Skill: 6 Fallback Methods
TLDR: When automatic UDID detection fails because no simulator is currently booted, the iOS Simulator Skill offers six fallback strategies—including explicit UDID strings, device name matching, partial name searches, the "booted" shortcut, manual booting, and programmatic selection—all unified through the resolve_device_identifier() function in device_utils.py.
The iOS Simulator Skill is an open-source Python utility that streamlines iOS simulator management through command-line automation. While it attempts to auto-detect the target device's UDID by checking for booted simulators, this mechanism fails when no device is running, requiring developers to specify alternatives to auto-UDID detection through various identifier formats.
How Auto-UDID Detection Works in device_utils.py
The automatic detection flow begins in ios-simulator-skill/scripts/common/device_utils.py. The resolve_udid() function first checks for an explicitly provided --udid argument. If none exists, it calls get_booted_device_udid() to scan for currently running simulators. When both checks return empty, the library raises a RuntimeError with instructions to provide a valid identifier.
Six Alternatives to Auto-UDID Detection
When the auto-detection path fails, developers can use these six fallback methods, all processed through resolve_device_identifier():
1. Provide an Explicit UDID String
The most reliable alternative is passing the full 40-character UDID directly via the command line. In resolve_udid(), if a valid UDID format is detected, the function returns it unchanged.
python scripts/simctl_boot.py --udid ABC12345-6789-DEF0-1234-56789ABCDEF0
2. Use Exact Device Names
Instead of memorizing hex strings, you can pass the simulator's display name. The resolve_device_identifier() function queries list_simulators() to match the string against the name field.
python scripts/app_launcher.py --udid "iPhone 16 Pro"
3. Match Partial Device Names
For convenience, partial matches work through case-insensitive containment checks. Passing "iPhone 16" matches the first simulator containing that substring.
python scripts/gesture.py --udid "iPhone 16"
4. Force the "booted" Shortcut
The special identifier "booted" explicitly triggers get_booted_device_udid(), ensuring you target the currently running simulator even if auto-detection skipped it.
python scripts/keyboard.py --udid booted
5. Boot a Simulator Manually
When no device is running, manually boot one first using xcrun simctl, then run your script without arguments to leverage auto-detection.
xcrun simctl boot "iPhone 16 Pro"
python scripts/simctl_shutdown.py
6. Programmatic Selection via list_simulators()
For custom logic, call list_simulators(state="available") or state="booted" directly, then pass the selected UDID to resolve_device_identifier().
from ios_simulator_skill.scripts.common.device_utils import list_simulators, resolve_device_identifier
available = list_simulators(state="available")
newest = max(available, key=lambda s: s["runtime"])
udid = resolve_device_identifier(newest["name"])
Summary
- Explicit UDID arguments bypass all detection logic for guaranteed targeting.
- Device names (exact or partial) resolve through
resolve_device_identifier()indevice_utils.py. - The "booted" shortcut forces selection of the currently running simulator.
- Manual booting enables auto-detection to succeed on subsequent script runs.
- Programmatic selection via
list_simulators()supports custom filtering logic like iOS version targeting. - All alternatives ultimately route through
resolve_device_identifier()to ensure valid UDID resolution before executingsimctloridbcommands.
Frequently Asked Questions
What happens if I don't provide any UDID and no simulator is booted?
The resolve_udid() function raises a RuntimeError with a message indicating that no device was found and suggesting you provide a valid UDID, device name, or boot a simulator first.
Can I use partial device names like "iPad" instead of full names?
Yes. The resolve_device_identifier() function performs case-insensitive substring matching against all simulator names when an exact match isn't found.
Is there a way to always target whatever simulator is currently running?
Yes. Pass the special identifier "booted" as the UDID argument. This explicitly calls get_booted_device_udid() to return the UDID of the currently booted device.
How do I list all available simulators programmatically?
Import list_simulators() from device_utils.py and call it with state=None for all devices, state="available" for shutdown devices, or state="booted" for running ones. The function returns a list of dictionaries containing name, udid, and runtime keys.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →