Skip to content

Crash on CarPlay: requestGeometryUpdateWithPreferences not supported by CPTemplateApplicationScene #311

@yagoal

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.

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