95 lines
2.7 KiB
Markdown
95 lines
2.7 KiB
Markdown
# HelloWorld for iOS
|
|
|
|
A minimal UIKit application plus a command-line build and installation workflow.
|
|
The workflow was tested with:
|
|
|
|
- Intel macOS Sonoma 14.8.7 running in Proxmox
|
|
- Xcode 16.2 and the iOS 18.2 SDK
|
|
- An iPhone 15 running iOS 26.5.2
|
|
- `pymobiledevice3` 9.36.0
|
|
|
|
The host Xcode does not need to support the phone's installed iOS version. The
|
|
script builds the Xcode **target** directly for `iphoneos`, which avoids Xcode's
|
|
destination compatibility check, and uses `pymobiledevice3` to install the
|
|
result through Apple's installation service.
|
|
|
|
## Prerequisites
|
|
|
|
1. Select Xcode and finish its first-launch setup:
|
|
|
|
```bash
|
|
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
|
|
sudo xcodebuild -license accept
|
|
sudo xcodebuild -runFirstLaunch
|
|
```
|
|
|
|
2. Install a current `pymobiledevice3`. Version 2.30.0 is too old for current
|
|
AltServer JIT support because it does not expose the `mounter` command.
|
|
|
|
```bash
|
|
brew install openssl@3
|
|
python3 -m pip install -U pymobiledevice3
|
|
```
|
|
|
|
3. Sign in to the Apple account in Xcode, pair the iPhone, and enable
|
|
**Settings > Privacy & Security > Developer Mode** on the phone.
|
|
|
|
4. Ensure the phone is registered with the Personal Team. AltServer can perform
|
|
the initial registration. A free Personal Team profile expires after seven
|
|
days, so rerun the script to rebuild and reinstall before expiration.
|
|
|
|
## Build and install
|
|
|
|
Connect and unlock one iPhone, then run:
|
|
|
|
```bash
|
|
./scripts/build-install.sh
|
|
```
|
|
|
|
To select a device explicitly and launch the app after installation:
|
|
|
|
```bash
|
|
./scripts/build-install.sh \
|
|
--udid DEVICE_UDID \
|
|
--launch
|
|
```
|
|
|
|
The launch step requires the phone to remain unlocked. The build and signed IPA
|
|
are written under `build/device/`.
|
|
|
|
Useful overrides:
|
|
|
|
```bash
|
|
TEAM_ID=HY3W4U256Z \
|
|
BUNDLE_ID=local.proxmox.helloworld.e2e \
|
|
CONFIGURATION=Debug \
|
|
./scripts/build-install.sh
|
|
```
|
|
|
|
Use `--build-only` to compile, sign, package, and validate without installing.
|
|
When the phone is disconnected, pass its UDID explicitly so the script can
|
|
still verify the provisioning profile:
|
|
|
|
```bash
|
|
./scripts/build-install.sh --build-only --udid DEVICE_UDID
|
|
```
|
|
|
|
## Why this works with an older Xcode
|
|
|
|
An ordinary scheme build aimed at an iOS 26 phone causes Xcode 16.2 to reject
|
|
the destination before compilation. This project instead uses a target-level
|
|
device build:
|
|
|
|
```bash
|
|
xcodebuild -project HelloWorld.xcodeproj \
|
|
-target HelloWorld \
|
|
-sdk iphoneos \
|
|
-allowProvisioningUpdates \
|
|
build
|
|
```
|
|
|
|
The resulting ARM64 app targets iOS 15 or later and therefore runs on iOS 26.
|
|
Installation and device queries are handled independently by
|
|
`pymobiledevice3`, which supports newer device protocols without requiring a
|
|
newer macOS release.
|