355b14faef
Enable App Store builds without EAS, iOS 18 App Intents plugins, and signing fixes for distribution export. Add mobile invoice PDF preview, compact line items, and more reliable shortcut deep-link handling. Co-authored-by: Cursor <cursoragent@cursor.com>
89 lines
3.8 KiB
Markdown
89 lines
3.8 KiB
Markdown
# Local iOS release (no EAS)
|
||
|
||
Archive and upload **beenvoice** to App Store Connect using Xcode on your Mac — no Expo Application Services (EAS) subscription required.
|
||
|
||
## Prerequisites
|
||
|
||
- macOS with **Xcode** (same major version you use for development)
|
||
- **Apple Developer Program** membership
|
||
- App record in [App Store Connect](https://appstoreconnect.apple.com) with bundle ID `com.beenvoice.app`
|
||
- **Distribution** signing set up in Xcode (automatic signing + team is enough for most cases)
|
||
- [App Store Connect API key](https://appstoreconnect.apple.com/access/integrations/api) (for upload only)
|
||
|
||
## One-time setup
|
||
|
||
```bash
|
||
cd beenvoice-app
|
||
cp .ios-release.env.example .ios-release.env
|
||
```
|
||
|
||
Edit `.ios-release.env`:
|
||
|
||
| Variable | Where to find it |
|
||
|----------|------------------|
|
||
| `APPLE_TEAM_ID` | [developer.apple.com/account](https://developer.apple.com/account) → Membership → Team ID |
|
||
| `APP_STORE_CONNECT_API_KEY_ID` | App Store Connect → Users and Access → Integrations → Keys |
|
||
| `APP_STORE_CONNECT_API_ISSUER_ID` | Same page (Issuer ID at top) |
|
||
| `APP_STORE_CONNECT_API_KEY_PATH` | Path to downloaded `AuthKey_XXXXXX.p8` |
|
||
| `EXPO_PUBLIC_API_URL` | Production API URL baked into the release bundle |
|
||
|
||
Optional: store the `.p8` in `~/.appstoreconnect/private_keys/` (never commit it).
|
||
|
||
Open the iOS project once in Xcode and confirm **Signing & Capabilities** succeeds for targets **beenvoice** and **ExpoWidgetsTarget**.
|
||
|
||
## Commands
|
||
|
||
```bash
|
||
# Archive + export signed IPA to dist/ios-release/export/
|
||
bun run ios:release
|
||
|
||
# Archive + export + upload to App Store Connect (TestFlight)
|
||
bun run ios:release:upload
|
||
```
|
||
|
||
### Flags (pass through to the script)
|
||
|
||
```bash
|
||
bash scripts/ios-release.sh --archive-only # .xcarchive only
|
||
bash scripts/ios-release.sh --export-only --upload # re-upload existing archive
|
||
bash scripts/ios-release.sh --no-prebuild # skip expo prebuild
|
||
bash scripts/ios-release.sh --no-bump # don't increment build number
|
||
```
|
||
|
||
With `IOS_BUMP_BUILD=1` in `.ios-release.env`, each run bumps `CFBundleVersion` via `agvtool` (recommended for repeated TestFlight uploads).
|
||
|
||
## What the script does
|
||
|
||
1. `expo prebuild --platform ios` (unless `--no-prebuild`)
|
||
2. `pod install`
|
||
3. Optional build-number bump (`agvtool`)
|
||
4. `xcodebuild archive` (Release, generic iOS device)
|
||
5. `xcodebuild -exportArchive` → App Store IPA
|
||
6. `xcrun altool --upload-app` (with `--upload` only)
|
||
|
||
Artifacts land in `dist/ios-release/` (gitignored).
|
||
|
||
## After upload
|
||
|
||
1. App Store Connect → **TestFlight** — wait for “Processing” to finish
|
||
2. Smoke-test on device
|
||
3. Submit for App Store review when ready
|
||
|
||
See also [APP_STORE_CONNECT.md](./APP_STORE_CONNECT.md) for metadata, screenshots, and review notes.
|
||
|
||
## Notes
|
||
|
||
- **Dev client:** `expo-dev-client` is in the native project today. Store builds still work, but the binary includes the dev client shell. For a slimmer production binary, remove that plugin and re-run prebuild before release (or maintain a separate `app.config` variant).
|
||
- **Manual upload:** After `bun run ios:release`, drag the IPA into Apple’s [Transporter](https://apps.apple.com/app/transporter/id1450874784) app instead of using `--upload`.
|
||
- **CI:** Run the same script on a Mac runner (GitHub `macos-latest`, etc.) with secrets injected as env vars instead of `.ios-release.env`.
|
||
|
||
## Troubleshooting
|
||
|
||
| Issue | Fix |
|
||
|-------|-----|
|
||
| No signing certificate | Xcode → Settings → Accounts → Download Manual Profiles; or open project and enable automatic signing |
|
||
| `pod install` fails | `cd ios && pod repo update && pod install` |
|
||
| Upload auth error | Verify API key has **Developer** access; check Key ID, Issuer ID, and `.p8` path |
|
||
| Duplicate build number | Enable `IOS_BUMP_BUILD=1` or bump `CURRENT_PROJECT_VERSION` in Xcode |
|
||
| Widget extension signing | Both **beenvoice** and **ExpoWidgetsTarget** need the same team |
|