Cannot use health and mdsflutter(depending on Movesense-mobile-lib) libraries in the same Flutter application

Issue #119 resolved
Benoît Vorlet created an issue

Hello, I have a problem using the mdsflutter library in my Flutter application because of the mixing of static and dynamic pods on IOS.

Globally, I'm already using a library called "Health" (https://pub.dev/packages/health) and I need to support the Movesense sensor to get ECG data. When I try to install the mdsflutter library, the pod installation succeeds but when building Xcode, there is a missing header file:

health/health-Swift.h' file not found

I assume this is due to the deletion of use_frameworks! in my podfile. It doesn't seem to me that cocoapods supports the use of use_frameworks! only for certain pods. And if I continue to use_frameworks! it's the Movesense pod that failed at Xcode compile time due to an undefined symbol error:

mdsflutter
Undefined symbol: _OBJC_CLASS_$_MDSWrapper
The linker command failed with output code 1 (use -v to see the invocation).

So I can't use both libraries.

I'm not familiar with IOS and the cocoapods environment, but have you found a solution to this problem? Or is there a solution to mix static and dynamic pods in the same pod file?

I've already tried:

If you need any further information, please don't hesitate to ask!

Here's my podfile :

platform :ios, '13.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

# Health will failed at Xcode build time
# target 'Runner' do
#   use_modular_headers!
#   pod 'Movesense', :git => 'ssh://git@altssh.bitbucket.org:443/movesense/movesense-mobile-lib.git'
#   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
# end

# Movesense will failed at Xcode build time
target 'Runner' do
  pod 'Movesense', :git => 'ssh://git@altssh.bitbucket.org:443/movesense/movesense-mobile-lib.git'
  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
           config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
      ]
    end
  end
end

Other informations :

  • Mobile device model and OS version : Iphone 13 pro, IOS 17.5.1
  • Movesense mobile library version : 3.15.0
  • Preconditions : A flutter application depending on health and mdsflutter
    health: ^9.0.0
    mdsflutter: ^2.0.0
  • Reproduction steps : Build the application using Xcode build
  • I will use the Movesense MD sensor from the developer kit (https://www.movesense.com/product/movesense-md-developer-kit-mdr/)

Comments (5)

  1. Petri Lipponen

    We encountered similar issue with the iOS isar database in another project. The solution was to all following clippet to the Podfile:

    dynamic_framework = ['isar_flutter_libs']
    
    pre_install do |installer|
      installer.pod_targets.each {| pod |
        if dynamic_framework.include?(pod.name)
          Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
          puts "turn to dynamic framework name:" + pod.name
          def pod.dynamic_framework;
            true
          end
          def pod.build_type;
            Pod::BuildType.dynamic_framework
          end
        end
      }
    end
    

    Then later in the configuration you can use the

      use_modular_headers!
      use_frameworks! :linkage => :static
    

    which the MDS requires, since it’s a static library.

  2. Log in to comment