Allow owners to turn on an auto-generated access password when sharing a note. Visitors must unlock the share page before reading the note or its attachments; existing public links stay open until a password is enabled.
EdgeEver iOS (Swift)
Native SwiftUI client for EdgeEver. This replaces the React Native / Expo iOS target.
App Store binaries on macOS beta: use Xcode Cloud (manual) — docs/ios-xcode-cloud.md.
Status
UI/interaction is aligned with the Android RN app (apps/mobile):
- Login / session (Keychain with UserDefaults fallback) / device id
- GRDB local mirror + bootstrap / incremental sync
- SQLite outbox (create/update, create-absorbs-update, conflict/retry)
- Workspace chrome: notebook title picker, search (250ms debounce), filter chips, list options (sort/density/batch), FAB create, long-press multi-select, swipe pin/delete
- Memo detail + create/edit autosave, share link, revisions, soft delete
- EditorBundle (WKWebView body + toolbar)
- Image pick + materialize-for-upload (K24) + protected resource blob loading
- Settings: general / account / tags / API tokens / devices / users (owner) / about
- Share Extension (text/URL → App Group → new draft)
- Locale (system/zh/en) + theme + list density
Android remains Expo / React Native in apps/mobile. Store builds for iOS use this native tree (Scripts/archive-app-store.sh), not EAS.
Motion / animations
Motion stack: SwiftUI Animation (timing / springs) + Pow (Emerge).
| Effect | Where |
|---|---|
| Jump (physics hop + squash) | First list open (whole list); create/edit return on that memo |
| Boing (elastic drop-in) | Staggered first-paint cards |
| Ping | Create button / returned memo highlight |
| Shine / Shake / Haptic | Pin success, errors, selection |
| SwiftUI scale press | Card / create / filter finger-down |
Curves & wrappers: EdgeEver/DesignSystem/Motion.swift.
Requirements
- Xcode 16+ (Xcode 27 beta OK for local dev)
- iOS 17+ deployment target
- XcodeGen to regenerate the project
brew install xcodegen
Generate & open
cd apps/ios
xcodegen generate
open EdgeEver.xcodeproj
Tests
# Unit + live API tests (live tests skip if local server is down)
xcodebuild test \
-project EdgeEver.xcodeproj \
-scheme EdgeEver \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'
Live API tests login to http://127.0.0.1:8787 using EDGE_EVER_AUTH_PASSWORD or monorepo .env.wrangler.generated.local.
Simulator auto-login (QA)
With local bun run dev running:
xcrun simctl launch booted org.edgeever.mobile \
-EdgeEverAutoLoginURL "http://127.0.0.1:8787" \
-EdgeEverAutoLoginUser admin \
-EdgeEverAutoLoginPassword "$EDGE_EVER_AUTH_PASSWORD"
Versioning
| Field | File | Notes |
|---|---|---|
MARKETING_VERSION |
Config/Version.xcconfig |
Align with monorepo release X.Y.Z on store submissions |
CURRENT_PROJECT_VERSION |
Config/Version.xcconfig |
Local floor for build numbers |
Xcode Cloud stamps CFBundleVersion from App Store Connect → Xcode Cloud → Build Number (not only this file). Before a Cloud store run, set that counter above the latest ASC build (Scripts/ensure-xcode-cloud-build-number.sh prints the recommended value).
App Store archive
Preferred: Xcode Cloud (manual only)
If the Mac runs macOS beta, local archives are rejected by App Store Connect (ITMS-90111) even with release Xcode. Day-to-day development stays local; only store / TestFlight binaries should use Xcode Cloud (25 compute hours/month with Apple Developer Program).
- Setup and workflow:
docs/ios-xcode-cloud.md - Cloud hooks:
ci_scripts/ci_post_clone.sh→ci_pre_xcodebuild.sh→ci_post_xcodebuild.sh - Workflow start condition must stay Manual so hours are not burned on every push
- Put ASC API secrets in Xcode Cloud shared environment variables so
ci_post_xcodebuild.shauto-uploads the App Store IPA
# Before Start Build (optional but recommended)
cd apps/ios
bash Scripts/ensure-xcode-cloud-build-number.sh
# If Cloud produced ARCHIVE_EXPORT but ASC has no build:
bash Scripts/upload-app-store-ipa.sh /path/to/EdgeEver-*-app-store.zip
Local archive (release macOS only)
Use the stable Xcode app (not beta) on a non-beta host OS:
cd apps/ios
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer bash Scripts/archive-app-store.sh
bash Scripts/upload-app-store-ipa.sh build/export/EdgeEver.ipa
On a beta host the script exits unless you set EDGE_EVER_IOS_ALLOW_BETA_HOST=1 (upload will still likely fail ASC).
Signing in the Xcode project is Automatic (Cloud-friendly). Local export still uses ExportOptions.plist with App Store profiles. Then submit the exact build with:
cd apps/ios
APP_STORE_VERSION=X.Y.Z APP_STORE_BUILD_NUMBER=N \
APP_STORE_CONNECT_API_KEY_ID=... \
APP_STORE_CONNECT_API_ISSUER_ID=... \
APP_STORE_CONNECT_API_KEY_P8_BASE64=... \
fastlane ios submit_review
Regenerating the Xcode project
Edit project.yml, then:
xcodegen generate