Flutter集成Firebase Analytics/iOS遇Undefined symbol链接错误求助
Flutter iOS集成Firebase Analytics与Crashlytics出现链接错误的解决方法
在iOS模拟器及真机运行时出现以下链接错误:
Error (Xcode): Undefined symbol: _FIRConsentStatusDenied Error (Xcode): Undefined symbol: _FIRConsentStatusGranted Error (Xcode): Undefined symbol: _FIRConsentTypeAdPersonalization Error (Xcode): Undefined symbol: _FIRConsentTypeAdStorage Error (Xcode): Undefined symbol: _FIRConsentTypeAdUserData Error (Xcode): Undefined symbol: _FIRConsentTypeAnalyticsStorage Error (Xcode): Undefined symbol: _OBJC_CLASS_$_FIRAnalytics Error (Xcode): Linker command failed with exit code 1 (use -v to see invocation) Could not build the application for the simulator.
已尝试添加arm64到Excluded Architectures、更新/清理Pods等方案,均无效。
环境信息
Flutter Doctor输出
[✓] Flutter (Channel stable, 3.19.3, on macOS 14.4.1 23E224 darwin-arm64, locale tr-TR) • Flutter version 3.19.3 on channel stable at /Users/taha/Dev/core/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision ba39319843 (2 months ago), 2024-03-07 15:22:21 -0600 • Engine revision 2e4ba9c6fb • Dart version 3.3.1 • DevTools version 2.31.1 [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/taha/Library/Android/sdk • Platform android-34-ext8, build-tools 34.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 15.3) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 15E204a • CocoaPods version 1.15.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2023.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) [✓] VS Code (version 1.89.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.88.0
pubspec依赖
dependencies: adjust_sdk: ^4.31.0 android_id: ^0.3.6 animate_do: ^3.0.2 auto_route: ^7.8.4 auto_size_text: ^3.0.0 bloc: ^8.1.2 cached_network_image: ^3.2.3 cached_network_svg_image: ^0.0.7 chewie: ^1.8.1 collection: 1.18.0 connectivity_plus: ^5.0.2 cupertino_icons: ^1.0.2 device_info_plus: ^9.0.3 dio: ^5.3.2 dropdown_button2: ^2.3.9 equatable: ^2.0.5 expandable: ^5.0.1 file_picker: ^6.1.1 firebase_analytics: ^10.10.5 firebase_core: ^2.31.0 firebase_crashlytics: ^3.5.5 firebase_messaging: ^14.9.2 flutter: sdk: flutter flutter_bloc: ^8.1.3 flutter_cache_manager: ^3.3.2 flutter_email_sender: ^6.0.2 flutter_inappwebview: ^6.0.0 flutter_localizations: sdk: flutter flutter_notification_channel: ^3.1.0 flutter_rating_bar: ^4.0.1 flutter_secure_storage: ^9.0.0 flutter_slidable: ^3.0.1 flutter_svg: ^2.0.9 get_ip_address: ^0.0.6 get_it: ^7.6.4 hive: ^2.2.3 html: ^0.15.4 http: ^1.1.0 image_cropper: ^5.0.1 image_gallery_saver: ^2.0.3 image_picker: ^1.0.2 infinite_scroll_pagination: ^4.0.0 internet_connection_checker: ^1.0.0+1 keep_screen_on: ^3.0.0 keyboard_actions: ^4.2.0 local_auth: ^2.1.7 mqtt_client: ^10.0.3 overlay_support: ^2.1.0 package_info_plus: ^7.0.0 path: ^1.8.3 path_provider: ^2.0.12 pdf: ^3.10.8 pdfx: git: url: https://github.com/ScerIO/packages.flutter ref: 8b105a7dfc6b90220c1d79fcb805fb764cab00c5 path: packages/pdfx pinput: ^3.0.1 protoc_plugin: ^21.0.2 readmore: ^2.2.0 share_plus: ^7.2.1 shimmer: ^3.0.0 skeletonizer: ^1.0.1 sqflite: ^2.3.0 sticky_headers: ^0.3.0+2 syncfusion_flutter_charts: 23.1.44 syncfusion_flutter_datagrid: 23.1.44 syncfusion_flutter_gauges: 23.1.44 talker: ^4.0.2 talker_bloc_logger: ^4.0.2 talker_dio_logger: ^4.0.2 talker_flutter: ^4.0.2 toast: ^0.3.0 turkish: ^0.2.1 tw_queue: ^0.0.3 url_launcher: ^6.2.4 video_player: ^2.7.2 webview_flutter: ^4.2.0 wolt_modal_sheet: ^0.1.4
Podfile内容
# Uncomment this line to define a global platform for your project # platform :ios, '14.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' project 'Runner', { 'Debug' => :debug, 'Profile' => :release, 'Release' => :release, } def flutter_root generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) unless File.exist?(generated_xcode_build_settings_path) raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" end File.foreach(generated_xcode_build_settings_path) do |line| matches = line.match(/FLUTTER_ROOT\=(.*)/) return matches[1].strip if matches end raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" end require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) flutter_ios_podfile_setup target 'Runner' do use_frameworks! use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) pod 'Toaster' pod 'IQKeyboardManagerSwift', '6.5.16' pod 'EnVerify', '1.3.14.5' # $FirebaseAnalyticsWithoutAdIdSupport = false end def remove_duplicated_frameworks(app_pod_name, installer) test_targets = get_test_targets(app_pod_name, installer) puts "Detected test targets: #{test_targets}" puts "Removing duplicated frameworks from OTHER_LDFLAGS" targets = installer.aggregate_targets.select { |x| !test_targets.include?(x.name) } puts " targets: #{targets}" # Checks each pair of targets if they have common pods. Duplicates are removed from the first one's xcconfig. for i in 0..targets.size-1 do target = targets[i] puts " target: #{target}" remainingAppPodTargets = target.pod_targets puts " remainingAppPodTargets: #{remainingAppPodTargets}" target.xcconfigs.each do |config_name, config_file| # Removes all frameworks which exist in other pods remainingAppPodTargets .flat_map {|pod_target| get_framework_names(pod_target)} .each { |framework| config_file.frameworks.delete(framework) } # Saves updated xcconfig xcconfig_path = target.xcconfig_path(config_name) config_file.save_as(xcconfig_path) end end end def get_test_targets(app_pod_name, installer) main_target_name = app_pod_name.gsub("Pods-", "") installer.aggregate_targets .find { |x| x.name == app_pod_name } .user_project .targets .select { |x| x.test_target_type? } .flat_map { |x| ["Pods-#{x}", "Pods-#{main_target_name}-#{x}"] } .select { |x| installer.aggregate_targets.map(&:name).include?(x) } .uniq end def get_framework_names(pod_target) frameworkNames = pod_target.specs.flat_map do |spec| # We should take framework names from 'vendored_frameworks'. # If it's not defined, we use 'spec.name' instead. # # spec.name can be defined like Framework/Something - we take the first part # because that's what appears in OTHER_LDFLAGS. puts " spec: #{spec}" frameworkPaths = unless spec.attributes_hash['ios'].nil? then spec.attributes_hash['ios']['vendored_frameworks'] else spec.attributes_hash['vendored_frameworks'] end || [spec.name.split(/\//, 2).first] map_paths_to_filenames(frameworkPaths) end frameworkNames.uniq end def map_paths_to_filenames(paths) Array(paths).map(&:to_s).map do |filename| extension = File.extname filename File.basename filename, extension end end post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = "" config.build_settings['CODE_SIGNING_REQUIRED'] = "NO" config.build_settings['CODE_SIGNING_ALLOWED'] = "NO" config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'No' end flutter_additional_ios_build_settings(target) end installer.aggregate_targets.each do |target| target.xcconfigs.each do |variant, xcconfig| xcconfig_path = target.client_root + target.xcconfig_relative_path(variant) IO.write(xcconfig_path, IO.read(xcconfig_path).gsub("DT_TOOLCHAIN_DIR", "TOOLCHAIN_DIR")) end end remove_duplicated_frameworks('Pods-Runner', installer) end
解决方案
1. 注释掉移除重复框架的脚本
Podfile中的remove_duplicated_frameworks脚本会自动清理链接标志中的重复框架,但可能误删了FirebaseAnalytics相关依赖,导致符号找不到。修改post_install部分,注释掉这一行:
# remove_duplicated_frameworks('Pods-Runner', installer)
2. 启用Firebase Analytics的AdID配置
取消Podfile中以下行的注释,确保Firebase Analytics的完整符号集被引入:
$FirebaseAnalyticsWithoutAdIdSupport = false
3. 彻底清理并重新安装Pods
执行以下命令清理缓存和Pods:
flutter clean cd ios rm -rf Pods Podfile.lock pod deintegrate pod install cd ..
4. 统一Firebase依赖版本
确保所有Firebase相关依赖版本相互兼容,建议升级到最新稳定版,比如修改pubspec.yaml:
firebase_core: ^2.32.0 firebase_analytics: ^10.11.0 firebase_crashlytics: ^3.6.0 firebase_messaging: ^14.10.0
执行flutter pub get后重新安装Pods。
5. 验证Xcode链接配置
打开iOS项目的Runner target,检查Build Settings:
- 确认
Other Linker Flags包含-ObjC - 确认
Link Binary With Libraries中存在FirebaseAnalytics.framework(如果缺失,手动添加Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework)
内容的提问来源于stack exchange,提问作者t13n
相关产品推荐
相关产品推荐

