2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FlutterでCarPlayのサンプルを作ってみた

Posted at

はじめに

FlutterでCarPlayを作る機会があったので、サンプルを作ってみました。

更新履歴

2024.1.10 初回投稿

準備(ここはChatGPTに聞いてそのままコピペ)

  1. Apple Developer Programへの登録
    まず、Apple Developer Programに登録している必要があります。まだ登録していない場合は、Apple Developerの公式サイトから登録してください。

  2. CarPlay対応アプリのカテゴリ確認
    Appleが現在CarPlay対応アプリとして認めているカテゴリは以下の通りです:

    • オーディオ
    • ナビゲーション
    • 通信(VoIPなど)
    • EV充電管理
    • 駐車
    • クイックフード注文
    • 燃料補給
      注意: CarPlayアプリはこれらのカテゴリのいずれかに該当する必要があります。
  3. 適合性確認

    アプリがCarPlay対応要件に準拠していることを確認する必要があります。Appleは、CarPlayアプリのUI、ユーザーエクスペリエンス、機能がガイドラインに従っていることを求めています。

    Human Interface Guidelines (HIG) for CarPlayを確認してください。

  4. CarPlay App Entitlementの申請
    CarPlayアプリを開発するには、CarPlayの権限(Entitlement)をAppleにリクエストする必要があります。このプロセスでは、以下の情報を提供する必要があります:

    • アプリの詳細
    • 使用ケース
    • CarPlayとの統合計画
    • 申請は、Apple Developer Programのお問い合わせフォームを通じて行います。)
      • 以下の手順で進めます:
        Apple Developer Programのアカウントにログイン。
        「お問い合わせ」セクションに移動。
        「技術サポート」または「APIの利用リクエスト」を選択。
        CarPlay App Entitlementのリクエストを具体的に記載し、送信します。

ここでは、iOSシミュレータを使って実機は使わず「CarPlay App Entitlementの申請」の申請を行わない方法で試しています。

Flutterプロジェクト作成

  1. 適当なプロジェクト名で作成

    flutter create carplay_sample
    
  2. パッケージをインストール

    flutter pub add flutter_carplay
    
  3. flutter_carplay(https://pub.dev/packages/flutter_carplay/example)のサンプルコードをmain.dartにそのまま貼り付ける

  4. そのまま貼り付けると、「images/logo_flutter_1080px_clr.png」がないと怒られるので、適当にアイコンを作って、入れておきます。その際、pubspec.yamlのassetsの設定を忘れずに...
    プロジェクトの最上層に「assets」「images」ディレクトリを作成
    以下のcarplay.pngを追加

  assets:
    - assets/images/

carplay.png

XCodeの設定

AppDelegateの修正

  1. FlutterプロジェクトのiOS>「Open in XCode」からXCodeを開く

  2. Runner>Runner内のAppDelegateを開く

  3. 10,11行目の以下のコードをコメントアウトもしくは削除して、「return true」のみにして保存

import Flutter
import UIKit

@main
@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
  }
}

SceneDelegate.swift作成

  1. 同じ階層のRunner内に、「SceneDelegate.swift」を作成して、以下のコードをそのままコピペ
@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()
    }
}

info.plistに追加

  1. 同じRunnerの階層内のinfo.plistに以下を付け加える
<?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>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>CADisableMinimumFrameDurationOnPhone</key>
	<true/>
	<key>UIApplicationSupportsIndirectInputEvents</key>
	<true/>
  //ここから  
    <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>
    <key>NSSupportsCarPlay</key>
    <true/>
    //ここまで
</dict>
</plist>

Runnerファイルの追加

  1. プロジェクトの一番上の「Runner」をクリック
  2. TARGETS>Runnerをクリック(最初から選択されている場合もあります)
  3. 「Signing&Capabilities」タブをクリックします。
  4. 「Signing&Capabilities」タブの下の「All」横の「+Capability」をクリックするとポップアップが表示されます。
  5. 一覧の中の「Keychain Sharing」をダブルクリックします。すると、Runner内にさらにRunnerファイルが作成されます。
    スクリーンショット 2025-01-10 18.14.33.png
  6. この「Runner」ファイルの「Entitlements File」の下にKeyが「Keychain Access Groups」となっているので、ここを「com.apple.developer.carplay-maps」に変更。typeも「Boolean」、Valueを「YES」に変更する
    スクリーンショット 2025-01-10 18.22.34.png

シミュレータで実行

  1. 「flutter run」で実行

  2. iOSシミュレータにアプリの画面が表示されます。
    Simulator Screenshot - iPhone 16 Pro - 2025-01-10 at 18.08.33.png

  3. Simulatorメニューの「I/O」>「External Display」>「CarPlay...」を選択する
    スクリーンショット 2025-01-10 18.10.46.png

  4. Setup画面が表示されるので、一旦このままで「run」ボタンを押す
    スクリーンショット 2025-01-10 18.11.58.png

  5. CarPlay画面が表示されるので、該当のアプリをクリックすればアプリが表示されます。

スクリーンショット 2025-01-10 18.13.01.png

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?