Interacting With iOS Devices
The libimobiledevice suite is the Swiss-army knife for talking to iOS devices over USB without Apple tooling. This page is a cheat sheet of the commands you will use most.
Device Discovery
idevice_id -l # list connected UDIDs (also -u for details)
ideviceinfo # dump device info as key=value pairs
ideviceinfo -k ProductVersion # single value, e.g. the iOS version
ideviceinfo -k ProductType # e.g. iPhone14,5
App Install / Uninstall / List
ideviceinstaller -l # list installed apps (bundle IDs)
ideviceinstaller -i /path/app.ipa # install an IPA
ideviceinstaller -u com.example.app # uninstall by bundle ID
ideviceinstaller -U # upgrade an IPA
ideviceinstaller -o app_only # list only user apps
Real-Time System Logs
idevicesyslog # stream the device syslog to the terminal
idevicesyslog --match com.example # filter by a string (process/bundle prefix)
# Pipe to a file for review
idevicesyslog > device.log
Launching and Debugging Apps
# Launch an app by bundle ID and (optionally) pass arguments
idevicedebug run com.example.app
idevicedebug run com.example.app -- arg1 arg2
# Capture a crash report for a running/failed app
idevicecrashreport --extract . # save crash logs to ./ and remove from device
Port Forwarding (USB Tunnel)
# Forward device port 22 (SSH) to local 2222 over USB
iproxy 2222 22
# Forward a range, e.g. device 4444 -> local 4444
iproxy 4444
# Bind only on loopback by default; add -l to listen on all interfaces
iproxy -l 2222 22
Once iproxy 2222 22 is running you can:
ssh root@localhost -p 2222
Apple Configurator / cfgutil
cfgutil ships with Apple Configurator and complements the idevice* tools, especially for automation on macOS.
# List devices
cfgutil list
# Get device ECID / serial / product type
cfgutil get ecid
cfgutil get serial
# Run a command on all connected devices
cfgutil -e 0xE3C9... install /path/app.ipa
# Reboot/resume a device
cfgutil -e 0xE3C9... reboot
# Launch an app by bundle id
cfgutil -e 0xE3C9... launch com.example.app
The -e <ecid> flag targets a specific device; all targets everything.
App Data Access
On a physical device, app containers live under /var/mobile/Containers/Data/Application/<UUID>/. On a jailbroken device you can browse them over SSH. On a simulator, simctl gives you the path directly.
# Simulator: absolute path to the data container
xcrun simctl get_app_container "iPhone 15 Pro" com.example.app data
# Simulator: path to the app bundle itself
xcrun simctl get_app_container "iPhone 15 Pro" com.example.app app
# Copy a database out for local inspection
cp "$(xcrun simctl get_app_container "iPhone 15 Pro" com.example.app data)/Documents/app.sqlite" .
On a jailbroken device over SSH:
# After iproxy 2222 22 and ssh root@localhost -p 2222
find /var/mobile/Containers/Data/Application -maxdepth 1 -type d
ls "/var/mobile/Containers/Data/Application/<UUID>/Documents"
Pairing and Provisioning
idevicepair validate # is the host paired/trusted with the device?
idevicepair pair # initiate pairing manually
idevicepair unpair # remove pairing
Common Gotchas
- If
idevice_id -lshows nothing, the device is locked, untrusted, or the USB cable is charge-only. - After a device reboot, re-run
idevicepair validate; pairing can be dropped. ideviceinstaller -llists user + system apps depending on the device state; filter with-o app_only.- On newer iOS you may need the matching libimobiledevice version; update via brew before troubleshooting odd errors.