# iDevice AFC File Transfer and App Management Methods in the ipsw Go Library

> Explore iDevice AFC file transfer and app management methods in the ipsw Go library. Learn seamless data transfer and app control directly via lockdownd services.

- Repository: [blacktop/ipsw](https://github.com/blacktop/ipsw)
- Tags: deep-dive
- Published: 2026-02-26

---

**The `ipsw` library provides native Go implementations for iDevice interaction through two primary packages: `pkg/usb/afc` for AFC file transfer operations and `pkg/usb/apps` for app management, both communicating via lockdownd services without external dependencies.**

The `blacktop/ipsw` repository offers a complete Go-based toolkit for communicating with iOS devices over USB. Understanding the **iDevice interaction methods** for file system access and application lifecycle management enables developers to automate deployment workflows entirely within Go programs, eliminating the need for external binaries like `ideviceinstaller` or `ifuse`.

## AFC File Transfer Architecture

The **AFC (Apple File Conduit)** implementation in `pkg/usb/afc` provides POSIX-like file operations by connecting to the lockdownd service `com.apple.afc`. This service allows sandboxed access to the device's filesystem, enabling both single-file and recursive directory transfers.

### Establishing the AFC Connection

According to the source code in [`pkg/usb/afc/afc.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/afc/afc.go), the `NewClient` function initializes a session by negotiating with lockdownd using the target device's UDID:

```go
afcClient, err := afc.NewClient("<UDID>")
if err != nil {
    log.Fatalf("AFC client error: %v", err)
}
defer afcClient.Close()

```

This creates an `afc.Client` that wraps the raw USB connection (`usb.Client`) and manages the binary AFC protocol encoding, including operation codes and argument marshaling.

### Single File Operations

The helper methods in [`pkg/usb/afc/helper.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/afc/helper.go) abstract the low-level `FileRefOpen` calls. Use `CopyFileToDevice` and `CopyFileFromDevice` for streaming single files via `io.Copy`:

```go
// Copy local file to device Documents folder
err = afcClient.CopyFileToDevice("/Documents/myfile.txt", "./myfile.txt")
if err != nil {
    log.Fatalf("Copy error: %v", err)
}

```

These functions handle opening remote file references, streaming data chunks, and closing handles automatically.

### Recursive Directory Transfer

For directory operations, `CopyToDevice` and `CopyFromDevice` handle recursive transfers by walking the filesystem tree. The implementation creates remote subdirectories via `MakeDir` and traverses structures using the `Walk` method:

```go
// Recursively copy local directory to device
err = afcClient.CopyToDevice("/Documents/remoteFolder", "./localFolder", nil)
if err != nil {
    log.Fatalf("Recursive copy failed: %v", err)
}

```

The `RemoveAll` method provides depth-first recursive deletion of remote directory trees, complementing the copy operations.

## App Management via Installation Proxy

The `pkg/usb/apps` package implements the **Installation Proxy** protocol (`com.apple.mobile.installation_proxy`) for comprehensive application lifecycle management, including querying, installation, upgrading, and removal.

### Querying Installed Applications

The `InstalledApps` method in [`pkg/usb/apps/installation.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/apps/installation.go) returns metadata for all applications as a slice of app structures:

```go
appsClient, err := apps.NewClient("<UDID>")
if err != nil {
    log.Fatalf("Apps client error: %v", err)
}
defer appsClient.Close()

list, err := appsClient.InstalledApps()
if err != nil {
    log.Fatalf("Failed to fetch apps: %v", err)
}

```

Additional lookup methods include `Lookup` for raw metadata, `LookupExePath` for binary locations, `LookupDisplayName` for user-facing names, and `LookupContainer` for app sandbox paths.

### Installing and Upgrading Packages

The `Install` and `Upgrade` methods accept IPA or ZIP archives and provide progress callbacks via `ProgressFunc`. As implemented in [`installation.go`](https://github.com/blacktop/ipsw/blob/main/installation.go), these methods send PLIST-encoded commands and parse `ProgressEvent` responses:

```go
err = appCli.Install("./MyApp.ipa", func(ev *apps.ProgressEvent) {
    log.Printf("Install %s – %d%%", ev.Status, ev.PercentComplete)
})
if err != nil {
    log.Fatalf("Install error: %v", err)
}

```

The `CopyAndInstall` convenience method combines local file copying with installation for streamlined deployment workflows.

### Uninstallation and Archiving

For removal operations, `Uninstall` accepts a bundle identifier and optional progress callback:

```go
bundleID := "com.example.myapp"
if err = cli.Uninstall(bundleID, nil); err != nil {
    log.Fatalf("Uninstall failed: %v", err)
}

```

The package also supports `Archive` and `RestoreArchive` for creating and restoring application backups, along with `Upgrade` for in-place app updates.

## Core Implementation Files

- [`pkg/usb/afc/afc.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/afc/afc.go): Low-level AFC protocol request/response handling and error mapping.
- [`pkg/usb/afc/helper.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/afc/helper.go): High-level file copy and directory walk utilities including `CopyToDevice` and `RemoveAll`.
- [`pkg/usb/apps/installation.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/apps/installation.go): Installation Proxy client implementing `Install`, `Upgrade`, `Uninstall`, and lookup methods.
- `pkg/usb/lockdownd/`: Service negotiation layer used by both AFC and apps clients to establish sessions.
- [`pkg/usb/usb.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/usb.go): Generic USB transport abstraction for socket handling and device discovery.

## Summary

- **AFC file transfer** uses the `com.apple.afc` service via `pkg/usb/afc`, providing `CopyFileToDevice`, `CopyToDevice`, and `RemoveAll` operations for both single files and recursive directories.
- **App management** leverages the Installation Proxy (`com.apple.mobile.installation_proxy`) through `pkg/usb/apps` for installing, upgrading, querying, and removing applications.
- Both clients initialize through lockdownd sessions identified by device UDID and support progress callbacks for monitoring long-running operations.
- The pure-Go implementation requires no external binaries, communicating directly with iOS devices over USB using the AFC and Installation Proxy protocols.

## Frequently Asked Questions

### What is AFC in the context of iDevice file transfer?

AFC (Apple File Conduit) is a binary protocol that provides sandboxed file system access to iOS devices. In the `ipsw` library, the `pkg/usb/afc` package implements this protocol to enable POSIX-like file operations including copying, walking directories, and recursive deletion without requiring jailbreak or external tools like `ifuse`.

### How does the ipsw library handle app installation progress?

The `apps.Client` methods accept a `ProgressFunc` callback that receives `ProgressEvent` structures containing `Status` strings and `PercentComplete` integers. This allows real-time monitoring of installation, upgrade, and uninstallation operations as the device reports progress via the Installation Proxy service (`com.apple.mobile.installation_proxy`).

### Can I transfer entire directories using the AFC client?

Yes. While `CopyFileToDevice` handles single files, the `CopyToDevice` and `CopyFromDevice` methods in [`pkg/usb/afc/helper.go`](https://github.com/blacktop/ipsw/blob/main/pkg/usb/afc/helper.go) recursively traverse directory trees, automatically creating remote subdirectories with `MakeDir` and handling nested file transfers via the `Walk` method.

### What dependencies are required to use these iDevice interaction methods?

The `ipsw` library requires only Go standard libraries and its internal USB transport layer (`pkg/usb`). It communicates directly with the device's lockdownd daemon over USB using native protocols, eliminating dependencies on external binaries like `ideviceinstaller` for app management or `ifuse` for file transfer.