# iOS app setup — Xcode steps The Capacitor shell + Share Extension code are committed. Xcode can't auto-register a new target from disk, so one-time Xcode work is needed before the first build. ## 1. Open the workspace ```bash cd web pnpm exec cap sync ios pnpm exec cap open ios ``` `cap sync` copies the latest web build into `ios/App/App/public` and refreshes config. `cap open` launches Xcode on `ios/App/App.xcworkspace`. ## 2. Configure signing on the App target - Click the `App` project → `App` target → **Signing & Capabilities**. - Team: your Apple Developer team. - Bundle identifier: `fr.arthurbarre.anydrop`. - Add capability: **App Groups** → create `group.fr.arthurbarre.anydrop`. - Set the entitlements file to `App/App.entitlements` (already committed). ## 3. Add the Share Extension target - File → New → Target → iOS → **Share Extension**. - Product name: `AnyDropShare`. - Language: Swift. - Bundle identifier: `fr.arthurbarre.anydrop.Share`. - **Delete the auto-generated files** Xcode just created (ShareViewController.swift, MainInterface.storyboard, Info.plist). - In the Project navigator, right-click the `AnyDropShare` group → **Add Files to "App"…** → select the files already in `ios/App/AnyDropShare/`: - `ShareViewController.swift` - `Info.plist` - `AnyDropShare.entitlements` - With `AnyDropShare` target selected → Build Settings → search `Info.plist File` → set to `AnyDropShare/Info.plist`. - Build Settings → `Code Signing Entitlements` → set to `AnyDropShare/AnyDropShare.entitlements`. - **Signing & Capabilities** on the extension target: - Same team. - **Add capability → App Groups** → check `group.fr.arthurbarre.anydrop` (same as main app). - Also remove `MainInterface.storyboard` reference in the extension's Info.plist if Xcode re-added one — we use `ShareViewController` programmatically (`NSExtensionPrincipalClass`), no storyboard. ## 4. Build + run - Plug in an iPhone (Simulator also works but AirDrop/Messages targets aren't there). - Select the `App` scheme → pick your device → ⌘R. - First launch, iOS may ask to trust the developer certificate (Settings → General → VPN & Device Management). ## 5. Test the share flow 1. Open Photos, select one or more images/videos, tap Share. 2. Tap **AnyDrop** in the app row (scroll if needed — you can drag it to the front via "Edit Actions"). 3. Extension runs → writes files to the App Group → opens `anydrop://share`. 4. Main app catches the URL → Capacitor fires `appUrlOpen` → JS drains the inbox → `/share` page shows the selected peer list → pick a device → P2P send. ## 6. Ship updates - **Web changes** (anything under `web/src`): the app loads from `https://anydrop.arthurbarre.fr`, so redeploying the web is enough. No App Store review needed. - **Native changes** (Swift, Info.plist, entitlements, Capacitor config): rebuild + re-archive + TestFlight or direct install. ## Known gotchas - **Custom URL scheme requires a real app install.** Testing in Safari or the PWA will not fire `appUrlOpen`. - **App Group must match exactly** on both targets (`group.fr.arthurbarre.anydrop`). If they diverge, the extension writes and the app reads different directories. - **Camera/photo permission** prompt appears the first time the extension is used; the copy is in `App/Info.plist` (`NSPhotoLibraryUsageDescription`). - **Cookies / sessions** in Capacitor's WKWebView are **not** shared with Safari. Users will need to sign in inside the app once.