iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

iOS Build

Building an Ionic app for iOS goes through Capacitor + Xcode. The pipeline: build the web bundle, copy it into the iOS project, open in Xcode, configure signing, archive, and upload to App Store Connect via Transporter or fastlane. Most pain comes from signing — once that is sorted, the rest is a few clicks.

End-to-end iOS build, signing, and TestFlight upload

EXAMPLE
# 1) Prerequisites
# - macOS with Xcode (latest stable)
# - Apple Developer account with App ID + paid membership
# - CocoaPods: 'sudo gem install cocoapods' (or brew install cocoapods)
# - Node, Ionic CLI: 'npm i -g @ionic/cli'

# 2) Add the iOS platform once per project
ionic capacitor add ios

# 3) Build the web bundle for production
ionic build --prod
# Then sync the built assets into the native project
ionic capacitor sync ios

# 4) Set the bundle id, version, build number in
#    ios/App/App.xcodeproj/project.pbxproj (or via Xcode GUI)
#    - General > Identity > Bundle Identifier: au.com.example.shop
#    - Version (Marketing): 1.4.0   |   Build: 142

# 5) Open in Xcode for signing + capabilities
ionic capacitor open ios

# In Xcode:
# - Signing & Capabilities tab
#   - Team: <your Apple Dev team>
#   - 'Automatically manage signing' on (for dev) or off (for CI with manual profiles)
# - Add capabilities you use (Push, Sign in with Apple, Associated Domains, etc.)

# 6) Privacy: every native capability needs an Info.plist key
# ios/App/App/Info.plist
# <key>NSCameraUsageDescription</key>
# <string>We use the camera to scan order QR codes.</string>
# <key>NSLocationWhenInUseUsageDescription</key>
# <string>We use your location to suggest nearby pickup points.</string>

# 7) Build an archive (release mode) and upload
# In Xcode: Product > Scheme > Edit Scheme > Run > Build Configuration = Release
# Then: Product > Archive
# Window > Organizer > Distribute App > App Store Connect > Upload

# 8) Or fastlane it (CI-friendly) — one command per release
# Fastfile (ios/)
# lane :beta do
#   match(type: 'appstore', readonly: true)              # signing via Match
#   build_app(scheme: 'App', workspace: 'App.xcworkspace', export_method: 'app-store')
#   upload_to_testflight(skip_waiting_for_build_processing: true)
# end
# Run: cd ios && bundle exec fastlane beta

# 9) Common gotchas
# - 'No bundle URL present' on dev build: 'ionic capacitor sync ios' before opening Xcode.
# - 'Profile doesn't include the Push Notification entitlement': enable Push in Apple Developer
#   and regenerate provisioning profile.
# - 'iTunes Connect rejection: app uses non-public API': remove offending plugins
#   (often older Cordova plugins).
# - Architectures: Apple Silicon vs Intel — set Excluded Architectures = arm64 ONLY for
#   the Simulator if a plugin's binary lacks arm64.

# 10) Post-upload
# App Store Connect > TestFlight > Builds (wait 10-30 min for processing)
# Add testers (internal first, then external). Internal builds skip review.

Why it matters

Once you have signed even one build by hand, switch to fastlane match for shared signing. It stores certificates and profiles in an encrypted git repo so the same profile works for every developer and every CI machine — no more "works on Lisas Mac" certificate races on release day.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
ionic build
npx cap sync ios
npx cap open ios   # → Archive in Xcode → upload to App Store Connect
Try it Yourself »

Discussion

Loading…