document remote tsswift workflow and bump to 0.6.0
CI / test (push) Has been cancelled

This commit is contained in:
2026-04-20 19:18:10 +00:00
parent 75f5a4e7e8
commit c908187840
3 changed files with 124 additions and 50 deletions
+118 -44
View File
@@ -1,70 +1,144 @@
# idp.global Swift App
Multiplatform SwiftUI scaffold for the personal `idp.global` companion app on iPhone, iPad, Mac, and Apple Watch.
Multiplatform SwiftUI passport companion for `idp.global` on iPhone, iPad, Mac, and Apple Watch.
## Included in this first pass
## Current App Behavior
- QR and NFC-based device pairing flows with a seeded preview payload fallback
- NFC authentication now attaches a signed GPS position on supported iPhone hardware
- Mocked approval inbox for accepting or rejecting identity requests
- Notification center with local notification permission flow and a test notification trigger
- Apple Watch companion target with a compact approval-first dashboard and request detail flow
- Shared app state and mock backend boundary so a real API can be connected later
- iPhone pairing starts on a welcome screen and then opens QR scanning explicitly.
- QR pairing supports a manual paste fallback when camera scanning is unavailable.
- NFC pairing and NFC identity proof attach a signed GPS position on supported iPhones.
- The app uses the live `idp.global` backend by default for pairing, dashboard loading, approvals, and alerts.
- The Apple Watch companion and widgets live in the same Xcode project and build with the main app scheme.
- `MockIDPService` still exists for previews and test scaffolding, but normal runtime uses `LiveIDPService`.
## Open the project
## Repo Layout
1. Open `swift/IDPGlobal.xcodeproj`.
2. Build the `IDPGlobal` scheme for:
- `My Mac`
- an iPad simulator
- an iPhone simulator
3. Build the `IDPGlobalWatch` scheme for an Apple Watch simulator when you want to verify the companion experience.
- root `package.json`
- root `.smartconfig.json`
- Swift project at `swift/IDPGlobal.xcodeproj`
## tsswift workflow
## tsswift Setup
This repo is configured for `tsswift` from the repo root and expects a named global remote builder.
Install tooling:
```bash
corepack pnpm install
```
Configure a global remote macOS builder once:
```bash
corepack pnpm exec tsswift config -g add-builder \
--name <builder-name> \
--host <ssh-host> \
--root-dir <remote-project-root> \
--platforms macos,ios,ipad
```
The global builder registry lives at:
```text
~/.git.zone/tsswift/config.json
```
Verify it with:
```bash
corepack pnpm exec tsswift config list-builders
corepack pnpm exec tsswift config show
```
## Remote Builder Behavior
This project does not keep per-repo SSH details inside `.smartconfig.json`.
Instead, it references a named builder, and `tsswift` resolves that builder from the global registry in `~/.git.zone/tsswift/config.json`.
How it works:
- `tsswift` syncs the repo to the configured remote project root via `rsync`
- `xcodebuild`, `simctl`, and simulator boot or launch commands execute on the remote macOS builder over SSH
- the local machine only orchestrates the workflow; Apple platform builds happen on the builder
- the selected simulator is opened by the requested device identifier instead of reviving a previously used simulator
- simulator builds are pinned to the builder machine's native architecture
Prerequisites:
- working SSH access to the remote builder host
- a configured global `tsswift` builder entry
- local permission to run `ssh` and `rsync`
Quick verification:
```bash
corepack pnpm exec tsswift config -g list-builders
corepack pnpm swift:doctor
```
`swift:doctor` should report the resolved remote builder and remote project root.
This repo's `.smartconfig.json` already points at that builder by name:
```json
"remoteBuilder": {
"name": "<builder-name>"
}
```
Current project defaults:
- default scheme: `IDPGlobal`
- default configuration: `Debug`
- default run platform: `macos`
- build platforms: `macos`, `ios`, `ipad`
- test platform: `macos`
- preferred iPhone and iPad simulators are configured in `.smartconfig.json`
- derived data path: `swift/.build/xcode-derived-data`
`tsswift` pins simulator builds to the builder machine's native architecture and opens the selected simulator device directly instead of reviving a previously used iPhone.
## Common Commands
From the repo root:
```bash
corepack pnpm install
corepack pnpm swift:doctor
corepack pnpm swift:emulators
corepack pnpm swift:build
corepack pnpm swift:build:macos
corepack pnpm run swift:build -- --platform ios
corepack pnpm run swift:build -- --platform ipad
corepack pnpm swift:test
corepack pnpm swift:run
corepack pnpm run swift:run -- --platform ios
corepack pnpm run swift:run -- --platform ipad
corepack pnpm swift:watch
```
This repo now follows the same layout as the other Swift app repos:
Notes:
- git root at the repo root
- root `package.json`
- root `.smartconfig.json`
- Swift app content under `swift/`
- `swift:build` builds the configured macOS, iPhone, and iPad matrix.
- `swift:test` runs the macOS test target.
- `swift:run` without extra flags follows the configured default platform, which is currently `macos`.
- `swift:run -- --platform ios` boots the configured remote iPhone simulator, installs the app, and launches it.
- `swift:run -- --platform ipad` does the same for the configured remote iPad simulator.
Current `tsswift` behavior here:
## Direct Xcode Use
- `build` targets macOS, iPhone Simulator, and iPad Simulator in parallel
- `test` targets macOS
- `run` defaults to macOS unless you pass `--platform ios` or `--platform ipad`
- `watch` rebuilds and relaunches macOS, iPhone, and iPad app instances on file changes
If you are working directly on a Mac instead of through `tsswift`, open:
The Apple Watch companion is still part of the Xcode project, but `tsswift` is currently configured around the main `IDPGlobal` app targets only.
```text
swift/IDPGlobal.xcodeproj
```
## Mock QR payload
Useful targets and schemes:
The app seeds this pairing payload on first launch:
- `IDPGlobal` for the main app
- `IDPGlobalWatch` for the watch app
- `IDPGlobalWidgets` for widgets
`idp.global://pair?token=swiftapp-demo-berlin&origin=code.foss.global&device=Safari%20on%20Berlin%20MBP`
## Pairing Notes
You can paste it manually, scan it as a QR code, or use the preview pairing action while the backend is still mocked.
For NFC authentication, the app reads the pairing payload from the tag, captures the current device location, signs that GPS position, and submits both together.
## Next integration step
Replace `MockIDPService` with a live service that:
- exchanges the pairing payload and signed NFC location proof for a session token
- loads approval requests and notifications from the backend
- posts approval decisions back to `idp.global`
- syncs session and request state between iPhone and Apple Watch, likely through a shared backend session or WatchConnectivity bridge
- Start a fresh pairing flow from the `idp.global` web session you want to trust.
- Scan the QR shown by that web flow, or paste the pairing link manually if camera access is unavailable.
- NFC flows are for supported iPhone hardware and include signed location evidence.
+1 -1
View File
@@ -13,6 +13,6 @@
"swift:launch": "tsswift launch --path swift/IDPGlobal.xcodeproj"
},
"devDependencies": {
"@git.zone/tsswift": "0.5.2"
"@git.zone/tsswift": "0.6.0"
}
}
+5 -5
View File
@@ -9,8 +9,8 @@ importers:
.:
devDependencies:
'@git.zone/tsswift':
specifier: 0.5.2
version: 0.5.2
specifier: 0.6.0
version: 0.6.0
packages:
@@ -39,8 +39,8 @@ packages:
'@design.estate/dees-element@2.2.4':
resolution: {integrity: sha512-O9cA6flBMMd+pBwMQrZXwAWel9yVxgokolb+Em6gvkXxPJ0P/B5UDn4Vc2d4ts3ta55PTBm+l2dPeDVGx/bl7Q==}
'@git.zone/tsswift@0.5.2':
resolution: {integrity: sha512-ZB8d9gBykrV0EhrOSo600YEoZpIO08xNP0T5qS5CV3vxymSAP86yY5epYazqhnZ9lmWkKUYDgDvc12jVYdeTpA==}
'@git.zone/tsswift@0.6.0':
resolution: {integrity: sha512-XrvzVYml822tWoT9Bogv1GFRf0V6JJnYGxQXZIOqjlzyHQXJSwMD9vh2uePsLn0LfgvEcTvXe3SL+NSlDBuvYw==}
hasBin: true
'@isaacs/cliui@9.0.0':
@@ -993,7 +993,7 @@ snapshots:
- supports-color
- vue
'@git.zone/tsswift@0.5.2':
'@git.zone/tsswift@0.6.0':
dependencies:
'@push.rocks/smartcli': 4.0.20
'@push.rocks/smartconfig': 6.1.0