Files
ulapp/doc/iOS_TestFlight.md
2026-08-24 20:24:36 -05:00

89 lines
3.7 KiB
Markdown

# UM Trace TestFlight build
## Fixed application identity
- Display name: `UM Trace`
- Bundle ID: `com.umagul.trace`
- Apple team ID: `W2N8APPQ2C`
- App Store Connect SKU: `UM-TRACE-IOS`
- Distribution profile: `UM Trace App Store`
The provisioning profile and all Apple signing files are local-only and covered by
`.gitignore`. Never commit a certificate, private key, App Store Connect API key, `.p12`, or
provisioning profile.
## Required local toolchain
- Xcode 26 at `/Applications/Xcode.app`
- .NET SDK 10.0.100 as the build host
- Workload set 10.0.100 with `maui-ios` and its .NET 9/iOS 26 compatibility pack
- An `Apple Distribution` identity, including its private key, in the login Keychain
- The `UM Trace App Store` provisioning profile installed locally
This repository's local SDK is installed at `~/.dotnet`. Verify it with:
```sh
~/.dotnet/dotnet --info
~/.dotnet/dotnet workload list
```
## Create an archive
Run the release helper from a normal macOS Terminal session. The build number must increase for
every upload to App Store Connect:
```sh
cd /Users/brent/ul-platform/app
./scripts/publish-testflight.sh 1
```
The app remains on its existing .NET 9 target. The .NET 10 SDK host supplies the supported .NET 9
compatibility pack for Xcode 26, avoiding an unrelated Android/Mac Catalyst framework migration.
The script deliberately supplies Xcode through `DEVELOPER_DIR`; it does not change the machine's
global `xcode-select` setting. It restores only the iOS target, builds with the iOS 26 SDK, selects
the installed `UM Trace App Store` profile, and prints the generated `.ipa` path.
## Create a signed IPA in Jenkins
The manually run `um-trace-ios-release` pipeline uses `Jenkinsfile.release`. By default it uses the
monotonically increasing Jenkins build number as the App Store build number. Set
`IOS_BUILD_NUMBER` only when an explicit higher override is required. The pipeline runs the tests,
signs with the distribution identity and `UM Trace App Store` profile, verifies the resulting
bundle signature and identity, and archives the IPA plus its SHA-256 file.
This pipeline only creates a signed artifact. It does not upload or submit anything to App Store
Connect, so TestFlight release remains a separate, deliberate step.
Before uploading, verify that this command lists a valid distribution identity:
```sh
security find-identity -v -p codesigning
```
If the identity is absent, import a `.p12` containing the matching private key or create a new
Apple Distribution certificate through Xcode and regenerate the provisioning profile against it.
## Deploy a development build to an iPhone
The local development profile is named `UM Trace Development`. It must include the target phone
and match an `Apple Development` identity for team `W2N8APPQ2C`. Keep the phone unlocked and
connected by USB for the first deployment, trust the Mac when prompted, and enable Developer Mode.
Save the phone UDID in the gitignored `.ios-device` file, then run from a normal macOS Terminal:
```sh
cd /Users/brent/ul-platform/app
./scripts/deploy-ios-device.sh
```
You can instead pass a UDID as the first argument or set `UM_TRACE_DEVICE_UDID`. The helper uses
Xcode 26, builds the `Debug` configuration for `ios-arm64`, signs with the development profile,
installs the app, and launches it on the selected phone.
## Background and privacy declarations
The iOS bundle declares `bluetooth-central` and `location` background modes, Bluetooth and
always/when-in-use location explanations, the MAUI `UserDefaults` required-reason API, and exempt
standard TLS use. Physical-device testing remains required to prove the SRS eight-hour background
BLE/location session; declaring a background mode does not itself guarantee continuous execution.