software-mansion / react-native-screens

Native navigation primitives for your React Native app.
https://docs.swmansion.com/react-native-screens/
MIT License
3.09k stars 519 forks source link

IOS - use_framework! not working when combining with react-native-reanimated v3 #1963

Open huyvuskedulo opened 1 year ago

huyvuskedulo commented 1 year ago

Description

We're trying to update into latest version of react-native + reanimated + react-native-screens, so far not so good we're able to track down which is the package that keep throwing the errors with some specific condition.

Our app is vanilla app and using old architecture.

Here is the error that it's throwing on Xcode after try to build the project:

Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_RCTImageLoader", referenced from:
      objc-class-ref in RNSScreenStackHeaderConfig.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I believe this is the combination of the use_framework + react-native-reanimated + react-native-screens

Steps to reproduce

Here is the simplify Podfile

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!

# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
#
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
# ```js
# module.exports = {
#   dependencies: {
#     ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'TestProject' do
  use_frameworks!

  config = use_native_modules!

  # Flags change depending on the env values.
  flags = get_default_flags()

  use_react_native!(
    :path => config[:reactNativePath],
    # Hermes is now enabled by default. Disable by setting this flag to false.
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    # Enables Flipper.
    #
    # Note that if you have use_frameworks! enabled, Flipper will not work and
    # you should disable the next line.
    :flipper_configuration => FlipperConfiguration.disabled,
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'TestProjectTests' do
    inherit! :complete
    # Pods for testing
  end

  post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end
end

This is how the package.json look like

    "react": "18.2.0",
    "react-native": "0.72.6",
    "@freakycoder/react-native-bounceable": "0.2.2",
    "@klarna/react-native-vector-drawable": "0.4.0",
    "@react-native-clipboard/clipboard": "1.11.2",
    "@react-native-community/datetimepicker": "7.6.1",
    "@react-native-community/netinfo": "9.4.1",
    "@react-navigation/native": "6.1.9",
    "@react-navigation/native-stack": "6.9.17",
    "react-native-reanimated": "3.5.4",
    "react-native-screens": "3.27.0",
    "patch-package": "6.4.7",
    "react-async": "10.0.1",
    "simple-evaluate": "1.4.5",
    "styled-components": "5.2.1",
    "typescript": "5.1.3",
    "brandi": "5.0.0"

Snack or a link to a repository

https://github.com/huyvuskedulo/TestProject

Screens version

3.27.0

React Native version

0.72.6

Platforms

iOS

JavaScript runtime

None

Workflow

None

Architecture

None

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

tboba commented 1 year ago

Hi @huyvuskedulo, thanks for reporting this issue! Why do you need to use use_frameforks! in your Podfile? I've launched the app without this line and it has been built properly in my case.

huyvuskedulo commented 1 year ago

Hey @tboba ,

Our app is a hybrid app which already being built by using native code (iOS/Android) a lot of places, and we're using many native libraries + Swift, so we can't get rid of use_framework!.

UPDATE; I downgraded the package into 3.25.0 and it does seem working fine

kkafar commented 1 year ago

@huyvuskedulo, I've narrowed down my search for PR that introduced this error to this PR: https://github.com/software-mansion/react-native-screens/pull/1920.

Could your please test react-native-screens version w/o this commit? You can do this by putting following line in your package.json:

"react-native-screens": "software-mansion/react-native-screens#72ab69225acb22d7d9c27f0a927c6ca1b0516344"

Please let me know, whether the crash happens on that version.

tboba commented 11 months ago

Hi @huyvuskedulo, since this issue is inactive for 3 weeks I just wanna make sure that you've managed to check the version without the commit mentioned by @kkafar. Are you still facing any issues there? Allow me to mark this issue with Close when stale tag for now, but don't hesitate to share your feedback there!

huyvuskedulo commented 11 months ago

Hey @tboba , thanks for the fix, it seems that it's working with that commit.

Sorry for the late reply since i'm not following this upgrade program anymore, but I did try your commit so far and it seem it bypassed the error, however i'm still facing other issue with the migration but not seem to relate to this fix. So I can't guarantee this fix will impact anything else :)

tboba commented 11 months ago

Hi @huyvuskedulo, thanks for the update! @kkafar so it looks like we should modify or even completely revert this commit 👀

kkafar commented 11 months ago

Yeah, that might be a one solution.

But I would suggest holding our commit-reverting-horses until we know what the root cause is.

I do not understand what mechanisms are behind this error right now, still need to debug it further, maybe it could be solved in some other way.

mateioprea commented 11 months ago

@huyvuskedulo I will assume you've enabled dynamic link for the project. For a quick fix you can set the build type for reanimated and rnscreens to static and that will fix the project.

if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
  pre_install do |installer|
      installer.pod_targets.each do |pod|
        if pod.name.eql?('RNReanimated') # add more pod names here 
          def pod.build_type;
            Pod::BuildType.static_library
          end
        end
      end
    end
end
delphinebugner commented 10 months ago

Thanks @mateioprea! I had the same error as @huyvuskedulo and indeed, I'm using dynamically linked framework (one of our major native dependency relies on it)

Setting RNScreens to stay statically linked in the podfile did the job 👌 Edit: And indeed I absolutely have to make static RNReanimated too!

It's not the first pod we modify that way, and probably not the last either 😅 We will probably keep it that way, unless you strongly not recommend it as you said it's only a quick fix!

itlijunjie commented 6 months ago

Try it. https://github.com/software-mansion/react-native-screens/issues/2117#issuecomment-2105600238

vyasdarshan commented 4 months ago

i resolved the issue with below changes in pod file

Package.json

"react-native-reanimated": "^3.13.0",
"react-native-gesture-handler": "^2.17.1",
"react-native-screens": "^3.25.0",

Pod file

pre_install do |installer|
      installer.pod_targets.each do |pod|
        if pod.name.eql?('RNScreens') || pod.name.eql?('RNCMaskedView') || pod.name.eql?('RNReanimated')
          def pod.build_type
            Pod::BuildType.static_library
          end
        end
      end
    end  
installer.pod_targets.each do |pod|
       if pod.name.eql?('RNReanimated')
         def pod.build_type
           Pod::BuildType.static_library
         end
       end
     end

After above changes in pod file clear derived data and clean the build , Install pod again and run