Why Your Flutter App is Crashing on iOS 19: A Migration Guide
Why Your Flutter App is Crashing on iOS 19: A Migration Guide
You've just updated your iPhone to iOS 19, or users are reporting crashes after the update. Your Flutter app that worked perfectly on iOS 18 is now breaking. Sound familiar?
iOS 19 introduced significant changes that affect how Flutter apps interact with the system, particularly around privacy, app lifecycle, and native dependencies. These changes can cause crashes, build failures, or runtime errors if not addressed.
Quick Solution: Update your
Info.plistwith required privacy manifest, addPrivacyInfo.xcprivacyfile, update Flutter to 3.24+, and ensure all native dependencies are iOS 19 compatible. Check yourPodfileand runpod installafter updating.
This guide covers the critical changes in iOS 19 and provides step-by-step migration instructions to get your Flutter app working again.
What Changed in iOS 19?
iOS 19 brings several breaking changes that affect Flutter apps:
- Privacy Manifest Requirements - Apps must declare data collection practices
- App Lifecycle Changes - New background execution rules
- Native Dependency Updates - Many CocoaPods need updates
- Xcode 16 Requirements - New build system and Swift 6 compatibility
- Entitlements Changes - New privacy-related entitlements
Let's address each one systematically.
Issue 1: Privacy Manifest Missing (Most Common Crash)
The Problem
Your app crashes on launch with errors like:
This app's privacy manifest does not include the required reason API usage description.
Or in Xcode:
Privacy manifest file is missing or invalid.
Why It Happens
iOS 19 requires all apps to include a Privacy Manifest (PrivacyInfo.xcprivacy) that declares:
- What data your app collects
- Which privacy-sensitive APIs you use
- Why you use those APIs
Solution: Add Privacy Manifest
Step 1: Create PrivacyInfo.xcprivacy File
Create a new file in your iOS project:
Location: ios/Runner/PrivacyInfo.xcprivacy
Content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<!-- Required APIs -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryActiveKeyboards</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>54BD.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<!-- Add your data collection types here -->
<!-- Example:
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeDeviceID</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
-->
</array>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
</dict>
</plist>
Step 2: Add to Xcode Project
- Open
ios/Runner.xcworkspacein Xcode - Right-click on
Runnerfolder → "Add Files to Runner" - Select
PrivacyInfo.xcprivacy - Ensure "Copy items if needed" is checked
- Ensure "Runner" target is selected
Step 3: Verify in Build Settings
In Xcode, go to Build Settings → Search for "Privacy" → Ensure PrivacyInfo.xcprivacy is included in the build.
Common Privacy API Reasons
Here are the most common reasons you'll need:
| API Category | Reason Code | Description |
|---|---|---|
| File Timestamp | C617.1 | Access file modification date |
| System Boot Time | 35F9.1 | Calculate time intervals |
| Disk Space | E174.1 | Check available storage |
| Active Keyboards | 54BD.1 | Detect keyboard language |
Issue 2: Info.plist Missing Required Keys
The Problem
App crashes or fails to launch with missing permission descriptions.
Solution: Update Info.plist
Add these required keys to ios/Runner/Info.plist:
<key>NSUserTrackingUsageDescription</key>
<string>We use this to provide personalized content. Your data stays private.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photos to let you select images.</string>
<key>NSCameraUsageDescription</key>
<string>We need camera access to let you take photos.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to show nearby content.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need microphone access for voice features.</string>
Important: Only include keys for features your app actually uses. Apple will reject your app if you request permissions you don't use.
Issue 3: App Lifecycle Changes
The Problem
Your app behaves incorrectly when:
- Going to background/foreground
- Receiving push notifications
- Handling deep links
- Managing background tasks
Solution: Update App Lifecycle Handling
Update Flutter Version
First, ensure you're on Flutter 3.24+ which includes iOS 19 lifecycle fixes:
flutter upgrade
flutter pub get
Update AppDelegate (if using custom code)
If you have custom AppDelegate.swift, update it:
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// iOS 19: Ensure proper initialization
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// iOS 19: New lifecycle method
override func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
return UISceneConfiguration(
name: "Default Configuration",
sessionRole: connectingSceneSession.role
)
}
}
Update Background Modes
In Info.plist, ensure background modes are properly declared:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
<!-- Only include modes you actually use -->
</array>
Issue 4: CocoaPods Dependencies Outdated
The Problem
Build fails with errors like:
[!] CocoaPods could not find compatible versions
Or runtime crashes from outdated native dependencies.
Solution: Update Pods
Step 1: Update Podfile
Open ios/Podfile and ensure minimum iOS version:
platform :ios, '13.0' # iOS 19 requires at least iOS 13, but consider 15.0+
Step 2: Update CocoaPods
cd ios
pod repo update
pod deintegrate
pod install
cd ..
Step 3: Clean Build
flutter clean
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..
flutter pub get
Step 4: Update Flutter Plugins
Check for plugin updates:
flutter pub upgrade
Common plugins that need updates for iOS 19:
firebase_core- Update to latestgoogle_sign_in- Requires 6.0+image_picker- Requires 1.0.7+permission_handler- Requires 11.0+
Issue 5: Xcode 16 and Swift 6 Compatibility
The Problem
Build errors related to Swift version or Xcode compatibility.
Solution: Update Development Environment
Update Xcode
- Update to Xcode 16+ (required for iOS 19)
- Open Xcode → Preferences → Locations
- Ensure Command Line Tools point to Xcode 16
Update Flutter
flutter upgrade
flutter doctor -v
Ensure Flutter channel is stable:
flutter channel stable
flutter upgrade
Verify Swift Version
In Xcode, check Build Settings → Swift Language Version should be Swift 5 or 6.
Issue 6: Entitlements Missing
The Problem
App crashes when accessing certain features or fails App Store validation.
Solution: Update Entitlements
Open ios/Runner/Runner.entitlements and ensure these are present:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string> <!-- or 'production' -->
<!-- Add other entitlements as needed -->
</dict>
</plist>
Complete Migration Checklist
Follow this checklist to ensure your app is iOS 19 ready:
Pre-Migration
- Backup your project
- Update Flutter to 3.24+
- Update Xcode to 16+
- Update CocoaPods:
sudo gem install cocoapods
Privacy & Permissions
- Create
PrivacyInfo.xcprivacyfile - Add required privacy API reasons
- Update
Info.plistwith usage descriptions - Remove unused permission requests
- Declare data collection in privacy manifest
Dependencies
- Update all Flutter plugins:
flutter pub upgrade - Update CocoaPods:
pod install - Check plugin compatibility with iOS 19
- Update Firebase SDK if used
Build Configuration
- Update minimum iOS version in
Podfile - Update
Runner.entitlements - Verify Swift version compatibility
- Clean build folder:
flutter clean
Testing
- Test on iOS 19 simulator
- Test on physical iOS 19 device
- Test app lifecycle (background/foreground)
- Test all permission requests
- Test deep linking
- Test push notifications
App Store
- Verify privacy manifest in App Store Connect
- Update privacy policy if data collection changed
- Test TestFlight build on iOS 19
Step-by-Step Migration Process
Day 1: Preparation
# 1. Update Flutter
flutter upgrade
flutter channel stable
# 2. Update dependencies
flutter pub upgrade
# 3. Update CocoaPods
cd ios
pod repo update
pod install
cd ..
Day 2: Privacy Manifest
- Create
PrivacyInfo.xcprivacy(use template above) - Add to Xcode project
- Declare all privacy-sensitive APIs
- Test build
Day 3: Testing
- Test on iOS 19 simulator
- Test on physical device
- Fix any runtime issues
- Update plugins if needed
Day 4: App Store Submission
- Create TestFlight build
- Test on iOS 19 devices
- Submit for review
Common Error Messages and Fixes
Error: "Privacy manifest file is missing"
Fix: Create PrivacyInfo.xcprivacy as described in Issue 1.
Error: "Required reason API usage description missing"
Fix: Add the required reason code to PrivacyInfo.xcprivacy under NSPrivacyAccessedAPITypes.
Error: "App uses unencrypted connections"
Fix: Add to Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
</dict>
Error: "Invalid bundle structure"
Fix: Ensure your app structure follows iOS 19 requirements. Run:
flutter clean
flutter build ios --release
Error: "Swift version mismatch"
Fix: Update Xcode and ensure Swift 5+ is selected in Build Settings.
Testing Your Migration
Test Checklist
- Launch Test: App launches without crashes
- Permission Test: All permission dialogs work
- Background Test: App handles background/foreground correctly
- Deep Link Test: Deep links work on iOS 19
- Push Notification Test: Notifications work correctly
- Performance Test: No performance regressions
Simulator Testing
# List available simulators
xcrun simctl list devices
# Boot iOS 19 simulator
xcrun simctl boot "iPhone 15 Pro"
# Run your app
flutter run
Device Testing
- Connect iOS 19 device
- Trust the device in Xcode
- Run:
flutter run --release
Best Practices for iOS 19
1. Minimal Privacy Manifest
Only declare APIs you actually use. Don't copy-paste entire templates.
2. Regular Updates
Keep Flutter and plugins updated:
# Weekly check
flutter upgrade
flutter pub upgrade
3. Test Early
Test on iOS 19 beta as soon as it's available, not after release.
4. Monitor App Store Connect
Check for privacy manifest warnings in App Store Connect before submission.
5. Document Changes
Keep a changelog of iOS 19-specific changes for your team.
Troubleshooting
Build Still Fails After Migration
-
Clean everything:
flutter clean cd ios rm -rf Pods Podfile.lock .symlinks pod deintegrate pod install cd .. -
Check Xcode version: Must be 16+
-
Check Flutter version:
flutter doctor -v -
Verify privacy manifest: Open in Xcode and check for errors
App Crashes on Launch
- Check device logs in Xcode: Window → Devices and Simulators → View Device Logs
- Verify all required keys in
Info.plist - Ensure privacy manifest is included in build
- Test with a minimal Flutter app to isolate the issue
Permission Dialogs Not Showing
- Check
Info.plisthas correct usage descriptions - Verify permissions are requested at the right time
- Test on a fresh install (permissions are cached)
Resources
- Apple Privacy Manifest Documentation
- Flutter iOS Deployment Guide
- iOS 19 Release Notes
- Flutter Plugin Compatibility
Conclusion
iOS 19 migration requires attention to privacy manifests, lifecycle changes, and dependency updates. The most critical change is the privacy manifest requirement - without it, your app will crash on launch.
Follow this guide systematically:
- Add privacy manifest
- Update Info.plist
- Update dependencies
- Test thoroughly
- Submit to App Store
With these changes, your Flutter app will work smoothly on iOS 19 and pass App Store review.
Next Steps
- Set up automated testing for iOS updates
- Monitor Flutter plugin updates for iOS 19 compatibility
- Review your app's privacy practices and update privacy policy
- Consider implementing iOS 19-specific features (like improved widgets)
Updated for iOS 19, Flutter 3.24+, and Xcode 16+