# Devices and signing

ipa-hub uses paired Apple devices reported by Xcode. Physical devices are included by default; simulators are optional.

To pair a device, open **Device Hub** (installed with Xcode) and choose **File → Pair Nearby Device...** from the macOS menu bar at the top of the screen. Follow the pairing prompts and enable Developer Mode when requested.

## List and inspect devices

```sh
ipa-hub device ls
ipa-hub device ls --all
ipa-hub device info --device-name "My iPhone"
```

`device` without a subcommand displays help. `device ls` shows available destinations; `--all` includes unavailable paired devices. `device info` shows a concise summary, installed apps, and the source and signature expiry of apps tracked by ipa-hub. Add `--json` for raw details.

## Choose a destination

```sh
ipa-hub install gh:owner/repo --device DEVICE_ID
ipa-hub install gh:owner/repo -n "Living Room"
ipa-hub install gh:owner/repo -t iphone -t ipad
```

`--device` (`-d`) accepts a CoreDevice ID, UDID, or exact name. `--device-name` (`-n`) matches the full, case-sensitive name. Duplicate matches prompt for a selection.

Repeat `--device-type` (`-t`, `--type`) to consider several types: `iphone`, `ipad`, `appletv`, `visionos`, and `applewatch`. All filters are combined; they do not make an incompatible IPA work on another platform. Embedded Watch companions are not supported.

## Simulators

```sh
ipa-hub device ls -s
ipa-hub install ./Simulator.ipa --simulators-only -n "iPhone 15 Pro Max"
```

`--include-simulators` (`-s`) adds simulators. `--simulators-only` excludes physical devices. Simulator IPAs must be compiled for Simulator; re-signing cannot convert a device IPA. Simulator installations do not require a provisioning profile or expire. Discovery requires an Xcode version that reports simulators through CoreDevice.

## Signing teams and profiles

```sh
ipa-hub teams
ipa-hub teams --all
ipa-hub install gh:owner/repo --team TEAM_ID
ipa-hub install ./App.ipa --select-profile
ipa-hub install ./App.ipa --all-profiles
ipa-hub install ./App.ipa --profile ~/Profiles/App.mobileprovision
```

By default, `teams` and installation choices show only unrestricted `*` profiles (`TEAM.*`). `teams --all` (`-a`) also shows profiles scoped to an app or bundle-ID prefix; use `install --all-profiles` to include compatible specific profiles in the installation picker. `--select-profile` forces a picker even when only one profile matches, including expired profiles marked for renewal. An explicit `--profile PATH` remains usable without `--all-profiles`.

Use `teams --json` for profile paths and certificate hashes; add `--all` to include specific profiles in JSON too. `--identity SHA1` selects a specific signing identity. The low-level library functions `listProfiles()` and `listTeams()` continue returning all discovered profiles; installation options accept `allProfiles: true` to expand signing choices.

In the manager’s **Settings**, enable **Show specific provisioning profiles** to include these profiles. The preference is saved on that browser/device and applies to installations, updates, signature refreshes, and imported apps. It controls profile visibility even when a pasted command contains `--all-profiles`.

When no suitable profile exists, or the selected profile has expired, ipa-hub builds a disposable app using `xcodebuild -allowProvisioningUpdates` and your account already signed in to Xcode. It uses the selected team, app identifier, platform, and device. If the team cannot be discovered from local profiles or certificates, pass `--team TEAM_ID`. Xcode may register the target device and create or update signing assets.

The project, DerivedData, build products, logs, module caches, and temporary build files live together under `~/.ipa-hub/tmp` (or the configured data directory). They are removed after success or failure; other projects and their caches are left alone. The renewed profile stays in Xcode’s provisioning-profile library for future installations. Xcode controls which profiles Apple issues: a wildcard is preferred, but an app-specific profile may be returned, with a warning. Before signing, ipa-hub verifies the profile’s team, bundle identifier, platform, expiry, certificate/private key, and device authorization. Required capabilities are checked during signing.

## Automatic signature refresh

App Manager enables **Automatically refresh app signature** for each installed app by default. Open the app’s three-dot menu to turn it off or on. The preference is saved on the Mac and survives app updates and server restarts. Library consumers can use `hub.setAutomaticSignatureRefresh(deviceId, bundleId, enabled)`.

While the server is running, it checks the saved installations on startup and once an hour. It starts trying two days before a seven-day signature expires, or thirty days before a year-long signature expires. Other lifetimes use two sevenths of the installed signature’s duration, capped at thirty days. Signature expiry includes the provisioning profiles for the app and its extensions, and the signing certificate’s expiry.

When the local signing certificate is within seven days of expiry, installations signed before that seven-day cutoff are also eligible. A successful refresh records the new installation date so the same certificate cutoff does not repeatedly trigger it. Xcode manages renewal using the Apple account already signed in on your Mac; if signing needs attention, the server reports the error and tries again on its next hourly check.

The device must be available over USB or the network. ipa-hub checks from the Mac that the app is still installed and that its main process is not running, including in the background. It checks again immediately before installation. Running apps and unavailable devices are skipped until a later check. Automatic refresh never opens the app. If an available device confirms that the app was uninstalled, ipa-hub removes its installation record, retained IPA, and saved download credential.

Each successful installation keeps a private copy of the original IPA under `~/.ipa-hub/devices/<device-id>/apps/<installation-id>/original.ipa`, outside the download cache. Automatic refresh uses that copy without downloading the app again or upgrading its version. A successful replacement removes the previous copy; a failed installation keeps it. Apps installed before this retention feature need one manual signature refresh or reinstall to save their original IPA. Simulators do not need signature refreshes.

## When signing needs attention

If automatic provisioning fails, check **Xcode → Settings → Accounts**, accept any pending developer agreements, and ensure the target device is paired and its platform SDK is installed. For a valid, explicitly chosen profile that does not authorize the device, choose another profile or update its device list in Xcode. ipa-hub never asks you to enter Apple credentials.

ipa-hub preserves the bundle identifier when possible. An explicit non-wildcard profile may change it, which can affect app data and Keychain access. App extensions require matching profiles; `--strip-extensions` removes them explicitly.

