Undefined symbol: OBJC_CLASS$_FlipperClient
Linker command failed with exit code 1 (use -v to see invocation)
This is an error that caused some confusion and many answers that partially solve the issue but none of them address the issues in a coherent way.
WHAT CAUSES THE ERROR:
In release builds it is caused by trying to line to react-native-flipper library that is not provided for linking yet required in
installer.generated_aggregate_target.xcconfigs
You can find these files in Targets Support Files > Pods-yourAppName in Xcode.
You can find it under OTHER_LDFLAGS with value -l"react-native-flipper"
In my opinion this is an oversight on behalf of the react-native-flipper team.
Most likely in your build output log you will find something like this.:
Undefined symbols for architecture arm64:
"OBJC_CLASS$_FlipperClient", referenced from: in
libreact-native-flipper.a4
ld: symbol(s) not found for architecture arm64 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
If you inspect FlipperReactNativeJavaScriptPluginManager file you will see that it is trying to:
#import <FlipperKit/FlipperClient.h>
And since there is no library to be linked the linker fails and the whole build fails.
YOU MIGHT ALREADY TRIED THIS SOLUTIONS:
use_flipper!(['Debug'])
use_flipper!({'Flipper' => '0.126.0', configurations: ['Debug', 'Dev.Debug']})
:flipper_configuration => FlipperConfiguration.enabled(["Debug"]),
PRODUCTION=1 bundle exec pod install
They might have worked but they are very dependant on the version of react-native-flipper that you use.
use_flipper! - deprecated in newer versions,
FlipperConfiguration.enabled(["Debug"]) - this will not work in older versions.
PRODUCTION=1 - env variable is not always available in your build,
As you can see here the PRODUCTION=1 is available only since this commit:
https://github.com/facebook/flipper/commit/0c442bf4b186859a0262ef259ba70d4996da3f3f
YET FOR OLDER VERSIONS IT WILL CONTINUE INCLUDES
But still the pods require other pods:
https://github.com/facebook/flipper/commit/44f5e35675f7198d720cc5075ec1f822e110d669#diff-ca0a0286a67452f62d0a79751348c6688482fbce1e93212428494f071904eda1
And going from FlipperKit.podspec
https://github.com/facebook/flipper/blob/main/iOS/Podfile
Which will include Flipper.podspect
https://github.com/facebook/flipper/blob/main/Flipper.podspec
And along the way one of them is going to add that pesky ld flag again.
HOW TO SOLVE THIS ISSUE:
If you are running the newest version of react-native-flipper and have access to build env variables all you have to do is pass
PRODUCTION=1 bundle exec pod install
flag and following this commit it will work.
https://github.com/facebook/flipper/commit/0c442bf4b186859a0262ef259ba70d4996da3f3f
If you are not so lucky and have to run older version of react-native-flipper you have to delete the linker flag from your release pods
Targets Support Files > Pods-yourAppName You can do it manually just to try out if your build will produce an archive for TestFlight or release
Or add a post install function that will remove the undesired linker flag.
def flipper_remove(generated_aggregate_target, config_name, config_file)
xcconfig_path = generated_aggregate_target.xcconfig_path(config_name)
if File.exist?(xcconfig_path)
puts "FLIPPER: Found xcconfig file: #{File.basename(xcconfig_path)}"
xcconfig_content = File.read(xcconfig_path)
modified_content = xcconfig_content.gsub('-l"react-native-flipper"', '')
File.open(xcconfig_path, 'w') { |file| file.write(modified_content) }
else
puts "FLIPPER: xcconfig file does not exist: #{File.basename(xcconfig_path)}"
end
end
post_install do |installer|
installer.generated_aggregate_targets.each do |generated_aggregate_target|
generated_aggregate_target.xcconfigs.each do |config_name, config_file|
next unless config_name == 'Release'
flipper_remove(generated_aggregate_target, config_name, config_file)
end
end
end
use_flipper!({ configurations: ['Debug', 'Dev.Debug'] })
– Arty