What if you could create CarPlay with React Native. Well, now you can.
One of the most useful resources for undertanding the requirements, constraints and capabilities of CarPlay apps is the official App Programming Guidelines from Apple. It's a 50-page document that clearly lays out steps required and you are strongly encouraged to read it if you are new to CarPlay.
You can develop CarPlay capabilities with this project without waiting for Apple to send you back an entitlement, through the simulator.
If you want to build and run your app on an iPhone or share it with others through the App Store Connect or TestFlight, you will need to request a CarPlay entitlement from Apple first. The process will take anywhere from a few days to weeks - your mileage will vary. This depends on the type of Entitlement you are requesting. If you are part of the MFi program, this may help speed things up too. You then need to add the entitlement to your privisioning profile or signing certificate that you use for signing your app in XCode.
You can go to this Apple CarPlay entitlement request page to request a CarPlay Entitlement. You need to be logged in with an Apple Developer account.
To start a CarPlay simulator in XCode, within the Simulator window, go to the menu option IO, click on External Displays, then select CarPlay.
Whether you are running through a simulator or building the app for distribution, you need to ensure that the correct entitlement key is added in your Entitlements.plist
file. If you don't have an Entitlements.plist file, create one in your iOS/
directory.
- Install the library
yarn add react-native-carplay --save
- Link using normal or cocoapods method
react-native link react-native-carplay
# in ios/Podfile:
pod 'react-native-carplay', path: '../node_modules/react-native-carplay'
- Edit your AppDelegate
// AppDelegate.h
// [step 1] add this line to the top
#import <CarPlay/CarPlay.h>
// [step 2] add the "CPApplicationDelegate" to the end, before ">":
@interface AppDelegate : UIResponder <UIApplicationDelegate, CPApplicationDelegate>
// AppDelegate.m
// [step 1] add this line to the top
#import <RNCarPlay.h>
// ...
// [step 2] add the following two methods before @end
- (void)application:(UIApplication *)application didConnectCarInterfaceController:(CPInterfaceController *)interfaceController toWindow:(CPWindow *)window {
[RNCarPlay connectWithInterfaceController:interfaceController window:window];
}
- (void)application:(nonnull UIApplication *)application didDisconnectCarInterfaceController:(nonnull CPInterfaceController *)interfaceController fromWindow:(nonnull CPWindow *)window {
[RNCarPlay disconnect];
}
@end
import { CarPlay, GridTemplate } from 'react-native-carplay';
const template = new GridTemplate();
CarPlay.setRootTemplate(template);
Sets the root template of CarPlay.
This must be called before running any other CarPlay commands. Can be called multiple times.
CarPlay.setRootTemplate(template, /* animated */ false);
Pushes a new template to the navigation stack.
Note you cannot push the same template twice.
(where template
is one of GridTemplate, ListTemplate or SearchTemplate)
CarPlay.pushTemplate(template, /* animated */ true);
Pop currently presented template from the stack.
CarPlay.popTemplate(/* animated */ false);
Pop currently presented template from the stack to a specific template. The template must be in the stack.
CarPlay.popToTemplate(template, /* animated */ false);
Pop the stack to root template.
CarPlay.popToRoot(/* animated */ false);
import { CarPlay, MapTemplate } from 'react-native-carplay';
function CarPlayView() {
return (
<View>
<Image style={{ width: 100, height: 100 }} />
<Text>My thing</Text>
<GoogleMap />
</View>
);
}
const map = new MapTemplate({
guidanceBackgroundColor: '#aeafaf',
component: CarPlayView,
mapButtons: [{
id: 'test',
image: require('assets/images/test.png'),
focusedImage: require('assets/images/test-focused.png'),
}]
});
CarPlay.setRootTemplate(map);
import { CarPlay, ListTemplate } from 'react-native-carplay';
// Register a new template in memory
const artists = new ListTemplate({
title: 'List of artists',
leadingNavigationBarButtons: [{
id: 'play',
type: 'text',
title: 'Play',
}],
sections: [{
items: [{
text: 'AC/DC'
detailText: 'Rock',
image: require('./artists/ac-dc.png'),
showsDisclosureIndicator: true,
}],
}],
onItemSelect(item) {
const artist = new ListTemplate({
title: 'AC/DC',
sections: [...],
});
CarPlay.pushTemplate(artist, true);
}
});
CarPlay.setRootTemplate(songs, false);
- CPListTemplate
- CPGridTemplate
- CPSearchTemplate
- CPMapTemplate
- CPVoiceControlTemplate
- CPAlertTemplate
- CPActionSheetTemplate
- CPNavigationSession
- CPTrip
- CPManeuver
- CPAlertAction
- CPSessionConfiguration
- setRootTemplate
- pushTemplate
- popTemplate
- popToTemplate
- presentTemplate
- dismissTemplate
- updateListTemplateSections
- reactToUpdatedSearchText
- reactToSelectedResult
- topTemplate
- rootTemplate
- didConnect
- didDisconnect
- didSelectListItem
- selectedResult
- gridButtonPressed
- updatedSearchText
- searchButtonPressed
- barButtonPressed