tinyios is cross platform software to talk to ios devices over usb or wifi. It mimics a small set of features that can be done via xcode, developer tools and system settings on a mac.
It exposes itself as a HTTP server so it can be accessed from anywhere. It is also stateless and rootless which makes it easy to run as an ephemeral container.
tinyios depends on usbmuxd installed on the host machine to manage device pairing and device communication through usb or wifi. You will also need to make usbmuxd on the host available inside the container.
The main purpose of tinyios is to set up ios devices and then talk to them via Appium WebDriver commands. Once a device is set up, drive it through the WDA passthrough — everything under /{udid}/wda/cmd/ is forwarded straight to WebDriverAgent on the device.
-
Forward device to WSL
-
Install dependencies
To use tinyios on Linux or WSL you need to install usbmuxd to handle device pairing and device communication. You can run these commands to install or update existing usbmuxd to the latest version
git clone https://github.com/libimobiledevice/usbmuxd.git cd usbmuxd ./autogen.sh make sudo make installYou will also need socat to make usbmuxd available from the host to container
sudo apt install socat sudo socat TCP-LISTEN:27015,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxd
-
Run latest container image on port 8080
docker run --rm \ -p 8080:8080 \ -e USBMUXD_SOCKET_ADDRESS=host.docker.internal:27015 \ albinstman/tinyios
-
Install dependencies
To use tinyios on Linux or WSL you need to install usbmuxd to handle device pairing and device communication. You can run these commands to install or update existing usbmuxd to the latest version
git clone https://github.com/libimobiledevice/usbmuxd.git cd usbmuxd ./autogen.sh make sudo make installYou will also need socat to make usbmuxd available from the host to container
sudo apt install socat sudo socat TCP-LISTEN:27015,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxd
-
Run latest container image on port 8080
docker run --rm \ -p 8080:8080 \ -e USBMUXD_SOCKET_ADDRESS=host.docker.internal:27015 \ albinstman/tinyios
- Make usbmuxd available for container
brew install socat socat TCP-LISTEN:27015,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxd
- Run latest container image on port 8080
docker run --rm \ -p 8080:8080 \ -e USBMUXD_SOCKET_ADDRESS=host.docker.internal:27015 \ albinstman/tinyios
The API Reference below is generated from the annotations on the handlers in main.go. After changing or adding an endpoint, regenerate it with:
make docsBase URL http://localhost:8080 — every response is JSON.
Device-scoped routes take the target device's udid as the first path segment. List connected devices with GET /devices to find it.
| Method | Endpoint | Description | |
|---|---|---|---|
| Device | |||
GET |
/devices |
List devices | |
POST |
/{udid}/erase |
Erase device | |
GET |
/{udid}/processes |
List processes | |
POST |
/{udid}/reboot |
Reboot device | |
| Pairing | |||
POST |
/{udid}/pair/enable |
Enable pairing | |
GET |
/{udid}/paired |
Check pairing status | |
| Activation | |||
POST |
/{udid}/activate/enable |
Enable activation | |
GET |
/{udid}/activated |
Check activation status | |
| Supervision | |||
POST |
/{udid}/supervise/enable |
Enable supervision | |
GET |
/{udid}/supervised |
Check supervision status | |
| Developer | |||
GET |
/{udid}/devmode |
Check developer mode status | |
POST |
/{udid}/devmode/enable |
Enable developer mode | |
GET |
/{udid}/image |
Check developer disk image status | |
POST |
/{udid}/image/enable |
Mount developer disk image | |
| Profiles | |||
POST |
/{udid}/profiles/add |
Add profile | |
POST |
/{udid}/profiles/http |
Set global HTTP proxy | |
GET |
/{udid}/profiles/list |
List profiles | |
| Apps | |||
POST |
/{udid}/apps/install |
Install application | |
POST |
/{udid}/apps/kill |
Kill application | |
GET |
/{udid}/apps/list |
List applications | |
POST |
/{udid}/apps/run |
Run application | |
| WDA | |||
ANY |
/{udid}/wda/cmd/ |
WebDriverAgent passthrough | |
POST |
/{udid}/wda/kill |
Kill WebDriverAgent | |
POST |
/{udid}/wda/run |
Run WebDriverAgent |
Returns a list of all connected iOS devices
curl http://localhost:8080/devicesErases all content and settings from the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/eraseReturns a list of running processes on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/processesReboots the specified iOS device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/rebootPairs the device using the provided certificate
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/pair/enableReturns whether the device is paired
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/pairedActivates the specified iOS device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/activate/enableReturns whether the device is activated
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/activatedPrepares and enables supervision on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/supervise/enableReturns whether the device is supervised
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/supervisedReturns whether developer mode is enabled on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/devmodeEnables developer mode on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/devmode/enableReturns whether the developer disk image is mounted
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/imageMounts the developer disk image on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/image/enableInstalls a configuration profile on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
profile |
body | ProfileAddRequest | yes | Base64 encoded profile |
Body:
{
"b64profile": "<string>"
}curl -X POST http://localhost:8080/<udid>/profiles/add \
-H 'Content-Type: application/json' \
-d '{"b64profile": "<string>"}'Configures the device to use an HTTP proxy for profile installation
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
request |
body | ProfileHttpRequest | yes | HTTP proxy configuration |
Body:
{
"address": "<string>",
"port": "<string>"
}curl -X POST http://localhost:8080/<udid>/profiles/http \
-H 'Content-Type: application/json' \
-d '{"address": "<string>", "port": "<string>"}'Returns a list of configuration profiles installed on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/profiles/listInstalls an application from a URL on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
request |
body | AppInstallRequest | yes | Application IPA URL |
Body:
{
"url": "<string>"
}curl -X POST http://localhost:8080/<udid>/apps/install \
-H 'Content-Type: application/json' \
-d '{"url": "<string>"}'Terminates a running application by process ID
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
pid |
form | string | yes | Process ID |
curl -X POST http://localhost:8080/<udid>/apps/kill -d "pid=<pid>"Returns a list of applications installed on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/apps/listLaunches an application on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
bundleid |
form | string | yes | Application bundle identifier |
curl -X POST http://localhost:8080/<udid>/apps/run -d "bundleid=<bundleid>"Transparent reverse proxy to the WebDriverAgent HTTP server running on the device. Everything after /wda/cmd is forwarded verbatim to WDA, exposing its full WebDriver/Appium endpoint surface (for example /status, /session, element interactions). Sub-paths are proxied as-is.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl http://localhost:8080/<udid>/wda/cmd/statusStops WebDriverAgent on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/wda/killStarts WebDriverAgent on the device
| Name | In | Type | Required | Description |
|---|---|---|---|---|
udid |
path | string | yes | Device UDID |
curl -X POST http://localhost:8080/<udid>/wda/run