iOS Build
iOS builds require macOS with Xcode and an Apple Developer Program membership ($99/year) for App Store distribution.
One-time setup
- Install Xcode from the Mac App Store, open it once to finish component setup.
sudo xcode-select --switch /Applications/Xcode.appflutter doctorshould show a green iOS toolchain.
Configure signing
- Open the project in Xcode:
open ios/Runner.xcworkspace
- Select the Runner target → Signing & Capabilities.
- Choose your Team. The bundle identifier is already set by
tool/apply_config.dartto the value from your admin panel. - If you use push notifications: add the Push Notifications capability and enable Background Modes → Remote notifications.
- If you use deep links: add the Associated Domains capability with
applinks:yourdomain.comfor each deep-link domain.
Build & upload
Test on a device/simulator:
flutter run
Release build + upload:
flutter build ipa --release
Then open build/ios/archive/Runner.xcarchive in Xcode → Distribute App → App Store Connect (or upload the .ipa from build/ios/ipa/ with the Transporter app).
Push notifications on iOS
FCM needs an APNs key: Apple Developer → Certificates → Keys → create an APNs Auth Key (.p8), then upload it in Firebase Console → Project Settings → Cloud Messaging → Apple app configuration. Without this step iOS pushes will not arrive even though Android works.
Universal Links
Enter your Apple Team ID (Developer account → Membership) on the admin Applications page, re-download the configuration package and upload the generated website/.well-known/apple-app-site-association file to your website — served over HTTPS, Content-Type: application/json, no file extension.
Permissions compiled into the binary
ios/Podfile ships with a # --- appforge:permissions --- block that decides which permission handlers are compiled in. tool/apply_config.dart rewrites it from your admin panel's Permissions page, so the binary only references the APIs your app actually uses.
This matters: with every handler compiled in, App Store review sees references to contacts, calendar, health and similar frameworks that have no usage description, and rejects the upload with ITMS-90683: Missing Purpose String.
Keep the marker comments intact, and re-run dart run tool/apply_config.dart after changing permissions in the panel. If you edit the Podfile by hand, run pod install from the ios/ folder afterwards.
Usage descriptions
Info.plist usage texts (camera, microphone, location, photos, Face ID) are inserted automatically from the admin Permissions page — App Store review rejects apps with missing or generic texts, so write honest, specific sentences.