feat: add Capacitor iOS native shell #83
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/westside-app!83
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "78-capacitor-init-ios"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds Capacitor to westside-app with iOS platform support. The SvelteKit SPA (adapter-static) is now wrapped in a native WKWebView shell for future App Store distribution. Keycloak redirect URIs are platform-aware so OAuth works on both web and native.
Changes
package.json/package-lock.json-- added @capacitor/core, @capacitor/cli, @capacitor/ios, @capacitor/appcapacitor.config.ts-- new config with appIdcom.westsidekingsandqueens.app, appNameWestside Kings & Queens, webDirbuildios/-- generated Xcode project (committed per Capacitor convention)src/lib/keycloak.js-- addedgetBaseUrl()helper usingCapacitor.isNativePlatform()to returncapacitor://localhoston native orwindow.location.originon web; all redirect URIs now use this helperTest Plan
npm run buildproduces static output inbuild/npx cap sync ioscompletes without errorsios/App/App.xcodeprojin Xcode and verify it builds (requires macOS)westside-spaalready hascapacitor://localhost/*in redirect URIsReview Checklist
Related
Review findings
Issue found and fixed:
@capacitor/cliand@capacitor/ioswere placed independenciesinstead ofdevDependencies. These are build-time tools (CLI for cap add/sync/build, iOS platform adapter for native builds) and should not ship as runtime dependencies. Fixed in commit16c4d66.No other issues found:
capacitor.config.tsuses correct appId, appName, webDir, and dev port (5174 matching the vite dev script)getBaseUrl()in keycloak.js correctly usesCapacitor.isNativePlatform()and all threewindow.location.originreferences are updatedios/directory is standard Capacitor boilerplate, committed per conventionios/.gitignoreproperly excludes build artifacts, DerivedData, and generated config filesPR #83 Review
DOMAIN REVIEW
Tech stack identified: SvelteKit (adapter-static) + Capacitor 8.3 (iOS) + Keycloak-js PKCE auth + Swift/Xcode project scaffolding.
This PR adds Capacitor to wrap the existing SvelteKit SPA in a native WKWebView shell for iOS App Store distribution. The meaningful code change is in
src/lib/keycloak.js-- a newgetBaseUrl()helper that returnscapacitor://localhoston native platforms andwindow.location.originon web. All redirect URIs (login,logout,silentCheckSsoRedirectUri) now route through this helper. The rest of the diff is Capacitor-generated Xcode project scaffolding and dependency additions.Dependency placement: Correct.
@capacitor/coreand@capacitor/appare independencies(runtime).@capacitor/cliand@capacitor/iosare indevDependencies(build-time only).Capacitor config:
capacitor.config.tscorrectly setsappId: 'com.westsidekingsandqueens.app',webDir: 'build'(matches adapter-static output), and leavesserverempty for production (local file serving). The commented-out dev server URL is fine for documentation purposes.iOS project: Standard Capacitor scaffold.
IPHONEOS_DEPLOYMENT_TARGET = 15.0is reasonable.PRODUCT_BUNDLE_IDENTIFIERmatches the Capacitor config. NoDEVELOPMENT_TEAMset (correct for scaffold -- developer sets this locally). No signing certs or provisioning profiles committed.Keycloak integration: The
checkLoginIframe: falsesetting on line 58 ofkeycloak.jsis critical and correct -- iframe-based login detection does not work in WKWebView. The platform-awaregetBaseUrl()pattern cleanly handles the OAuth redirect URI difference between web (window.location.origin) and native (capacitor://localhost).Xcode project pbxproj: Clean. Debug and Release configurations are standard. Swift 5.0 target. No hardcoded secrets, no stale team IDs.
BLOCKERS
None.
On the test coverage question: this PR adds a pure platform-detection helper (
getBaseUrl()) and Xcode scaffolding. The project has zero test infrastructure (no vitest, no Playwright, no test files). ThegetBaseUrl()function is a 4-line platform conditional that is inherently validated by the acceptance criteria (build + Xcode open + manual test on device). Requiring test infrastructure as a blocker for this scaffolding PR would be scope creep. The test plan (build verification, cap sync, Xcode build) is appropriate for the nature of the change.NITS
silentCheckSsoRedirectUrion native: Line 56-57 ofkeycloak.jscomputescapacitor://localhost/silent-check-sso.htmlon native. WithcheckLoginIframe: false, keycloak-js still usessilentCheckSsoRedirectUrifor the initialcheck-ssoflow via a hidden iframe. Iframes withcapacitor://URLs may silently fail in WKWebView. Currently this is harmless (if silent SSO fails, the user just has to log in manually), but worth noting for the TestFlight validation pass in issue #80.Generated files tracked despite gitignore:
ios/App/App/capacitor.config.jsonandios/App/App/config.xmlare committed but also listed inios/.gitignore(lines 12-13). This happens becausecap add iosgenerates files before gitignore takes effect. Futurecap syncruns will regenerate these files, which git will then ignore (since they are already tracked, git will show modifications). Consider runninggit rm --cached ios/App/App/capacitor.config.json ios/App/App/config.xmlso gitignore can take over, or remove those entries from.gitignoreto intentionally track them. Either approach is fine -- the current state is just ambiguous.config.xmlwildcard access:ios/App/App/config.xmlcontains<access origin="*" />, which allows the WebView to load any URL. This is the Capacitor default and acceptable for a Keycloak-authenticated app that needs to reach external services, but should be locked down to specific origins (keycloak.tail5b443a.ts.net,basketball-api.tail5b443a.ts.net,minio-api.tail5b443a.ts.net) before App Store submission as a hardening measure.No
cap:syncorcap:buildnpm scripts: Consider adding convenience scripts topackage.json(e.g.,"cap:sync": "npm run build && npx cap sync ios") to standardize the native build workflow. Minor quality-of-life item.SOP COMPLIANCE
78-capacitor-init-iosreferences issue #78)Closes #78PROCESS OBSERVATIONS
npm ci+check+build) is unaffected. Positive for DF -- parallel distribution channels without coupling.getBaseUrl()inkeycloak.js. Web behavior is unchanged (Capacitor.isNativePlatform()returnsfalseon web). Native behavior is new scope validated by TestFlight (issue #80).VERDICT: APPROVED