carplay+expo

carplay+expo

gaoyanchen Lv3

1、CarPlay app entitlements

In Xcode, create an Entitlements.plist file in your project, if you don’t have one already. Add your CarPlay app entitlement keys as a boolean key. The following example is for a CarPlay audio app.

1
2
<key>com.apple.developer.carplay-audio</key> 
<true/>

com.apple.developer.carplay-audio In Xcode, under Signing & Capabilities turn off Automatically manage signing, and under Build Settings ensure that Code Signing Entitlements is set to the path of your Entitlements.plist file.

2、导入react-native-carplay包

yarn add react-native-carplay

3、在ios项目空间编辑CarPlay with React Native

Welcome to CarPlay Development!

Begin your journey with the App Programming Guidelines for CarPlay , a comprehensive 50-page manual by Apple detailing the essentials for CarPlay apps.

For additional details while developing or contributing, refer to the CarPlay Documentation .

🚀 Quickstart: Utilize the simulator to test CarPlay capabilities without waiting for Apple’s entitlement approval.

🔑 Entitlements: To deploy on a device or distribute via App Store Connect or TestFlight, obtain a CarPlay entitlement here . The approval duration varies, and participation in the MFi program may expedite the process. Incorporate the entitlement into your app’s provisioning profile in Xcode.

🖥 Simulator: In Xcode, navigate to the Simulator window, choose IO > External Displays > CarPlay to launch the CarPlay simulator.

Important:

Ensure your Entitlements.plist within the iOS/ directory contains the correct entitlement key, whether for simulation or actual deployment.

Installing

You need to convert your project to using Scenes , as this is the standard when managing multiple windows in iOS 13+. This is a requirement for CarPlay apps.

1. Add your PhoneScene

This is where your app will run on the phone.

PhoneSceneDelegate.h

1
2
3
4
5
6
7
#import <UIKit/UIKit.h>

@interface PhoneSceneDelegate : UIResponder <UIWindowSceneDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

PhoneSceneDelegate.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import "PhoneSceneDelegate.h"

@implementation PhoneSceneDelegate
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
AppDelegate *appDelegate = (AppDelegate *)UIApplication.sharedApplication.delegate;
UIWindowScene *windowScene = (UIWindowScene *)scene;
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = appDelegate.rootView;
UIWindow *window = [[UIWindow alloc] initWithWindowScene:windowScene];
window.rootViewController = rootViewController;
self.window = window;
[window makeKeyAndVisible];
}

@end

2. Add your CarScene

This is where your app will run on CarPlay.

CarSceneDelegate.h

1
2
3
4
5
#import <Foundation/Foundation.h>
#import <CarPlay/CarPlay.h>

@interface CarSceneDelegate : UIResponder <CPTemplateApplicationSceneDelegate>
@end

CarSceneDelegate.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "CarSceneDelegate.h"
#import "CarSceneDelegate.h"
#import "RNCarPlay.h"

@implementation CarSceneDelegate

- (void)templateApplicationScene:(CPTemplateApplicationScene *)templateApplicationScene
didConnectInterfaceController:(CPInterfaceController *)interfaceController {
// Dispatch connect to RNCarPlay
[RNCarPlay connectWithInterfaceController:interfaceController window:templateApplicationScene.carWindow];
}

- (void)templateApplicationScene:(CPTemplateApplicationScene *)templateApplicationScene
didDisconnectInterfaceController:(CPInterfaceController *)interfaceController {
// Dispatch disconnect to RNCarPlay
in [RNCarPlay disconnect];
}

@end

3. Add Scene Manifest to Info.plist

ios/App/Info.plist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<key>UIApplicationSceneManifest</key>

<dict>
<key>UIApplicationSupportsMultipleScenes</key>

<true/>
<key>UISceneConfigurations</key>

<dict>
<key>CPTemplateApplicationSceneSessionRoleApplication</key>

<array>
<dict>
<key>UISceneClassName</key>

<string>CPTemplateApplicationScene</string>

<key>UISceneConfigurationName</key>

<string>CarPlay</string>

<key>UISceneDelegateClassName</key>

<string>$(PRODUCT_MODULE_NAME).CarSceneDelegate</string>

</dict>

</array>

<key>UIWindowSceneSessionRoleApplication</key>

<array>
<dict>
<key>UISceneClassName</key>

<string>UIWindowScene</string>

<key>UISceneConfigurationName</key>

<string>Phone</string>

<key>UISceneDelegateClassName</key>

<string>$(PRODUCT_MODULE_NAME).PhoneSceneDelegate</string>

</dict>

</array>

</dict>

</dict>

Entitlement matrix

List Grid T B Alert A S 🎤 ▶️ Map 🔎 POI Info 📇
com.apple.developer.carplay-audio
com.apple.developer.carplay-communication
com.apple.developer.carplay-charging
com.apple.developer.carplay-maps
com.apple.developer.carplay-parking
com.apple.developer.carplay-quick-ordering

Connect / Disconnect

Efficiently manage CarPlay connections by utilizing the connected status and on-connect/disconnect events. Ensure to check the connection state before invoking CarPlay APIs, ideally within a useEffect hook or by using a non-React function.

1
2
3
4
5
6
7
8
9
10
11
12
// react
useEffect(() => {
CarPlay.registerOnConnect(onConnect);
return () => {
CarPlay.unregisterOnConnect(onConnect);
};
});

// imperative
CarPlay.registerOnConnect(() => {
CarPlay.setRootTemplate(/* template */);
});

Templates

Templates are used to render contents on the CarPlay screen from your app. Details of the templates supported by apple can be found in the developer guide

MapTemplate

A template that displays a navigation overlay that your app draws on the map.

Visual Previews


Example Usage

1
2
3
4
5
6
new MapTemplate({
component: /* react native view */ MapView,
guidanceBackgroundColor: '#eeff00',
onAlertActionPressed() {},
onStartedTrip() {},
});

See more configuration options in the TypeScript Docs

  • CPMapTemplate : Learn more about the capabilities and limitations of the MapTemplate in CarPlay.
  • CPMapTemplateDelegate : Understand the delegate callbacks that can be used to manage user interactions with the MapTemplate.

ListTemplate

A template that displays and manages a list of items.

Visual Previews

Example Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
new ListTemplate({
sections: [
{
header: 'Header A',
items: [
{
text: 'Item 1',
},
],
},
],
title: 'List Template',
async onItemSelect() {},
});

See more configuration options in the TypeScript Docs

  • CPListTemplate : Learn more about the capabilities and limitations of the ListTemplate in CarPlay.
  • CPListTemplateDelegate : Understand the delegate callbacks that can be used to manage user interactions with the ListTemplate.

InformationTemplate

A template that provides information for a point of interest, food order, parking location, or charging location.

Visual Previews

Example Usage

1
2
3
4
5
6
new InformationTemplate({
title: 'Information',
items: [{ title: 'foo', detail: 'bar' }],
actions: [{ id: 'demo', title: 'Demo' }],
onActionButtonPressed() {},
});

See more configuration options in the TypeScript Docs

GridTemplate

A template that displays and manages a grid of items.

Visual Previews

Example Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
new GridTemplate({
trailingNavigationBarButtons: [
{
id: 'a',
type: 'image',
image: require('star.jpg'),
},
],
buttons: [
{
id: '0',
titleVariants: ['Item 0'],
image: require('click.jpg'),
},
],
title: 'Grid Template',
onButtonPressed() {},
onBarButtonPressed() {},
});

See more configuration options in the TypeScript Docs

  • CPGridTemplate : Discover the capabilities and constraints of the CPGridTemplate in CarPlay.
  • CPGridTemplateDelegate : Delve into the delegate callbacks available for handling user interactions within the CPGridTemplate.

SearchTemplate

A template that provides the ability to search for a destination and see a list of search results.

Visual Previews

Example Usage

1
2
3
4
5
new SearchTemplate({
async onSearch(query) {},
async onItemSelect({ index }) {},
onSearchButtonPressed() {},
});

See more configuration options in the TypeScript Docs

  • CPSearchTemplate : Explore the features and limitations of the CPSearchTemplate in CarPlay.
  • CPSearchTemplateDelegate : Learn about the delegate callbacks for managing interactions within the CPSearchTemplate.

VoiceTemplate

A template that displays a voice control indicator during audio input.

This template is presented via CarPlay.presentTemplate. In order to implement voice recognition, take a look at the @react-native-voice/voice package.

Visual Previews

Example Usage

1
2
3
4
5
6
7
8
9
10
new VoiceControlTemplate({
voiceControlStates: [
{
identifier: 'a',
image: require('cat.jpg'),
repeats: true,
titleVariants: ['Searching...'],
},
],
});

See more configuration options in the TypeScript Docs

AlertTemplate

A template that displays a modal alert and should be presented via CarPlay.presentTemplate.

Visual Previews

Example Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
new AlertTemplate({
titleVariants: ['Hello world'],
actions: [
{
id: 'ok',
title: 'Ok',
},
{
id: 'ok',
title: 'Cancel',
},
{
id: 'remove',
title: 'Remove',
style: 'destructive',
},
],
onActionButtonPressed() {},
});
  • CPAlertTemplate : Explore the functionality of CPAlertTemplate for displaying alerts in CarPlay.
  • CPAlertTemplateDelegate : Learn about delegate methods for managing user interactions with CarPlay alerts.

ActionSheetTemplate

A template that displays a modal action sheet and should be presented via CarPlay.presentTemplate.

Visual Previews

Example Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new ActionSheetTemplate({
title: 'Example',
message: 'This is an message for you',
actions: [
{
id: 'ok',
title: 'Ok',
},
{
id: 'remove',
title: 'Remove',
style: 'destructive',
},
],
onActionButtonPressed() {},
});

TabBarTemplate

A container template that displays and manages other templates, presenting them as tabs.

Note: This template must be set as the root template and cannot be pushed on top of other templates.

Visual Previews

Example Usage

1
2
3
4
5
6
7
8
9
// Define tab templates
const tpl1 = new ListTemplate(/* ... */);
const tpl2 = new ListTemplate(/* ... */);

// Setup the tab container template
new TabBarTemplate({
templates: [tpl1, tpl2],
onTemplateSelect() {},
});
  • CPTabBarTemplate : Investigate the features and usage of CPTabBarTemplate to create a tab bar interface in CarPlay.
  • CPTabBarTemplateDelegate : Explore the delegate methods for responding to tab selection events in the CPTabBarTemplate.
    ``

Troubleshooting

Image Size and Resolution

Quirks observed where PNG image resolutions should be specfied with scale factor of 3.0 (i.e. append with @3x) with ListTemplate image sizing suggested around 80 x 80 px per Issue #6

  • Title: carplay+expo
  • Author: gaoyanchen
  • Created at : 2024-10-19 19:07:05
  • Updated at : 2024-10-20 17:22:00
  • Link: https://gyc.660624.xyz/2024/10/19/carplay+expo/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments