Skip to main content

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 -l shows 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 -l lists 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.