| name | dev-ios |
| description | iOS development workflow for building, signing, and deploying to physical devices. Covers remote builds on ch405, provisioning profiles, keychain, and srun tooling. Use when dealing with iOS builds, device deployment, code signing, or provisioning issues. |
iOS Development Workflow
Architecture
Build happens on ch405 (remote Mac), install/run happens on local machine (where device is plugged in). Communication via reverse SSH tunnel set up by sproject.
Key Tools (~/.bin/)
| Command | Description |
|---|
sproject <project> | SSH to ch405, sets up reverse tunnel, opens tmux |
srun-local phy <project> | From ch405 SSH: build remote, install on local physical device |
srun-local sim <project> | From ch405 SSH: build remote, run on local simulator |
srun-phy <project> | Build + install + launch on physical device (local only) |
srun-sim <project> | Build + install + launch on simulator (local only) |
_srun-build <project> <type> | Internal: builds on ch405, copies .app to local /tmp |
Typical Workflow
sproject local_events
srun-local phy local_events
srun-local sim local_events
Device UUID Configuration
Device UUID is configured in 3 places (all must match):
~/.bin/srun-phy - default in DEVICE_UUID="${IOS_DEVICE_UUID:-<uuid>}"
<project>/.ios-device-uuid - read by bin/install-ios-device
<project>/bin/run-ios-device - default fallback
To find device UUID: xcrun devicectl list devices (on machine where device is plugged in).
The UDID (different from CoreDevice UUID) is visible in Xcode > Window > Devices and Simulators. Both are needed:
- CoreDevice Identifier (format
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX): used by xcrun devicectl
- UDID (format
00008140-XXXXXXXXXXXXXXXX): must be registered on developer.apple.com
Code Signing & Keychain
ch405 uses a dedicated CI keychain:
security unlock-keychain -p ci ~/Library/Keychains/ci.keychain-db
_srun-build handles this automatically. For manual builds via SSH:
security list-keychains -d user -s ~/Library/Keychains/ci.keychain-db ~/Library/Keychains/login.keychain-db
security unlock-keychain -p ci ~/Library/Keychains/ci.keychain-db
Without unlocking the keychain, codesign fails with errSecInternalComponent.
Provisioning Profiles
Profiles are cached in ~/Library/Developer/Xcode/UserData/Provisioning Profiles/.
Adding a New Device
- Get UDID from Xcode (Window > Devices and Simulators) on the machine where device is connected
- Add UDID on developer.apple.com/account/resources/devices/list
- On ch405, delete cached profiles:
rm ~/Library/Developer/Xcode/UserData/Provisioning\ Profiles/*.mobileprovision
- In Xcode on ch405, open project, toggle "Automatically manage signing" off/on for each target (Morris, MorrisShareExtension) to force profile regeneration
- Clean and rebuild:
rm -rf ~/Library/Developer/Xcode/DerivedData/Morris-*
security unlock-keychain -p ci ~/Library/Keychains/ci.keychain-db
xcodebuild -project ios/Morris.xcodeproj -scheme Morris -allowProvisioningUpdates \
-destination "generic/platform=iOS" -configuration Debug CODE_SIGN_STYLE=Automatic build
- Update device UUID in the 3 config locations (see above)
Verifying Profiles
Check which devices are in a profile:
security cms -D -i "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles/<uuid>.mobileprovision" | grep -A 10 "ProvisionedDevices"
Common Error
This provisioning profile cannot be installed on this device = device UDID not in the embedded profile. Follow "Adding a New Device" steps above.
Build Commands (on ch405 directly)
./bin/build-ios
./bin/build-ios device
./bin/run-ios-device