# How to Install IPA Files Using vphone‑cli's Guest Daemon: Complete Protocol Guide

> Install IPA files on your virtual iPhone using vphone-cli's guest daemon. This guide details the protocol for seamless IPA installation via vsock and vphoned.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: how-to-guide
- Published: 2026-09-06

---

**vphone-cli installs IPAs by uploading the file to the guest VM via vsock and sending an `ipa_install` protocol request to the `vphoned` daemon, which handles the actual installation inside the virtual iPhone.**

The **vphone-cli** project by Lakr233 provides a macOS-native interface for running virtualized iOS devices. A core feature is its ability to install `.ipa` and `.tipa` application packages through a dedicated **guest daemon** (`vphoned`) running inside the VM. This article breaks down the complete installation flow, from capability negotiation to cleanup, based on the actual Swift implementation in the repository.

## How the IPA Installation Protocol Works

The installation process relies on a **three-phase protocol** between the host application and the guest daemon. Understanding this flow helps diagnose failures and enables programmatic automation.

### Phase 1: Capability Negotiation

When the virtual machine boots, the host queries the daemon for supported capabilities. The daemon advertises `ipa_install` if its version includes the installer functionality.

The host tracks this capability in [`VPhoneAppDelegate.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneAppDelegate.swift):

```swift
// Capabilities are queried during VM connection
// mc?.updateInstallAvailability checks for "ipa_install"
// and disables the menu item when unavailable

```

If the daemon doesn't report `ipa_install`, the **Install IPA/TIPA…** menu item becomes disabled. This prevents user confusion when running an outdated guest image【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneAppDelegate.swift#L170-L242】.

### Phase 2: Initiating the Install Request

Users can trigger installation through two entry points:

**Apps Menu (GUI)** — [`VPhoneMenuApps.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneMenuApps.swift) presents "Install IPA/TIPA…", opens an `NSOpenPanel`, and calls `VPhoneControl.installIPA(localURL:)`【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneMenuApps.swift#L51-L71】

**Command Line** — The `--install-ipa` flag in [`VPhoneCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneCLI.swift) parses a URL and forwards it to the same method【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneCLI.swift#L59-L73】

### Phase 3: Host-Side Installer Execution

The `VPhoneControl` class in [`VPhoneControl.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneControl.swift) implements the core protocol logic. The `installIPA(localURL:)` method first validates daemon support, then delegates to `installIPAWithBuiltInInstaller`【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneControl.swift#L54-L61】.

The built-in installer performs these steps:

1. **Create temporary directory** — `/var/mobile/Documents/vphone-installs` on the guest
2. **Upload the IPA file** — via `uploadFile` over the vsock channel
3. **Optionally upload signing certificate** — for enterprise or ad-hoc signed apps
4. **Send JSON request** — with `"t": "ipa_install"` and the remote file path
5. **Await daemon response** — success message or error details
6. **Cleanup** — `defer` block registers uploaded files for removal【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneControl.swift#L64-L92】【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneControl.swift#L76-L84】

The daemon processes the install request and returns a status. The host surfaces this directly to the caller, or a generic success string if empty【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneControl.swift#L100-L106】.

## Installing IPA Files: Practical Methods

### Method 1: GUI Installation from the Apps Menu

Select **Apps → Install IPA/TIPA…** from the menu bar. This presents a file picker restricted to `.ipa` and `.tipa` extensions via `VPhoneInstallPackage.allowedContentTypes`.

```swift
// Implementation in VPhoneMenuApps.swift
@objc func installIPAFromDisk() {
    let panel = NSOpenPanel()
    panel.allowedContentTypes = VPhoneInstallPackage.allowedContentTypes
    if panel.runModal() == .OK, let url = panel.url {
        Task {
            let result = try await control.installIPA(localURL: url)
            print("[install] \(result)")
        }
    }
}

```

The result appears in a modal dialog after the async task completes【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneMenuApps.swift#L72-L83】.

### Method 2: Command-Line Installation

With the VM running and the guest daemon connected, use the `--install-ipa` flag:

```bash

# Basic installation

vphone-cli --install-ipa /path/to/MyApp.ipa

# Installation with spaces in path

vphone-cli --install-ipa "/Users/dev/Downloads/My App.tipa"

```

The CLI parses the URL in [`VPhoneCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneCLI.swift) and invokes the same `installIPA` method as the GUI【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneCLI.swift#L59-L73】.

### Method 3: Programmatic Installation in Swift

Integrate IPA installation into your own Swift tools using `VPhoneControl`:

```swift
import vphone_cli

let control = VPhoneControl(...)
let ipaURL = URL(fileURLWithPath: "/tmp/MyApp.ipa")

Task {
    do {
        let message = try await control.installIPA(localURL: ipaURL)
        print("Install succeeded:", message)
    } catch {
        print("Install failed:", error)
    }
}

```

This pattern appears in [`VPhoneVirtualMachineView.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachineView.swift) for automatic post-connection installs.

## Error Handling and Troubleshooting

### "unknown type: ipa_install"

If `installIPA` receives this daemon response, the method surfaces a clear error suggesting a VM reboot. This indicates the guest image lacks the installer component or the daemon failed to initialize properly【/cache/repos/github.com/Lakr233/vphone-cli/main/sources/vphone-cli/VPhoneControl.swift#L54-L61】.

### Verify Capability Detection

Check that the guest daemon connected successfully. The **Install IPA/TIPA…** menu item disables automatically when `ipa_install` capability is absent.

## Key Source Files Reference

| File | Role | Critical Functions |
|------|------|------------------|
| [`sources/vphone-cli/VPhoneControl.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneControl.swift) | Protocol implementation | `installIPA(localURL:)`, `installIPAWithBuiltInInstaller` |
| [`sources/vphone-cli/VPhoneMenuApps.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneMenuApps.swift) | GUI entry point | `installIPAFromDisk()` |
| [`sources/vphone-cli/VPhoneCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneCLI.swift) | CLI entry point | `--install-ipa` flag parsing |
| [`sources/vphone-cli/VPhoneAppDelegate.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneAppDelegate.swift) | Capability detection | `updateInstallAvailability` |
| [`sources/vphone-cli/VPhoneVirtualMachineView.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVirtualMachineView.swift) | Auto-install example | Post-connection install calls |

## Summary

- **Capability negotiation** determines whether the guest daemon supports `ipa_install` before enabling UI options
- **Two entry points** serve users: the Apps menu for GUI workflows and `--install-ipa` for automation
- **Protocol flow** uploads the IPA to `/var/mobile/Documents/vphone-installs`, sends a JSON request with `"t": "ipa_install"`, and cleans up afterward
- **Error handling** provides actionable feedback when the daemon lacks installer support

## Frequently Asked Questions

### What file types does vphone-cli support for installation?

**vphone-cli supports `.ipa` (standard iOS app packages) and `.tipa` (tweaked/modified IPAs).** The file picker in [`VPhoneMenuApps.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneMenuApps.swift) restricts selection to these types via `VPhoneInstallPackage.allowedContentTypes`, and the daemon handles both formats through the same `ipa_install` protocol.

### Why is the "Install IPA/TIPA" menu item disabled?

**The menu disables when the guest daemon doesn't advertise the `ipa_install` capability.** This happens if the VM is still booting, the daemon crashed, or the guest image lacks the installer component. Restarting the VM typically resolves this by triggering fresh capability negotiation in [`VPhoneAppDelegate.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneAppDelegate.swift).

### Can I install IPAs automatically without user interaction?

**Yes — use the CLI flag or programmatic API.** The `--install-ipa` flag in [`VPhoneCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneCLI.swift) enables shell scripting, while `VPhoneControl.installIPA(localURL:)` allows Swift-based automation as demonstrated in [`VPhoneVirtualMachineView.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachineView.swift) for post-connection installs.

### Where does the IPA get stored during installation?

**The host uploads IPAs to `/var/mobile/Documents/vphone-installs` inside the guest VM.** A `defer` block in `installIPAWithBuiltInInstaller` registers these files for cleanup after installation completes, preventing accumulation of temporary install packages.