{"id":50389528,"url":"https://github.com/mobile-next/devicekit-ios","last_synced_at":"2026-05-30T17:30:50.783Z","repository":{"id":350937922,"uuid":"1129132722","full_name":"mobile-next/devicekit-ios","owner":"mobile-next","description":"A modern WebDriverAgent alternative. JSON-RPC server for iOS device   automation — touch, inspect, stream, control.","archived":false,"fork":false,"pushed_at":"2026-05-24T14:10:50.000Z","size":361,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-24T15:28:15.118Z","etag":null,"topics":["accessibility","automation","device-automation","ios","mobile-automation","mobile-testing","mobile-use","screen-streaming","webdriveragent","xcuitest"],"latest_commit_sha":null,"homepage":"https://mobilenexthq.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mobile-next.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-06T16:45:21.000Z","updated_at":"2026-05-24T14:10:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mobile-next/devicekit-ios","commit_stats":null,"previous_names":["mobile-next/devicekit-ios"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/mobile-next/devicekit-ios","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobile-next%2Fdevicekit-ios","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobile-next%2Fdevicekit-ios/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobile-next%2Fdevicekit-ios/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobile-next%2Fdevicekit-ios/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mobile-next","download_url":"https://codeload.github.com/mobile-next/devicekit-ios/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobile-next%2Fdevicekit-ios/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33703064,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","automation","device-automation","ios","mobile-automation","mobile-testing","mobile-use","screen-streaming","webdriveragent","xcuitest"],"created_at":"2026-05-30T17:30:50.273Z","updated_at":"2026-05-30T17:30:50.774Z","avatar_url":"https://github.com/mobile-next.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DeviceKit iOS\n\n[![Swift](https://img.shields.io/badge/Swift-5.9-orange.svg?style=flat-square)](https://swift.org)\n[![Platform](https://img.shields.io/badge/Platform-iOS%2016.0+-blue.svg?style=flat-square)](https://developer.apple.com/ios/)\n[![License](https://img.shields.io/badge/License-FSL--1.1--Apache--2.0-lightgrey.svg?style=flat-square)](LICENSE)\n\nControl any iOS device or simulator over a simple JSON-RPC API. Tap, swipe, stream video, inspect the UI, from any language, over localhost.\n\n## Table of Contents\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Starting the Server](#starting-the-server)\n  - [JSON-RPC API](#json-rpc-api)\n  - [Streaming Endpoints](#streaming-endpoints)\n- [Architecture](#architecture)\n- [Building](#building)\n- [Testing](#testing)\n- [Communication](#communication)\n- [License](#license)\n\n## What You Can Build\n\n- **Interactive automation** — Tap, swipe, long-press, type text, press hardware buttons (home, lock, volume)\n- **App control** — Launch, terminate, and detect the foreground app by bundle ID\n- **Live screen visibility** — MJPEG and H264 streaming at configurable FPS, bitrate, and quality\n- **UI inspection** — Full accessibility tree dumps for element targeting\n- **Screenshots** — PNG or JPEG capture with configurable quality\n- **System control** — Get/set orientation, open URLs, query screen size and scale\n- **Broadcast audio/video** — ReplayKit extension with H264 video and Opus audio over TCP\n- **Flexible transport** — JSON-RPC 2.0 over WebSocket or HTTP, from any language\n\n## Requirements\n\n| Platform | Minimum Version |\n|----------|----------------|\n| iOS      | 16.0           |\n| Swift    | 5.9            |\n| Xcode    | 15.0+          |\n\n## Installation\n\n### Building from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/mobile-next/devicekit-ios.git\ncd devicekit-ios\n\n# Build unsigned IPA for real devices\nmake ipa-unsigned\n\n# Build XCUITest runner for simulators\nmake sim-zip\n```\n\n### Build Targets\n\n| Target | Output | Description |\n|--------|--------|-------------|\n| `make ipa-unsigned` | `build/export/devicekit-ios-unsigned.ipa` | Unsigned IPA for arm64 devices |\n| `make sim-zip-arm64` | `build/export/devicekit-ios-Sim-arm64.zip` | Simulator runner (Apple Silicon) |\n| `make sim-zip-x86_64` | `build/export/devicekit-ios-Sim-x86_64.zip` | Simulator runner (Intel) |\n| `make sim-zip` | Both simulator zips | arm64 + x86_64 |\n| `make lint` | — | Run SwiftLint |\n| `make clean` | — | Remove build artifacts |\n\n## Quick Start\n\nOnce the server is running at `127.0.0.1:12004`, make your first call:\n\n```bash\ncurl -X POST http://127.0.0.1:12004/rpc \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"method\":\"device.screenshot\",\"params\":{},\"id\":1}'\n```\n\nReturns a base64-encoded PNG of the current screen.\n\n## Usage\n\n### Starting the Server\n\nDeviceKit runs as an XCUITest. Once installed and launched on a device or simulator, it starts a server on `127.0.0.1:12004`.\n\n### Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DEVICEKIT_LISTEN_PORT` | `12004` | JSON-RPC server port |\n| `DEVICEKIT_LISTEN_HOST` | `127.0.0.1` | Bind address for the JSON-RPC server. All TCP servers (video, audio) also bind to `127.0.0.1` by default. |\n\n**Endpoints:**\n\n| Endpoint | Protocol | Description |\n|----------|----------|-------------|\n| `GET /ws` | WebSocket | JSON-RPC 2.0 |\n| `POST /rpc` | HTTP | JSON-RPC 2.0 |\n| `GET /health` | HTTP | Health check |\n| `GET /mjpeg` | HTTP | MJPEG screen stream |\n| `GET /h264` | HTTP | H264 screen stream |\n\n### JSON-RPC API\n\nAll methods follow the [JSON-RPC 2.0](https://www.jsonrpc.org/specification) specification.\n\n```json\n{\n  \"jsonrpc\": \"2.0\",\n  \"method\": \"device.io.tap\",\n  \"params\": { \"x\": 100, \"y\": 200, \"deviceId\": \"any\" },\n  \"id\": 1\n}\n```\n\n#### Input\n\n| Method | Description |\n|--------|-------------|\n| `device.io.tap` | Tap at (x, y) coordinates |\n| `device.io.swipe` | Swipe from (x1, y1) to (x2, y2) |\n| `device.io.longpress` | Long press at (x, y) for a duration |\n| `device.io.gesture` | Multi-finger gesture with press/move/release actions |\n| `device.io.text` | Type text into the focused field |\n| `device.io.button` | Press a hardware button (`home`, `lock`, `volumeUp`, `volumeDown`) |\n\n#### Device\n\n| Method | Description |\n|--------|-------------|\n| `device.info` | Get screen size and scale factor |\n| `device.io.orientation.get` | Get current orientation (`PORTRAIT` / `LANDSCAPE`) |\n| `device.io.orientation.set` | Set orientation to `PORTRAIT` or `LANDSCAPE` |\n| `device.url` | Open a URL |\n\n#### Apps\n\n| Method | Description |\n|--------|-------------|\n| `device.apps.launch` | Launch an app by bundle ID |\n| `device.apps.terminate` | Terminate an app by bundle ID |\n| `device.apps.foreground` | Get the foreground app's bundle ID, name, and PID |\n\n#### Inspection\n\n| Method | Description |\n|--------|-------------|\n| `device.dump.ui` | Return the full accessibility view hierarchy |\n| `device.screenshot` | Capture a screenshot (base64 PNG/JPEG) |\n\n### Streaming Endpoints\n\n#### MJPEG\n\n```\nGET /mjpeg?fps=10\u0026quality=25\u0026scale=100\n```\n\n| Parameter | Default | Range | Description |\n|-----------|---------|-------|-------------|\n| `fps` | 10 | 1–60 | Frames per second |\n| `quality` | 25 | 1–100 | JPEG quality (%) |\n| `scale` | 100 | 10–100 | Scale factor (%) |\n\n#### H264\n\n```\nGET /h264?fps=30\u0026bitrate=4000000\u0026quality=60\u0026scale=50\n```\n\n| Parameter | Default | Range | Description |\n|-----------|---------|-------|-------------|\n| `fps` | 30 | 1–60 | Frames per second |\n| `bitrate` | 4000000 | 100000–10000000 | Target bitrate (bps) |\n| `quality` | 60 | 1–100 | Encoder quality (%) |\n| `scale` | 50 | 10–100 | Scale factor (%) |\n\n### Broadcast Extension\n\nThe ReplayKit broadcast extension provides system-level screen and audio capture over TCP, independent of the JSON-RPC server.\n\n| Port | Stream |\n|------|--------|\n| 12005 | H264 video |\n| 12006 | Opus audio |\n\n## Testing\n\nTests run against a live XCUITest server on a booted simulator. You need one simulator running — the test harness picks the first booted device automatically.\n\n```bash\n# Install test dependencies (one-time)\ncd tests \u0026\u0026 npm install \u0026\u0026 cd ..\n\n# Run tests with code coverage\nmake test-coverage\n\n# View coverage report as HTML\nmake coverage-html\n```\n\n## Architecture\n\n```\ndevicekit-ios/\n  DeviceKit/                    # Host app (SwiftUI, triggers broadcast picker)\n  DeviceKitTests/               # XCUITest runner (automation server)\n    JSONRPC/                    #   JSON-RPC protocol + 15 method handlers\n    Streamer/                   #   MJPEG and H264 HTTP streaming\n    XCTest/                     #   Private API wrappers (touch synthesis, accessibility)\n    H264Stream/                 #   Screenshot-based H264 streaming\n  BroadcastUploadExtension/     # ReplayKit extension (H264 + Opus over TCP)\n  h264-codec/                   # Swift package: H264 encoder (VideoToolbox)\n  opus-codec/                   # Swift package: Opus encoder (wraps libopus)\n```\n\n## Dependencies\n\n- [FlyingFox](https://github.com/swhitty/FlyingFox) — Lightweight HTTP and WebSocket server\n- [libopus](https://opus-codec.org/) — Audio codec (vendored as C source in `opus-codec/`)\n\n## Communication\n\nQuestions, issues, or ideas? [Open an issue](https://github.com/mobile-next/devicekit-ios/issues) — all feedback is welcome.\n\nWant to contribute? PRs are appreciated. Check open issues for good first tasks.\n\n## License\n\nDeviceKit iOS is released under the [Functional Source License 1.1, Apache 2.0 Future License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobile-next%2Fdevicekit-ios","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmobile-next%2Fdevicekit-ios","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobile-next%2Fdevicekit-ios/lists"}