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
pymobiledevice39.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
-
Select Xcode and finish its first-launch setup:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer sudo xcodebuild -license accept sudo xcodebuild -runFirstLaunch -
Install a current
pymobiledevice3. Version 2.30.0 is too old for current AltServer JIT support because it does not expose themountercommand.brew install openssl@3 python3 -m pip install -U pymobiledevice3 -
Sign in to the Apple account in Xcode, pair the iPhone, and enable Settings > Privacy & Security > Developer Mode on the phone.
-
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:
./scripts/build-install.sh
To select a device explicitly and launch the app after installation:
./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:
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:
./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:
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.