This commit is contained in:
@@ -1,70 +1,144 @@
|
|||||||
# idp.global Swift App
|
# 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
|
- iPhone pairing starts on a welcome screen and then opens QR scanning explicitly.
|
||||||
- NFC authentication now attaches a signed GPS position on supported iPhone hardware
|
- QR pairing supports a manual paste fallback when camera scanning is unavailable.
|
||||||
- Mocked approval inbox for accepting or rejecting identity requests
|
- NFC pairing and NFC identity proof attach a signed GPS position on supported iPhones.
|
||||||
- Notification center with local notification permission flow and a test notification trigger
|
- The app uses the live `idp.global` backend by default for pairing, dashboard loading, approvals, and alerts.
|
||||||
- Apple Watch companion target with a compact approval-first dashboard and request detail flow
|
- The Apple Watch companion and widgets live in the same Xcode project and build with the main app scheme.
|
||||||
- Shared app state and mock backend boundary so a real API can be connected later
|
- `MockIDPService` still exists for previews and test scaffolding, but normal runtime uses `LiveIDPService`.
|
||||||
|
|
||||||
## Open the project
|
## Repo Layout
|
||||||
|
|
||||||
1. Open `swift/IDPGlobal.xcodeproj`.
|
- root `package.json`
|
||||||
2. Build the `IDPGlobal` scheme for:
|
- root `.smartconfig.json`
|
||||||
- `My Mac`
|
- Swift project at `swift/IDPGlobal.xcodeproj`
|
||||||
- an iPad simulator
|
|
||||||
- an iPhone simulator
|
|
||||||
3. Build the `IDPGlobalWatch` scheme for an Apple Watch simulator when you want to verify the companion experience.
|
|
||||||
|
|
||||||
## 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:
|
From the repo root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
corepack pnpm install
|
|
||||||
corepack pnpm swift:doctor
|
corepack pnpm swift:doctor
|
||||||
corepack pnpm swift:emulators
|
corepack pnpm swift:emulators
|
||||||
corepack pnpm swift:build
|
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:test
|
||||||
corepack pnpm swift:run
|
corepack pnpm run swift:run -- --platform ios
|
||||||
|
corepack pnpm run swift:run -- --platform ipad
|
||||||
corepack pnpm swift:watch
|
corepack pnpm swift:watch
|
||||||
```
|
```
|
||||||
|
|
||||||
This repo now follows the same layout as the other Swift app repos:
|
Notes:
|
||||||
|
|
||||||
- git root at the repo root
|
- `swift:build` builds the configured macOS, iPhone, and iPad matrix.
|
||||||
- root `package.json`
|
- `swift:test` runs the macOS test target.
|
||||||
- root `.smartconfig.json`
|
- `swift:run` without extra flags follows the configured default platform, which is currently `macos`.
|
||||||
- Swift app content under `swift/`
|
- `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
|
If you are working directly on a Mac instead of through `tsswift`, open:
|
||||||
- `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
|
|
||||||
|
|
||||||
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.
|
- 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.
|
||||||
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.
|
- NFC flows are for supported iPhone hardware and include signed location evidence.
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|||||||
+1
-1
@@ -13,6 +13,6 @@
|
|||||||
"swift:launch": "tsswift launch --path swift/IDPGlobal.xcodeproj"
|
"swift:launch": "tsswift launch --path swift/IDPGlobal.xcodeproj"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsswift": "0.5.2"
|
"@git.zone/tsswift": "0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+5
-5
@@ -9,8 +9,8 @@ importers:
|
|||||||
.:
|
.:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@git.zone/tsswift':
|
'@git.zone/tsswift':
|
||||||
specifier: 0.5.2
|
specifier: 0.6.0
|
||||||
version: 0.5.2
|
version: 0.6.0
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@@ -39,8 +39,8 @@ packages:
|
|||||||
'@design.estate/dees-element@2.2.4':
|
'@design.estate/dees-element@2.2.4':
|
||||||
resolution: {integrity: sha512-O9cA6flBMMd+pBwMQrZXwAWel9yVxgokolb+Em6gvkXxPJ0P/B5UDn4Vc2d4ts3ta55PTBm+l2dPeDVGx/bl7Q==}
|
resolution: {integrity: sha512-O9cA6flBMMd+pBwMQrZXwAWel9yVxgokolb+Em6gvkXxPJ0P/B5UDn4Vc2d4ts3ta55PTBm+l2dPeDVGx/bl7Q==}
|
||||||
|
|
||||||
'@git.zone/tsswift@0.5.2':
|
'@git.zone/tsswift@0.6.0':
|
||||||
resolution: {integrity: sha512-ZB8d9gBykrV0EhrOSo600YEoZpIO08xNP0T5qS5CV3vxymSAP86yY5epYazqhnZ9lmWkKUYDgDvc12jVYdeTpA==}
|
resolution: {integrity: sha512-XrvzVYml822tWoT9Bogv1GFRf0V6JJnYGxQXZIOqjlzyHQXJSwMD9vh2uePsLn0LfgvEcTvXe3SL+NSlDBuvYw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
'@isaacs/cliui@9.0.0':
|
'@isaacs/cliui@9.0.0':
|
||||||
@@ -993,7 +993,7 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
'@git.zone/tsswift@0.5.2':
|
'@git.zone/tsswift@0.6.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartcli': 4.0.20
|
'@push.rocks/smartcli': 4.0.20
|
||||||
'@push.rocks/smartconfig': 6.1.0
|
'@push.rocks/smartconfig': 6.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user