Flutter CarPlay

CarPlay with Flutter
🚗

License: MIT Pub Version (including pre-releases)

Flutter Apps now on Apple CarPlay! flutter_carplay aims to make it safe to use iPhone apps made with Flutter in the car by integrating with CarPlay. CarPlay takes the things you want to do while driving and puts them on the car’s built-in display.

Apple announced some great features in iOS 14, one of which is users download CarPlay apps from the App Store and use them on iPhone like any other app. When an iPhone with a CarPlay app is connected to a CarPlay vehicle, the app icon appears on the CarPlay home screen. CarPlay apps are not separate apps—you add CarPlay support to an existing app.

Your app uses the CarPlay framework to present UI elements to the user. iOS manages the display of UI elements and handles the interface with the car. Your app does not need to manage the layout of UI elements for different screen resolutions, or support different input hardware such as touchscreens, knobs, or touch pads.

It supports only iOS 14.0+. For general design guidance, see Human Interface Guidelines for CarPlay Apps.

Overview

Flutter CarPlay Introduction

Before you begin CarPlay integration, you must carefully read this section.

The official App Programming Guidelines from Apple is the most valuable resource for understanding the needs, limits, and capabilities of CarPlay Apps. This documentation is a 49-page which clearly spells out the some actions required, and you are strongly advised to read it. If you are interested in a CarPlay System, learn more about the MFi Program.

Templates

CarPlay apps are built from a fixed set of user interface templates that iOS renders on the CarPlay screen. Each CarPlay app category can only use a restricted number of templates. Your app entitlement determines your access to templates. Flutter CarPlay

Supports

flutter_carplay currently supports:

  • Action Sheet Template
  • Alert Template
  • Grid Template
  • List Template
  • Tab Bar Template

By evaluating this information, you can request for the relevant entitlement from Apple.

Road Map

Since I don’t have some required entitlements, other templates will be supported in the future releases by flutter_carplay.

  • Map
  • Search
  • Voice Control & “Hey Siri” for hands-free voice activation
  • Information
  • Contact
  • Point of Interest
  • Now Playing

Contributing

  • Pull Requests are always welcome.
  • Pull Request Reviews are even more welcome! I need help in testing.
  • If you are interested in contributing more actively, please contact me at [email protected] Thanks!
  • If you want to help in coding, join Slack Channel, so we can chat over there.

Requesting the CarPlay Entitlements

All CarPlay apps require a CarPlay app entitlement.

If you want to build, run and publish your app on Apple with CarPlay compatibility or test or share the app with others through the TestfFlight or AdHoc, you must first request Apple to approve your Developer account for CarPlay access. The process can take from a few days to weeks or even months. It depends on the type of Entitlement you are requesting.

To request a CarPlay app entitlement from Apple, go to https://developer.apple.com/contact/carplay and provide information about your app, including the CarPlay App Category. You must also agree to the CarPlay Entitlement Addendum.

With this project, you can start developing and testing through Apple’s CarPlay Simulator without waiting for CarPlay Entitlements. Apple will review your request. If your app meets the criteria for a CarPlay app, Apple will assign a CarPlay app entitlement to your Apple Developer Account and will notify you.

Whether you are running the app through a simulator or developing it for distribution, you must ensure that the relevant entitlement key is added to the Entitlements.plist file. You must create an Entitlements.plist file if you do not already have one.

After you receive the CarPlay Entitlement

After you receive the entitlement, you need to configure your Xcode project to use it, which involves several steps. You create and import a provisioning profile, and add an Entitlements.plist file. Your project’s code signing settings also require minor changes.

For more detailed instructions about how to create and import the CarPlay Provisioning Profile and add an Entitlements File to Xcode Project, go to Configure your CarPlay-enabled app with the entitlements it requires.

Disclaimer Before The Installation

You are about to make some minor changes to your Xcode project after installing this package. This is due to the fact that It requires bitcode compilation which is missing in Flutter. You will procedure that will relocate (we won’t remove or edit) some Flutter and its package engines. If you’re planning to add this package to a critical project for you, you should proceed cautiously.

Please check THE EXAMPLE PROJECT before you begin to the installation.

THE INSTALLATION STEPS MAY BE DIFFICULT OR MAY NOT WORK PROPERLY WITH A FEW PACKAGES IN YOUR CURRENT PROJECT THAT COMMUNICATE WITH THE FLUTTER ENGINE. IF YOU ARE NOT COMPLETELY SURE WHAT YOU ARE DOING, PLEASE CREATE AN ISSUE, SO THAT I CAN HELP YOU TO SOLVE YOUR PROBLEM OR EXPLAIN WHAT YOU NEED TO.

WHILE THE INSTALLATION PROGRESS, IF YOU TRY TO CHANGE ANYTHING (E.G. ANYTHING WORKS WITH FLUTTER ENGINE, ANYTHING IN GENERATED PLUGIN REGISTRANT SPECIFICALLY ITS LOCATION, ANY FILE NAME, ANY CLASS NAME, OR ANY OTHER FUNCTION THAT WORKS ON APPDELEGATE CLASS, TEMPLATE OR WINDOW APPLICATION DELEGATE SCENE NAMES USED IN INFO.PLIST, INCLUDED STORYBOARD NAMES, BUT NOT LIMITED TO THESE), YOU ARE MOST LIKELY TO ENCOUNTER IRREVERSIBLE ERRORS AND IT MAY DAMAGE TO YOUR PROJECT. I STRONGLY RECOMMEND THAT YOU SHOULD COPY YOUR EXISTING PROJECT BEFORE THE INSTALLATION.

Get Started

Requirement Actions after Installating the Package

  1. The iOS platform version must be set to 14.0. To make it global, navigate to ios/Podfile and copy the first two lines:

# Uncomment this line to define a global platform for your project
+ platform :ios, '14.0'
- # platform :ios, '9.0'

After changing the platform version, execute the following command in your terminal to update your pod files:

// For Apple Silicon M1 chips:
$ cd ios && arch -x86_64 pod install --repo-update

// For Intel chips:
$ cd ios && pod install --repo-update
  1. Open ios/Runner.xcworkspace in Xcode. In your project navigator, open AppDelegate.swift.

    Flutter CarPlay

    Delete the specified codes below from the application function in AppDelegate.swift, and change it with the code below:

Bool {
– GeneratedPluginRegistrant.register(with: self)
– return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ return true
}
}
“>

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application( _ application: UIApplication,
                        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
-   GeneratedPluginRegistrant.register(with: self)
-   return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+   return true
}
}
  1. Create a swift file named SceneDelegate.swift in the Runner folder (not in the xcode main project file) and add the code below:

    @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 flutterEngine = FlutterEngine(name: "SceneDelegateEngine")
            flutterEngine.run()
            GeneratedPluginRegistrant.register(with: flutterEngine)
            let controller = FlutterViewController.init(engine: flutterEngine, nibName: nil, bundle: nil)
            window?.rootViewController = controller
            window?.makeKeyAndVisible()
        }
    }

    Flutter CarPlay

  2. One more step, open the Info.plist file whether in your favorite code editor or in the Xcode. I’m going to share the base code, so if you open in the Xcode, you can fill with the raw keys with the values.

    <div class="highlight highlight-text-xml position-relative" data-snippet-clipboard-copy-content="UIApplicationSceneManifest

    UIApplicationSupportsMultipleScenes

    UISceneConfigurations

    CPTemplateApplicationSceneSessionRoleApplication

    UISceneConfigurationName
    CarPlay Configuration
    UISceneDelegateClassName
    flutter_carplay.FlutterCarPlaySceneDelegate

    UIWindowSceneSessionRoleApplication

    UISceneConfigurationName
    Default Configuration
    UISceneDelegateClassName
    $(PRODUCT_MODULE_NAME).SceneDelegate
    UISceneStoryboardFile
    Main

    “>

    <key>UIApplicationSceneManifest</key>
    <dict>
      <key>UIApplicationSupportsMultipleScenes</key>
      <true />
      <key>UISceneConfigurations</key>
      <dict>
        <key>CPTemplateApplicationSceneSessionRoleApplication</key>
        <array>
          <dict>
            <key>UISceneConfigurationName</key>
            <string>CarPlay Configuration</string>
            <key>UISceneDelegateClassName</key>
            <string>flutter_carplay.FlutterCarPlaySceneDelegate</string>
          </dict>
        </array>
        <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>