pi-remote-ios/docs/BUILD.md

4.5 KiB

Build & Deploy

Device

Field Value
Name Johannes's iPhone
Model iPhone 12 mini (iPhone13,1)
Device ID 00008101-0012399122A0001E
iOS 26 (wireless pairing via Xcode 16.4)
Bundle ID de.vpsj.pi-remote
Team ID KNXX8R3648

Sidecar repo

/Users/jay/.pi/agent/git/git.vpsj.de/jay/pi-remote-control

1. Start sidecar (background, needs PTY via tmux)

cd /Users/jay/.pi/agent/git/git.vpsj.de/jay/pi-remote-control
tmux new-session -d -s pi-sidecar -x 220 -y 50 \
  "pi -nt -ne -ns -np -nc --no-session --offline -e extensions/remote-control --remote-control"

# Check it started (shows URL + token):
sleep 3 && tmux capture-pane -t pi-sidecar -p | grep -i "remote-control started"

# Kill when done:
tmux kill-session -t pi-sidecar

The URL + token are printed in the tmux pane, e.g.:

Remote-control started: http://10.13.37.2:17373/?token=<TOKEN>

Note: the LAN IP (10.13.37.2) can change. The token is regenerated each run and lives in ~/.pi/remote-control/token.

2. Build for device

cd /Users/jay/.pi/agent/git/git.vpsj.de/jay/pi-remote-ios

xcodebuild build \
  -project piRemote.xcodeproj \
  -scheme piRemote \
  -destination "platform=iOS,id=00008101-0012399122A0001E" \
  DEVELOPMENT_TEAM=KNXX8R3648 \
  CODE_SIGN_STYLE=Automatic

3. Install on device

APP=$(find ~/Library/Developer/Xcode/DerivedData/piRemote-*/Build/Products/Debug-iphoneos \
  -name "piRemote.app" -maxdepth 1 | head -1)

xcrun devicectl device install app \
  --device 00008101-0012399122A0001E "$APP"

4. Launch on device

xcrun devicectl device process launch \
  --device 00008101-0012399122A0001E \
  de.vpsj.pi-remote

5. Pair the iOS app with the sidecar

Run on Mac (sidecar must be running), with the token from step 1:

# Get the token from the sidecar URL, then:
curl -s "http://<SIDECAR_URL>/pair-qr?token=<TOKEN>"

Or one-liner (reads token from tmux pane automatically):

TOKEN=$(tmux capture-pane -t pi-sidecar -p | grep -o 'token=[^ ]*' | head -1 | cut -d= -f2) && \
SIDECAR=$(tmux capture-pane -t pi-sidecar -p | grep -o 'http://[^ ]*' | head -1 | sed 's/?.*//; s|/$||') && \
curl -s "$SIDECAR/pair-qr?token=$TOKEN"

Scan the QR code with the iPhone app. App stores the bearer token in Keychain and connects automatically.

Note: CLI index.ts requires pi's TypeScript runtime — use the HTTP endpoint above instead.

6. One-liner: build + install + launch

cd /Users/jay/.pi/agent/git/git.vpsj.de/jay/pi-remote-ios && \
xcodebuild build \
  -project piRemote.xcodeproj -scheme piRemote \
  -destination "platform=iOS,id=00008101-0012399122A0001E" \
  DEVELOPMENT_TEAM=KNXX8R3648 CODE_SIGN_STYLE=Automatic 2>&1 | grep -E "error:|SUCCEEDED|FAILED" | grep -v note: && \
APP=$(find ~/Library/Developer/Xcode/DerivedData/piRemote-*/Build/Products/Debug-iphoneos -name "piRemote.app" -maxdepth 1 | head -1) && \
xcrun devicectl device install app --device 00008101-0012399122A0001E "$APP" && \
xcrun devicectl device process launch --device 00008101-0012399122A0001E de.vpsj.pi-remote

APNs key

~/.local/share/pi-remote/apns/AuthKey_285C2X4689.p8
Key ID:  285C2X4689
Team ID: KNXX8R3648

Xcode version

Xcode 16.4 (/Applications/Xcode-16.4.0.app) — last Intel-compatible version. Device runs iOS 26; wireless pairing works despite version mismatch. Direct CLI deploy works via xcrun devicectl.

Simulator (for UI dev without device)

Preferred simulator: iPhone 12 mini (matches the physical test device). Sim UUID: 062F8F0A-B3E5-4A4B-BC8A-B01E98CF27F2

SIM=062F8F0A-B3E5-4A4B-BC8A-B01E98CF27F2
xcrun simctl boot $SIM
open -a Simulator

xcodebuild build \
  -project piRemote.xcodeproj \
  -scheme piRemote \
  -destination "platform=iOS Simulator,id=$SIM" \
  CODE_SIGNING_ALLOWED=NO

APP=$(find ~/Library/Developer/Xcode/DerivedData/piRemote-*/Build/Products/Debug-iphonesimulator -name "piRemote.app" -maxdepth 1 | head -1)
xcrun simctl install $SIM "$APP"
xcrun simctl launch $SIM de.vpsj.pi-remote

The app handles pi-remote:// URLs via .onOpenURL for dev convenience:

PAIR_URL=$(curl -s "http://10.13.37.2:17373/pair-qr?token=$TOKEN&format=url" | grep -oE 'pi-remote://[^[:space:]]+' | head -1)
xcrun simctl openurl $SIM "$PAIR_URL"
# Tap "Open" in the iOS confirm dialog — use cliclick to script it:
# (window content rect: pos (591,124), size (323,700))
cliclick c:778,495   # Open button on iPhone 12 mini