Skip to content

Crash on CarPlay: requestGeometryUpdateWithPreferences not supported by CPTemplateApplicationScene #311

Description

@yagoal

Description:

When using react-native-orientation-locker in a CarPlay environment, the app crashes with the following error:

-[CPTemplateApplicationScene requestGeometryUpdateWithPreferences:errorHandler:]: unrecognized selector sent to instance

The crash happens in the method lockToOrientation:usingMask: because the following code assumes the first connected scene is always a UIWindowScene:

if (@available(iOS 16.0, *)) {
    UIWindowScene *windowScene = (UIWindowScene *)[UIApplication sharedApplication].connectedScenes.allObjects.firstObject;
        
    UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:mask];
    [windowScene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {
#if DEBUG
        if (error) {
            NSLog(@"Failed to update geometry with UIInterfaceOrientationMask: %@", error);
        }
#endif
    }];
}

On CarPlay, the active scene is of type CPTemplateApplicationScene, which does not implement requestGeometryUpdateWithPreferences:errorHandler:.

💡 Suggested Fix

if (@available(iOS 16.0, *)) {
    UIScene *scene = UIApplication.sharedApplication.connectedScenes.allObjects.firstObject;
    if ([scene isKindOfClass:[UIWindowScene class]]) {
        UIWindowScene *windowScene = (UIWindowScene *)scene;

        UIWindowSceneGeometryPreferencesIOS *geometryPreferences =
            [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:mask];

        [windowScene requestGeometryUpdateWithPreferences:geometryPreferences
                                             errorHandler:^(NSError * _Nonnull error) {
            #if DEBUG
            if (error) {
                NSLog(@"Failed to update geometry with UIInterfaceOrientationMask: %@", error);
            }
            #endif
        }];
    } else {
        NSLog(@"[Orientation] Scene is not UIWindowScene (possibly CarPlay CPTemplateApplicationScene)");
    }
} else {
    UIDevice* currentDevice = [UIDevice currentDevice];
    [currentDevice setValue:@(UIInterfaceOrientationUnknown) forKey:orientation];
    [currentDevice setValue:@(newOrientation) forKey:orientation];
}

ℹ️ Additional Notes

  • This crash occurs because CarPlay scenes are of type CPTemplateApplicationScene instead of UIWindowScene.
  • CPTemplateApplicationScene does not support geometry updates, so calling requestGeometryUpdateWithPreferences directly causes an unrecognized selector crash.
  • The proposed fix adds a type check to ensure the call is only made when the scene is a UIWindowScene.
  • On iPhone/iPad the current behavior remains unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions