Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CarPlay standalone mode won't show anything when react navigation screens are present #154

Open
mursang opened this issue Nov 8, 2023 · 11 comments
Labels
bug Something isn't working

Comments

@mursang
Copy link

mursang commented Nov 8, 2023

Describe the bug
CarPlay works in standalone mode (without phone app opened), but it won't work because of something related to react native navigators

CarPlay (please complete the following information):

  • Device: Simulator and real device
  • OS version: iOS 17.0
  • RNCarPlay version 2.3.0

Additional context
I made some changes on my Swift code, in order to CarPlay work in standalone mode by forcing bridge to be present without the need of the app as stated in this comment:
#109 (comment)

Everything seems working fine with the app opened, but if I try to use CarPlay without app, it crashes without an error.
Just noticed it is related to my React Navigation code, but can't find where and how to fix.

In my App.js (starting point of my app) I return this:

---- code to connect Carplay that is correctly working  --- 

return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <ApplicationNavigator />
      </PersistGate>
    </Provider>
  );

ApplicationNavigator:

const ApplicationNavigator = () => {
  const { Layout, darkMode, NavigationTheme } = useTheme()
  const { colors } = NavigationTheme

  return (
    <SafeAreaView style={[Layout.fill, { backgroundColor: colors.card }]}>
      <NavigationContainer theme={NavigationTheme} ref={navigationRef}>
        <StatusBar barStyle={darkMode ? 'light-content' : 'dark-content'} />
        <Stack.Navigator screenOptions={{ headerShown: false }}>
          <Stack.Screen name="Startup" component={IndexStartupContainer} />
          <Stack.Screen name="Login" component={LoginContainer} />
          <Stack.Screen
            name="Main"
            component={MainNavigator}
            options={{
              animationEnabled: false,
            }}
          />
        </Stack.Navigator>
      </NavigationContainer>
    </SafeAreaView>
  )
}

export default ApplicationNavigator

So, just noticed that if I comment all Stack.Screens in the AppNavigator, CarPlay will work without any kind of problem, without the need of the app to be opened. (Obviously I can't open the app with these lines commented, as I see a blank scene).

I also tried to comment Screen by Screen, but seems something more related to Screens itself than with a specific one (or something that every screen loads, such as libraries?).

Did anyone have this problem and solved it?
Do you know how to debug this kind of crashes with CarPlay that don't drop any log?

Thank you very much!

@mursang mursang added the bug Something isn't working label Nov 8, 2023
@mursang
Copy link
Author

mursang commented Nov 9, 2023

Is there any way to detect in React Native that Carplay is working without opening the app? This way maybe I could make a workaround:
App: Load views as usual (tested and works as usual, before installing carplay)
Carplay: Don't load navigator (tested and works, but can't open App as it doesn't load any view)
App + Carplay: load navigator (tested and works)

this way, all three cases would work I think.

@DanielKuhn
Copy link
Contributor

After fiddling around with this topic for quite some time now, always in doubt of what's happening under the hood and seeing ever more questions around starting on CarPlay without having the app running on phone, I took the liberty to create (and document!) an example app which runs independently of the phone app and supports launching on CarPlay directly (without having the phone app running) in this PR: #158
Patches welcome, feel free to add comments and improvements.

@mursang
Copy link
Author

mursang commented Nov 28, 2023

After fiddling around with this topic for quite some time now, always in doubt of what's happening under the hood and seeing ever more questions around starting on CarPlay without having the app running on phone, I took the liberty to create (and document!) an example app which runs independently of the phone app and supports launching on CarPlay directly (without having the phone app running) in this PR: #158 Patches welcome, feel free to add comments and improvements.

Thank you for your efforts!
Unfortunately, after changing my project files to match yours, it compiles and works good on phone, but when trying to open Carplay in standalone mode, it breaks without any error (as I was experiencing before your changes). However, opening Carplay with phone app works good too.
I don't know why, but it seems something related to some library like react-navigation, react-redux or so.. Seems like if you are using it in the project, Carplay is not able to load that library in the background without the need of the phone app.

Do you know any way to debug errors on Carplay?

@mursang
Copy link
Author

mursang commented Nov 28, 2023

Well... after some testing I'm starting to suspect that is something related to api calls using axios. Will try to debug and to use another library (or maybe it's not possible to perform api calls when using carplay in standalone mode)

@DanielKuhn
Copy link
Contributor

@mursang The only way of debugging the stand-alone CarPlay app that I found was to add native logging as described here to my code and then checking the logs in the console (/System/Applications/Utilities/Console.app) of the physical device by filtering by process to only my app while the CarPlay-app is running in stand-alone mode.
I also had a black screen on CarPlay for a while - in my case the problem was the splash-screen call (RNSplashScreen.show()) which I still had in the AppDelegate's application:didFinishLaunchingWithOptions that CarPlay couldn't handle. After moving that to the PhoneDelegate everything worked.

@mursang
Copy link
Author

mursang commented Nov 28, 2023

@DanielKuhn thank you for pointing me in the right direction and for sharing your code.
My code was crashing due to react-native-screens that is installed by default with react-navigation. I could disable (not uninstalling) the use or react-native-screens, and now it works perfectly.

import { enableScreens } from 'react-native-screens';

enableScreens(false);

You saved my life!!

@DanielKuhn
Copy link
Contributor

@mursang great to hear that you got it fixed.
Could you elaborate on the problem you had with react-native-screens, though? I'm also using react-navigation with enableScreens(true) and so far there doesn't seem to be a problem. What exactly went wrong in your case?

Which versions of react native, react-navigation and react-native-screens are you using? I'm on

"react-native": "0.71.14",
"@react-navigation/bottom-tabs": "6.5.11",
"@react-navigation/drawer": "6.6.6",
"@react-navigation/material-top-tabs": "6.6.5",
"@react-navigation/native": "6.1.9",
"@react-navigation/native-stack": "6.9.17",
"@react-navigation/stack": "6.3.20",
"react-native-screens": "3.27.0",

@mursang
Copy link
Author

mursang commented Nov 28, 2023

@DanielKuhn After some debugging I found an error in the logs file:

0   CoreFoundation                	       0x1b4294870 __exceptionPreprocess + 164
1   libobjc.A.dylib               	       0x1ac5afc00 objc_exception_throw + 59
2   CoreFoundation                	       0x1b432519c -[NSObject(NSObject) doesNotRecognizeSelector:] + 343
3   UIKitCore                     	       0x1b71f8154 -[UIResponder doesNotRecognizeSelector:] + 259
4   CoreFoundation                	       0x1b41d9ff8 ___forwarding___ + 1563
5   CoreFoundation                	       0x1b431ab10 _CF_forwarding_prep_0 + 95
6   AppName                	               0x1049069c8 __56+[RNSScreenWindowTraits enforceDesiredDeviceOrientation]_block_invoke + 580

So I searched for that error and found it was related to orientation calculation in react-native-screens. I don't know exactly what fails, but disabling screens worked for me.

"react-native": "0.71.13",
"@react-navigation/bottom-tabs": "6.5.8",
"@react-navigation/native": "6.1.7",
"@react-navigation/stack": "5.14.9",
"react-native-screens": "3.27.0",

Seems like I am using an old version of the stack package. Maybe the latest version fixes the problem.

@uzegonemad
Copy link
Contributor

FYI I just opened software-mansion/react-native-screens#2035 to address this issue.

I also created a patch in the meantime.

@DanielKuhn
Copy link
Contributor

DanielKuhn commented Feb 15, 2024

@uzegonemad Good to see you found the root cause and an actual fix for the problem.

My CarPlay-app does not render anything or navigate in the phone app, that's probably why this isn't a problem in my case.
I did run into similar problems after switching to scenes as well, though. It seems to be a common misconception to always use the first connected scene, assuming it's the window scene.

My scene-finding code looks like this:

let activeWindowScene = UIApplication.shared.connectedScenes.filter { scene in
    return scene.activationState == .foregroundActive && scene is UIWindowScene
}.first

The latest bug I found when using scenes is that in iOS, when you connect an external display, the app crashes.
I fixed this in my PhoneSceneDelegate and opened #168 to fix it in the example app.

@tboba
Copy link

tboba commented May 10, 2024

Hi, everyone! React Native Screens maintainer here.
I see that this issue is related to software-mansion/react-native-screens#1857, which has been closed today. Do you know if this issue has been resolved on your side?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants