-
-
Notifications
You must be signed in to change notification settings - Fork 103
iOS Setup
Oguzhan Atalay edited this page Jan 24, 2026
·
1 revision
- Xcode 14+
- iOS 14.0+ deployment target
- CarPlay entitlement from Apple (required for App Store)
β οΈ You need to request a CarPlay entitlement from Apple before submitting to the App Store. For development and testing, you can use the CarPlay Simulator.
Add the CarPlay scene configuration to your ios/Runner/Info.plist:
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<!-- CarPlay Scene -->
<key>CPTemplateApplicationSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>CarPlay Configuration</string>
<key>UISceneDelegateClassName</key>
<string>flutter_carplay.FlutterCarPlaySceneDelegate</string>
</dict>
</array>
<!-- Main App Scene -->
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>Create ios/Runner/SceneDelegate.swift:
import UIKit
import Flutter
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
window = UIWindow(windowScene: windowScene)
let controller = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
window?.rootViewController = controller
window?.makeKeyAndVisible()
}
}Update your ios/Runner/AppDelegate.swift to use a shared Flutter engine:
import UIKit
import Flutter
// Global Flutter engine for sharing between app and CarPlay
let flutterEngine = FlutterEngine(name: "SharedEngine", project: nil, allowHeadlessExecution: true)
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Start the Flutter engine
flutterEngine.run()
GeneratedPluginRegistrant.register(with: flutterEngine)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}Create or update ios/Runner/Runner.entitlements:
<?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>com.apple.developer.carplay-audio</key>
<true/>
</dict>
</plist>Available entitlements (request from Apple):
-
com.apple.developer.carplay-audioβ Audio apps -
com.apple.developer.carplay-messagingβ Messaging apps -
com.apple.developer.carplay-navigationβ Navigation apps -
com.apple.developer.carplay-parkingβ Parking apps -
com.apple.developer.carplay-quick-orderingβ Quick food ordering -
com.apple.developer.carplay-chargingβ EV charging apps
- Open Xcode
- Run your app on a simulator
- Go to I/O β External Displays β CarPlay
- The CarPlay window will appear
Or use the standalone CarPlay Simulator:
- Open Xcode
- Go to Xcode β Open Developer Tool β CarPlay Simulator
The package supports launching CarPlay even when the app isn't running on the phone. This is handled automatically when you configure the shared Flutter engine as shown above.
To force update the template after connection:
_flutterCarplay.forceUpdateRootTemplate();See Troubleshooting for common iOS setup issues.