Class is implemented in both, One of the two will be used. Which one is undefined

后端 未结 5 877
感情败类
感情败类 2020-12-04 19:15

I have an issue with dependencies included in Cocoapods.

I have a Framework project (MyFramework target), which also has App target (MyFrameworkExampleApp). When I t

相关标签:
5条回答
  • 2020-12-04 20:03

    Updated: I write a blog article for my solution: https://medium.com/@GalvinLi/tinysolution-fix-cocoapods-duplicate-implement-warning-5a2e1a505ea8

    And a demo project: https://github.com/bestwnh/TinySolution


    I got the solution idea from internet but can't find one solution work, so I make a workaround by myself. Maybe the code is a bit long, but it work. Hope it can help someone.

    The auto_process_target(,,) is the key function, just change it to fit your project and all should work fine. (Because I use one framework for multi app target, so I make the app target parameter be an array.)

    post_install do |installer|
    
      # you should change the sample auto_process_target method call to fit your project
    
      # sample for the question
      auto_process_target(['MyFrameworkExampleApp'], 'MyFramework', installer)
      # sample for the multi app use on same framework
      auto_process_target(['exampleiOSApp', 'exampleMacApp'], 'exampleFramework', installer)
    
    end
    
    # the below code no need to modify
    
    def auto_process_target(app_target_names, embedded_target_name, installer)
      words = find_words_at_embedded_target('Pods-' + embedded_target_name,
                                            installer)
      handle_app_targets(app_target_names.map{ |str| 'Pods-' + str },
                         words,
                         installer)
    end
    
    def find_line_with_start(str, start)
      str.each_line do |line|
          if line.start_with?(start)
            return line
          end
      end
      return nil
    end
    
    def remove_words(str, words)
      new_str = str
      words.each do |word| 
        new_str = new_str.sub(word, '')
      end
      return new_str
    end
    
    def find_words_at_embedded_target(target_name, installer)
      target = installer.pods_project.targets.find { |target| target.name == target_name }
      target.build_configurations.each do |config|
        xcconfig_path = config.base_configuration_reference.real_path
        xcconfig = File.read(xcconfig_path)
        old_line = find_line_with_start(xcconfig, "OTHER_LDFLAGS")
    
        if old_line == nil 
          next
        end
        words = old_line.split(' ').select{ |str| str.start_with?("-l") }.map{ |str| ' ' + str }
        return words
      end
    end
    
    def handle_app_targets(names, words, installer)
      installer.pods_project.targets.each do |target|
        if names.index(target.name) == nil
          next
        end
        puts "Updating #{target.name} OTHER_LDFLAGS"
        target.build_configurations.each do |config|
          xcconfig_path = config.base_configuration_reference.real_path
          xcconfig = File.read(xcconfig_path)
          old_line = find_line_with_start(xcconfig, "OTHER_LDFLAGS")
    
          if old_line == nil 
            next
          end
          new_line = remove_words(old_line, words)
    
          new_xcconfig = xcconfig.sub(old_line, new_line)
          File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
        end
      end
    end
    

    If all work. You will see Update xxxx OTHER_LDFLAGS when you pod install or pod update. Then the warning gone.

    0 讨论(0)
  • 2020-12-04 20:06

    https://github.com/CocoaPods/CocoaPods/issues/7126#issuecomment-399395611

    post_install do |installer|
        applicationTargets = [
            'Pods-SampleApp',
        ]
        libraryTargets = [
            'Pods-SampleLib',
        ]
    
        embedded_targets = installer.aggregate_targets.select { |aggregate_target|
            libraryTargets.include? aggregate_target.name
        }
        embedded_pod_targets = embedded_targets.flat_map { |embedded_target| embedded_target.pod_targets }
        host_targets = installer.aggregate_targets.select { |aggregate_target|
            applicationTargets.include? aggregate_target.name
        }
    
        # We only want to remove pods from Application targets, not libraries
        host_targets.each do |host_target|
            host_target.xcconfigs.each do |config_name, config_file|
                host_target.pod_targets.each do |pod_target|
                    if embedded_pod_targets.include? pod_target
                        pod_target.specs.each do |spec|
                            if spec.attributes_hash['ios'] != nil
                                frameworkPaths = spec.attributes_hash['ios']['vendored_frameworks']
                                else
                                frameworkPaths = spec.attributes_hash['vendored_frameworks']
                            end
                            if frameworkPaths != nil
                                frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
                                    extension = File.extname filename
                                    File.basename filename, extension
                                end
                                frameworkNames.each do |name|
                                    puts "Removing #{name} from OTHER_LDFLAGS of target #{host_target.name}"
                                    config_file.frameworks.delete(name)
                                end
                            end
                        end
                    end
                end
                xcconfig_path = host_target.xcconfig_path(config_name)
                config_file.save_as(xcconfig_path)
            end
        end
    end
    
    0 讨论(0)
  • 2020-12-04 20:16

    I was facing the same problem and in my case just defining "use_frameworks!" as global resolved the problem.

    After Podfile changes you should,

    1. Clean project
    2. Quit from xcode
    3. Delete derived data
    4. Pod install

    similar Podfile to mine below,

    workspace 'sample'
    # Comment the next line if you don't want to use dynamic frameworks
    use_frameworks!
    platform :ios, '13.0'
    
    def sample_pods
      pod 'Alamofire' , '~> 5.1.0'
      pod 'RxSwift'
      pod 'CodableAlamofire'
    end
    
    def sample_framework_pods
      pod 'Alamofire' , '~> 5.1.0'
      pod 'RxSwift'
      pod 'CodableAlamofire'
    end
    
    target 'sample' do
      # Pods for sample
        sample_pods
    end
    
    target 'sample_framework' do
      project 'sample_framework/sample_framework.xcodeproj'
      # Pods for sample_framework
      sample_framework_pods
    end
    
    0 讨论(0)
  • 2020-12-04 20:17

    I also found another a script someone wrote that fix the bug automatically. It's simply make the same I answered above. Add it to your Podfile:

    post_install do |installer|
        sharedLibrary = installer.aggregate_targets.find { |aggregate_target| aggregate_target.name == 'Pods-[MY_FRAMEWORK_TARGET]' }
        installer.aggregate_targets.each do |aggregate_target|
            if aggregate_target.name == 'Pods-[MY_APP_TARGET]'
                aggregate_target.xcconfigs.each do |config_name, config_file|
                    sharedLibraryPodTargets = sharedLibrary.pod_targets
                    aggregate_target.pod_targets.select { |pod_target| sharedLibraryPodTargets.include?(pod_target) }.each do |pod_target|
                        pod_target.specs.each do |spec|
                            frameworkPaths = unless spec.attributes_hash['ios'].nil? then spec.attributes_hash['ios']['vendored_frameworks'] else spec.attributes_hash['vendored_frameworks'] end || Set.new
                            frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
                                extension = File.extname filename
                                File.basename filename, extension
                            end
                        end
                        frameworkNames.each do |name|
                            if name != '[DUPLICATED_FRAMEWORK_1]' && name != '[DUPLICATED_FRAMEWORK_2]'
                                raise("Script is trying to remove unwanted flags: #{name}. Check it out!")
                            end
                            puts "Removing #{name} from OTHER_LDFLAGS"
                            config_file.frameworks.delete(name)
                        end
                    end
                end
                xcconfig_path = aggregate_target.xcconfig_path(config_name)
                config_file.save_as(xcconfig_path)
            end
        end
    end
    
    0 讨论(0)
  • 2020-12-04 20:19

    I don't know the reason, but if you open your app's Pods-[AppName].debug.xcconfig file that cocoapods creates you'll find OTHER_LDFLAGS and you'll see it links to the same frameworks you link in your framework. So if you remove -framework [Duplicated framework] the warning disappears.

    Seems to be a cocoapods error

    0 讨论(0)
提交回复
热议问题