Skip to content

feat(ios): iOS app (App Store) - #715

Draft
kipavy wants to merge 35 commits into
devfrom
ci/ios
Draft

kipavy wants to merge 35 commits into
devfrom
ci/ios

Conversation

@kipavy

@kipavy kipavy commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Draft: iOS port (App Store build). Opened to run the full CI on the branch; not ready to merge.

  • ios.yml: signed App Store package (bundle id app.voltius), simulator run with screenshots, TestFlight upload on demand.
  • Mobile shell on iOS (isMobileShell() covers iOS), Face ID, data-protection keychain, SFTP downloads to the Files app, native share sheet and haptics (ios_native.rs), serial enumeration and MCP off on iOS.
  • asc.yml: App Store Connect API (status, listing).

🤖 Generated with Claude Code

https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE

kipavy and others added 30 commits October 24, 2026 19:10
First probe of the iOS build: bundle id app.voltius, manual signing with the
Apple Distribution certificate and App Store profile, purchases hidden
(VITE_DISTRIBUTION=appstore).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
- system_auth: the LocalAuthentication backend also runs on iOS.
- Register the protected store of apple-native-keyring-store on iOS, so
  secrets survive restarts.
- Info.ios.plist: NSFaceIDUsageDescription (iOS kills the app without it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
Also turn the MCP server off on iOS, as on Android.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
On iOS, download_dir_get points at the app Documents folder and download_publish moves the finished download there (with a (2), (3)... suffix on name clashes). UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace make the folder visible in Files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
Appium (XCUITest) taps the screen and reads the WebView DOM of a debug
build; a throwaway asyncssh server on the runner plays the remote host.
Each step leaves a screenshot and a DOM dump in the voltius-ios-e2e
artifact, with a summary of passed and failed steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
The phone UI was gated on "android" only, so iOS loaded the desktop shell.

- platform.ts: isMobilePlatform (android or ios), useIsMobile, useIsIOS;
  isMobileShell and App.tsx now pick MobileShell on both phones.
- Layout and UX checks move from useIsAndroid to useIsMobile (settings rows,
  sheets, pickers, notes, toasts, import/export, hosts toolbar, no local
  shells). Android-only native bridges stay on useIsAndroid: soft keyboard
  overlay, selection touch feed, Material You palette, system bars,
  volume-down Ctrl, SAF folder picker, file sharing.
- Desktop-only features also skip iOS: ~/.ssh/config sync, MCP server push.
  Passkey sign-in returns through the voltius:// link on both phones.
- iOS fallbacks: a tap on the terminal focuses xterm so the system keyboard
  opens; SFTP downloads take the Android temp -> publish path (the native side
  publishes into the app Documents folder, so the settings show the folder
  read-only, without the picker); text sharing uses the Web Share API; text
  exports are written into Documents.
- Face ID / Touch ID / passcode wording for the system unlock prompt.
- Test mocks of @/utils/platform learn the new helpers; tests for the
  platform helpers and the iOS share path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
ios_native.rs calls UIKit through the Objective-C runtime: UIActivityViewController for staged files (the Web Share API needs a fresh tap, which the download before sharing outlives) and UIFeedbackGenerator for haptics. Both commands are no-ops elsewhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
…he report

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
The previous/next/done bar above the iOS keyboard pushed the terminal extra-keys row up; WKContentView inputAccessoryView now returns nil (as Capacitor does). The app targets iPhone only (TARGETED_DEVICE_FAMILY = 1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
workflow_dispatch store=true builds with VITE_DEMO_SEED=1 (window.__voltiusDemoSeed, left out of normal bundles), runs on a 6.9-inch iPhone with a clean status bar, opens the shell and SFTP in a demo folder and saves the hosts, terminal, SFTP, snippets and more screens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
kipavy and others added 5 commits October 25, 2026 15:05
iOS zooms in when an input with text under 16px gets focus and keeps the page zoomed and shifted afterwards. maximum-scale=1 stops it (the app has its own UI scale setting). The store run goes back to the tab bar and retries the shell when the first handshake stalls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
…sers/deploy

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ly4RP96nLUnj4FWtWthpE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant