Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions CARPLAY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ This guide explains how to enable and integrate Apple CarPlay with the React Nat

Refer to the [Apple CarPlay Developer Guide](https://developer.apple.com/carplay/) to understand how CarPlay works and to complete the initial setup. Key steps include:

- Adding the CarPlay entitlement to your Xcode project.
- Creating a separate scene for the CarPlay map and enabling support for multiple scenes.
- Adding the CarPlay entitlement to your Xcode project
- Creating a separate scene for the CarPlay map and enabling support for multiple scenes

For a complete implementation example, refer to [AppDelegateCarPlay.m](example/ios/SampleApp/AppDelegateCarPlay.m), [PhoneSceneDelegate.m](example/ios/SampleApp/PhoneSceneDelegate.m) and [CarSceneDelegate.m](example/ios/SampleApp/CarSceneDelegate.m). Pay special attention to how the React Native window is initialized in `PhoneSceneDelegate` when using multiple scenes.

### SceneDelegate for CarPlay

Expand Down Expand Up @@ -83,4 +85,10 @@ For a more detailed example, refer to the `NavigationScreen.tsx` in the React Na

## Example Project

For a fully functional CarPlay implementation, check out the [SampleApp](./example/ios/) Xcode project, which includes the `SampleAppCarPlay` build target. The sample already contains test entitlement so you don't need to request one from Apple to run it.
For a fully functional CarPlay implementation, check out the [SampleApp](./example/ios/) Xcode project, which includes the `SampleAppCarPlay` build target. The sample already contains test entitlement so you don't need to request one from Apple to run it.

Start the CarPlay example from the command line:

```bash
yarn example ios:carplay
```
10 changes: 9 additions & 1 deletion example/ios/SampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,10 @@
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "SampleApp/Info-CarPlay.plist";
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"CARPLAY=1",
);
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -670,8 +674,12 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = SampleApp/SampleApp.entitlements;
CURRENT_PROJECT_VERSION = 1;
INFOPLIST_FILE = SampleApp/Info.plist;
INFOPLIST_FILE = "SampleApp/Info-CarPlay.plist";
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"CARPLAY=1",
);
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
3 changes: 0 additions & 3 deletions example/ios/SampleApp/AppDelegateCarPlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,4 @@
#import <UIKit/UIKit.h>

@interface AppDelegateCarPlay : RCTAppDelegate
@property(nonatomic, strong) UIWindow *window;
@property(nonatomic, strong) RCTBridge *bridge;
@property(nonatomic, strong) RCTRootView *rootView;
@end
17 changes: 17 additions & 0 deletions example/ios/SampleApp/AppDelegateCarPlay.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ - (BOOL)application:(UIApplication *)application
self.moduleName = @"SampleApp";
self.dependencyProvider = [RCTAppDependencyProvider new];

// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};

// Note: Ensure that you have copied the Keys.plist.sample to Keys.plist
// and have added the correct API_KEY value to the file.
//
Expand All @@ -39,6 +43,11 @@ - (BOOL)application:(UIApplication *)application
NSString *api_key = [keysDictionary objectForKey:@"API_KEY"];

[GMSServices provideAPIKey:api_key];

// Set automaticallyLoadReactNativeWindow to NO to prevent RCTAppDelegate from creating the
// window. It will be created in PhoneSceneDelegate for the main (phone) screen.
self.automaticallyLoadReactNativeWindow = NO;

return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

Expand All @@ -65,6 +74,14 @@ - (void)application:(UIApplication *)application
didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
}

- (BOOL)fabricEnabled {
return NO;
}

- (BOOL)bridgelessEnabled {
return NO;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
return [self bundleURL];
}
Expand Down
13 changes: 9 additions & 4 deletions example/ios/SampleApp/PhoneSceneDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@
* limitations under the License.
*/
#import "PhoneSceneDelegate.h"
#import <RCTAppDelegate.h>
#import <React/RCTRootView.h>
#import <UIKit/UIKit.h>
#import "AppDelegateCarPlay.h"

@implementation PhoneSceneDelegate

- (void)scene:(UIScene *)scene
willConnectToSession:(UISceneSession *)session
options:(UISceneConnectionOptions *)connectionOptions {
AppDelegateCarPlay *appDelegate =
(AppDelegateCarPlay *)[UIApplication sharedApplication].delegate;
RCTAppDelegate *appDelegate = (RCTAppDelegate *)[UIApplication sharedApplication].delegate;
if (!appDelegate) {
return;
}
Expand All @@ -34,12 +33,18 @@ - (void)scene:(UIScene *)scene
return;
}

UIView *rootView = [appDelegate.rootViewFactory viewWithModuleName:appDelegate.moduleName
initialProperties:appDelegate.initialProps
launchOptions:nil];
rootView.backgroundColor = [UIColor whiteColor];

UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = appDelegate.rootView;
rootViewController.view = rootView;

UIWindow *window = [[UIWindow alloc] initWithWindowScene:windowScene];
window.rootViewController = rootViewController;
self.window = window;

[appDelegate setWindow:window];
[window makeKeyAndVisible];
}
Expand Down
1 change: 1 addition & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"android": "react-native run-android",
"android-release": "react-native run-android --mode release",
"ios": "react-native run-ios",
"ios:carplay": "react-native run-ios --scheme SampleAppCarPlay",
"ios-release": "react-native run-ios --mode Release",
"lint": "eslint .",
"test": "jest",
Expand Down
Loading