Integration with CarPlay
- Last UpdatedApr 28, 2025
- 9 minute read
This tutorial shows how a MapView
can be rendered in your car's infotainment display with Apple's CarPlay. CarPlay allows to run an app on the actual hardware of a car. It can be simulated using a CarPlay simulator running on your development machine along your iOS simulator side-by-side.
The resulting app of this tutorial will show the MapView
instance on an in-car's head unit display with a zoom-in button and a zoom-out button. Another MapView
instance will be shown on the screen of the connected mobile device or simulator. The finished "HelloMapCarPlay" example app can be found on GitHub.
Note
Please note that while CarPlay may function as expected, its compatibility is not guaranteed, as this dependency is neither managed nor tested by the HERE SDK team.
How does it work?
The HERE SDK does not require any special set-up. It can be used together with CarPlay like any other API by following the CarPlay developer guides. As useful resources, use also the CarPlay API Reference and the CarPlay Programming Guide which are provided by Apple.
A general CarPlay integration may look like below:
- Configure CarPlay in
Info.plist
to handle CarPlay scenes and controllers. - In
CarPlaySceneDelegate
class, implementCPTemplateApplicationSceneDelegate
to manage CarPlay lifecycle events. - In
iPhoneSceneDelegate
class, implementUIWindowSceneDelegate
to manages the lifecycle events of a UI scene for the mobile application. - Create a
CarPlayViewController
to manage the map display on CarPlay andViewController
to manage the main view controller shown on the mobile device. - Initialize and configure a map in the CarPlay environment.
- Build and run your app as usual. In addition: Launch the CarPlay simulator from the simulator's main menu via I/O -> External Displays -> CarPlay. As a result, you can see the iPad or iPhone simulator in one window and the CarPlay simulator in a second window.
Your UIViewController
does not need to meet any specific requirements, except that it needs to follow Apple's design guidelines for in-car use.
In order to distribute your app or to deploy it onto a real device, your app needs to be reviewed by Apple. For this, you need to create a CarPlay app entitlement and agree to the CarPlay Entitlement Addendum.
Note
Until the entitlement is reviewed by Apple, a CarPlay app cannot be installed on a real device. Use an iOS device simulator instead. For deployment on a real device - even for testing purposes - a provisioning profile is needed that is enabled for the entitlement.
Integrate CarPlay
Let's take a closer look and create a new CarPlay app.
For this tutorial, we use the "HelloMap" app you can find on GitHub. By default, it shows a MapView
on the device. Now we want to extend this app to show a second instance of a MapView
on the in-car head unit display. For this, we need to integrate CarPlay.
The MapView
will behave like a normal MapView
: you can customize the look, add 3D objects onto it, or use any other HERE SDK engine along with it - however, it does not yet provide support for map gestures. Therefore, we will need to add buttons to interact with the map.
Note
The resulting app is only meant for testing purposes. For a production-ready app, make sure to follow the CarPlay design guidelines to see how to design an app that is relevant to the car environment.
Step 1 - Create a CarPlay entitlement
For this step, we need to create an Entitlements.plist
file. It specifies the capabilities of our app and is bound to our App ID. It can be created with Xcode. Make sure to follow the process as described here: for an appropriate entitlement, you need to contact Apple. For the below testing setup via simulator, this is not yet needed.
- In Xcode, create a new Property List file with the name
Entitlements.plist
. - Under Build Settings -> Code Signing Entitlements set the path to
HelloMapCarPlay/Entitlements.plist
.
Make sure that the file is located at this location: HelloMapCarPlay/HelloMapCarPlay/Entitlements.plist
- here, "HelloMapCarPlay" is our project name, inside which is another folder of the same name: add the file to this folder.
Edit the Entitlements.plist
file to look like this (adapt it later to meet the actual requirements of your app):
<?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-maps</key>
<true/>
</dict>
</plist>
The com.apple.developer.carplay-maps
key indicates an application scope that is needed for turn-by-turn navigation apps.
Step 2: Update the Info.plist
Add the following to your Info.plist
to enable the CarPlay scene configuration:
<!-- Scene configuration -->
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<!-- iPhone and iPad Scene Configuration -->
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).iPhoneSceneDelegate</string>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
</dict>
</array>
<!-- CarPlay Scene Configuration -->
<key>CPTemplateApplicationSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>CPTemplateApplicationScene</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).CarPlaySceneDelegate</string>
<key>UISceneConfigurationName</key>
<string>Default CarPlay Configuration</string>
</dict>
</array>
</dict>
</dict>
Step 3 - Create a CarPlay scene delegate
Adapt class CarPlaySceneDelegate
to conform CPTemplateApplicationSceneDelegate
protocol to manage the lifecycle events for the CarPlay scenes. CPTemplateApplicationSceneDelegate
is responsible for setting up the user interface in CarPlay and handling the transitions between different states of the application when used in a CarPlay environment. This class is specified in the Info.plist
under the CPTemplateApplicationSceneSessionRoleApplication
key and gets called when the app interacts with CarPlay.
CPTemplateApplicationSceneDelegate
requires us to implement two methods. The first one notifies when the mobile device is connected to the head unit's display - and thus, we receive a CarPlay window to show content. The second one notifies, when the device is disconnected. The CPTemplateApplicationSceneDelegate
allows us to receive a CPWindow
for which we set our CarPlayViewController
instance as rootViewController
. This will be the base view to manage the content in our CarPlay window.
On top, we create a CPMapTemplate
to define two buttons of type CPBarButton
. Apple's CPMapTemplate
also allows to receive and handle touch events. On a button click, we forward the event to our view controller to zoom the MapView
.
Similar to our view controller, we set the CPMapTemplate
instance as root template.
Below is the implementation of CarPlaySceneDelegate
:
Step 4 - Create a phone scene delegate
Implement UIWindowSceneDelegate
in iPhoneSceneDelegate
class to manage the lifecycle events of a UI scene for the application. UIWindowSceneDelegate
handles the setup and tear-down of the application's window and its content, responding to state transitions within the scene. The scene management includes creating and dismissing the window, transitioning the application between background and foreground, and handling configuration changes. It is specified in the Info.plist
under the UISceneConfigurations
key for standard iOS user interfaces. Below is the implementation of iPhoneSceneDelegate
:
Step 5 - Create a CarPlay view controller
We use a UIViewController
to show a MapView
. Our "HelloMap" example app already contains a ViewController
class which shows a MapView
. Now, we create a second one which is only instantiated to be used by CarPlay. However, code-wise, the class looks exactly the same:
With this new view controller, we create a second MapView
instance. And we add two zoom methods zoomIn()
and zoomOut()
to show how a basic interaction with the map can be implemented. In a next step, we create two buttons that will be shown in the head unit's display to call both methods.
You can add more buttons to interact with the map, e.g. for panning. However, make sure to follow Apple's design guidelines to not distract the driver's attention. Note that you can also pin images as an overlay to a MapScene
with the class MapImageOverlay
that allows to show bitmap graphics on top of the map view that do not move, scale or tilt together with the map.
Note
The HERE SDK does not yet support map gestures for CarPlay. Therefore, buttons need to be used to interact with the map. On top, not all cars support touch gestures such as pan movements. Read the CarPlay Programming Guide to learn more about gesture panning through knob and touch pad events.
Now, click Build to run a simulator. After the simulator has launched, open the simulator's app menu and choose I/O -> External Displays -> CarPlay. A second window opens and shows our app on the CarPlay home screen.
The resulting app looks like this:
Try the CarPlay example app
The finished "HelloMapCarPlay" example app can be found on GitHub.
Next steps
In this tutorial, we showed you how to add support for CarPlay to an existing app. Although we run two separate MapView
instances - one on the device and one on the head unit, you can handover functionality between the device and the head unit - since both MapView
instances run within the same app lifecycle. For example, a user can start route planning on a mobile device at home - then connect the device via USB in-car and start driving (if your app uses the Navigate Edition). The navigation progress can be shown on the car's head unit, while the device can show supportive information like maneuver details.
Make sure to not distract the driver with too much information: so, why not implementing voice controls on top to interact with the app? Some more ideas:
- Add a speed warner assistant, that shows the current valid speed limits on the head's unit display and warns acoustically when you exceed it.
- Show supporting road attribute information for the current road you are driving on.
- Implement an app that shows places information of POIs nearby, like fuel stations, restaurants or sightseeing spots.