Generate the manifest/PWA + native-wrapper icons that were referenced but missing (icon-192/512 were 404). A reproducible pure-Node generator (tools/gen-icons.mjs, npm run gen:icons) draws a clock ring with amber hands + a green target dot in the app palette — no image deps, hand-rolled PNG encoder with analytic anti-aliasing. - public/icons/icon-192, -512, -180 (apple-touch); linked in index.html. - resources/icon.png (1024) + splash.png (2732) for @capacitor/assets. - tests/tools/icons.test.js ties every manifest icon to a real PNG of the declared size. 213 tests pass; icons now serve 200. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.6 KiB
The Director — native iPad wrapper (Capacitor)
The app ships as an offline-first PWA; this wraps that same build in a thin native
iOS shell (a WKWebView) so it can be installed from Xcode / TestFlight and get a
real home-screen app, splash screen, and App Store path. No app logic changes —
Capacitor serves the dist/ build locally on the device.
The Capacitor config, scripts, and integration are committed. Generating and building the actual iOS project must be done on a Mac with the toolchain below — it cannot be produced without Xcode + CocoaPods.
Prerequisites (on the Mac)
- Full Xcode (not just Command Line Tools). Then point the toolchain at it:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developerand accept the licence (sudo xcodebuild -license accept). - CocoaPods:
brew install cocoapods(orsudo gem install cocoapods). - Node ≥ 20 (Capacitor 8) — already required to build the web app.
Check: xcodebuild -version and pod --version should both print a version.
One-time: generate the iOS project
npm install # pulls @capacitor/core, cli, ios (devDependencies)
npm run ios:add # = vite build → npx cap add ios (runs pod install)
This creates ios/ (an Xcode project under ios/App). Commit it — it is the native
project source. Generated/derived paths inside it are git-ignored (see .gitignore).
App icons + splash (once): placeholder sources are provided at resources/icon.png
(1024²) and resources/splash.png (2732²) — regenerate with npm run gen:icons, or
replace them with real art. Then npx @capacitor/assets generate --ios.
Every build after a web change
npm run ios:sync # = vite build → npx cap sync ios (copies fresh web assets + plugins)
npm run ios:open # opens ios/App/App.xcworkspace in Xcode
# or in one step:
npm run ios
In Xcode: pick your Team (Signing & Capabilities), choose an iPad simulator or a connected iPad, and Run (⌘R). For a device/TestFlight build you need an Apple Developer account and a signing profile.
Config
appId—uk.timevans.thedirector. Change this before the firstios:add(changing the bundle id after generation means regenerating or editing Xcode).webDir: dist— the vite output the shell serves.ios.contentInset: always+viewport-fit=coverinindex.htmlhandle the safe areas (notch / home indicator) so the Director Rail sits correctly.backgroundColormatches the app theme so there is no white flash on launch.
iOS-specific notes
- Offline: fully native — the web assets are bundled in the app, so it works with
no network regardless of the service worker. The browser PWA still uses
sw.js; the wrapper skips SW registration (window.Capacitor.isNativePlatform()inmain.js) to avoid a redundant SW under thecapacitor://scheme. - Keep-awake (💡):
navigator.wakeLockis unreliable inside WKWebView. For a solid screen-on toggle in the native build, add@capacitor-community/keep-awakeand callKeepAwake.keepAwake()/.allowSleep()from the shell's wake toggle whenwindow.Capacitoris present. The current toggle degrades gracefully until then. - Online art "Generate": works the same — it calls the GM-configured endpoint over the network when connected.
- Orientation: the manifest requests landscape; set the same in Xcode (Deployment Info → iPad → Landscape only) so it matches at the table.