How to Install IPAs into the Virtual iPhone Using vphone-cli

vphone-cli provides a self-contained IPA installation pipeline that extracts, re-signs, and deploys iOS apps to the virtual machine via vsock port 1337 without requiring external utilities like ideviceinstaller.

The Lakr233/vphone-cli repository ships a comprehensive command-line toolchain for managing virtual iPhone instances on macOS. Understanding how to install IPAs into the virtual iPhone using vphone-cli enables developers to sideload unsigned or custom applications into an isolated iOS VM, with the entire workflow executing across five distinct architectural layers.

Architecture of the IPA Installation Pipeline

The installation system is organized into specialized modules that handle everything from argument parsing to kernel-level networking.

Command Interface Layer

In sources/vphone-cli/VPhoneCLI.swift, the top-level command-line interface parses the install sub-command and its --ipa option using ArgumentParser. This layer validates file paths and instantiates the installation orchestrator.

Package Processing and Extraction

VPhoneInstallPackage.swift manages the heavy lifting of IPA preparation. It opens the ZIP archive, extracts Payload/*.app to a temporary directory, and recursively scans for every Mach-O binary—including executables, app extensions, and dynamic libraries—that requires re-signing.

Dynamic Code Signing

VPhoneSigner.swift implements the cryptographic layer. It generates a fresh entitlements plist matching the virtual device’s provisioning profile and invokes the private SecCodeSigner API (or a bundled codesign shim) to write new CodeSignature folders for each binary. The implementation also updates the app’s Info.plist with the new signing identity.

Network Transport and Guest Communication

VPhoneIPAInstaller.swift and VPhoneControl.swift handle the host-to-guest transmission. VPhoneControl establishes a persistent vsock connection to port 1337 and implements automatic reconnection logic if the daemon restarts. VPhoneIPAInstaller constructs a length-prefixed JSON payload containing the command, app path, and signature metadata, then transmits it over this socket.

Guest-Side Daemon

Inside the VM, the scripts/vphoned daemon listens on vsock port 1337. It unmarshals incoming JSON requests and forwards them to installd, the native iOS installation service, completing the deployment cycle.

Step-by-Step Installation Flow

The end-to-end process follows this strict sequence when you invoke the CLI:

  1. Command Invocation – vphone-cli install --ipa /path/to/App.ipa triggers ArgumentParser in VPhoneCLI.swift to create a VPhoneInstallPackage instance.
  2. Extraction – The package handler opens the IPA as a ZIP archive, extracts the .app bundle, and identifies all Mach-O targets.
  3. Re-signing – VPhoneSigner generates entitlements and applies new code signatures to every binary, ensuring the VM’s kernel will execute the code.
  4. Payload Construction – The installer prepares a JSON message with command: "install" and the absolute path to the re-signed bundle.
  5. Transmission – VPhoneControl opens the vsock connection and sends the JSON prefixed with a 4-byte length header.
  6. Guest Execution – vphoned receives the request, calls installd -install <appPath> inside the iOS VM, and captures the return status.
  7. Feedback – The CLI prints a success marker (✅ Installed App) or surfaces the daemon’s error message to the user.

Practical CLI Usage Examples

Basic Installation

Install a single IPA file by providing its absolute or relative path:

vphone-cli install --ipa ~/Downloads/ExampleApp.ipa

Batch Installation

The CLI accepts multiple --ipa arguments and processes them sequentially in a single command:

vphone-cli install \
  --ipa ~/Downloads/AppA.ipa \
  --ipa ~/Downloads/AppB.ipa

Debugging with Verbose Output

Add the -v or --verbose flag to inspect the internal state transitions, including extraction progress, signing operations, and network transmission status:

vphone-cli -v install --ipa MyApp.ipa

Custom Code Signing Identity

For advanced scenarios requiring a specific provisioning profile, export the VPHONE_SIGN_IDENTITY environment variable before execution. VPhoneSigner.swift checks for this variable when generating signatures:

export VPHONE_SIGN_IDENTITY="Apple Development: John Doe (ABCD1234)"
vphone-cli install --ipa MyApp.ipa

Summary

  • Self-contained workflow: The vphone-cli binary handles extraction, signing, and installation without relying on Xcode’s ideviceinstaller or similar external tools.
  • vsock networking: All communication occurs over vsock port 1337 using a length-prefixed JSON protocol managed by VPhoneControl.swift and the vphoned guest daemon.
  • Mandatory re-signing: Every Mach-O binary in the IPA must be re-signed with the VM’s identity via VPhoneSigner.swift before installd will accept the package.
  • Platform restriction: The toolchain requires macOS 15 or later, as implemented in the source code’s platform directives.

Frequently Asked Questions

Do I need external tools like ideviceinstaller to deploy IPAs?

No. The Lakr233/vphone-cli repository implements a fully self-contained installation pipeline. The CLI manages extraction, code signing, and network transmission directly to the virtual machine’s installd service, eliminating dependencies on external Apple utilities.

Why does vphone-cli re-sign application binaries before installation?

The virtual iPhone VM uses a unique code-signing identity distinct from your host Mac. According to VPhoneSigner.swift, the tool strips existing signatures and applies fresh ones using SecCodeSigner (or a shim) with entitlements that match the VM’s kernel policy. Without this step, the iOS kernel would terminate the app immediately upon launch.

Which network port does the guest daemon use to receive install commands?

The guest-side daemon vphoned listens on vsock port 1337. VPhoneControl.swift establishes the host-to-guest connection on this port and transmits length-prefixed JSON payloads containing the installation instructions.

Can I use a custom provisioning profile or signing certificate?

Yes. Set the environment variable VPHONE_SIGN_IDENTITY to your desired identity string before running the install command. The signing logic in VPhoneSigner.swift reads this variable and passes it to the underlying codesign invocation or SecCodeSigner configuration, allowing you to sign apps with specific developer certificates.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →