ios 类在两者中都实现,将使用两者之一。哪个是未定义的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46932341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:35:54  来源:igfitidea点击:

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

iosxcodecocoapods

提问by mag_zbc

I have an issue with dependencies included in Cocoapods.

我对 Cocoapods 中包含的依赖项有问题。

I have a Framework project (MyFramework target), which also has App target (MyFrameworkExampleApp). When I try to run the app, I get a console full of errors like so:

我有一个框架项目(MyFramework 目标),它也有应用程序目标(MyFrameworkExampleApp)。当我尝试运行该应用程序时,我得到一个充满错误的控制台,如下所示:

Class PodsDummy_AFNetworking is implemented in both /private/var/containers/Bundle/Application/AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/Frameworks/MyFramework.framework/MyFramework (0x1019a0438) and /var/containers/Bundle/Application/AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/MyFrameworkExampleApp (0x10107c558). One of the two will be used. Which one is undefined.

PodsDummy_AFNetworking 类在 /private/var/containers/Bundle/Application/AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/Frameworks/MyFramework.framework/MyFramework (0x1019a0undle) 和 /Bundle/Varcontainer 中实现/AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/MyFrameworkExampleApp (0x10107c558)。将使用两者之一。哪个是不确定的。

The thing is, the errors come from the libraries included only in MyFramework target

问题是,错误来自仅包含在 MyFramework 目标中的库

Here are the contents of my podfile:

这是我的 podfile 的内容:

# Specify platform.
platform :ios, '9.0'

# Let's ignore all warnings from all pods
inhibit_all_warnings!

target 'MyFramework' do

    # ReactiveCocoa for easier binding between UI and data models.
    pod 'ReactiveCocoa', '< 3.0'

    # ReactiveViewModel for easier handling of active/inactive view models.
    pod 'ReactiveViewModel', '0.3'

    # An Objective-C extension with some nice helpers including @weakify/@strongify.
    pod 'libextobjc', '~> 0.4.1'

    # AFNetworking Security stuff
    pod 'AFNetworking/Security', '~> 2.5.4'

    # KZPropertyMapper to easily map JSON dicts to properties
    pod "KZPropertyMapper"

    # Simple wrapper for KeyChain
    pod 'UICKeyChainStore', '~> 2.0.6'

    # Animated gifs
    pod 'FLAnimatedImage', '~> 1.0'

    # Firebase push notifications
    pod 'Firebase/Core'
    pod 'Firebase/Messaging'

    # Easy image downloading with cache.
    pod 'SDWebImage', '~> 3.7.2'

    # Activity indicator for RBSlider
    pod 'DGActivityIndicatorView'

end

target 'MyFrameworkExampleApp' do

    # Progress indicator
    pod 'MBProgressHUD', '~> 1.0.0'

    # Color picker
    pod 'iOS-Color-Picker'

    # Hockey SDK
    pod 'HockeySDK', '~> 5.0.0'

end

As you can see, App target does not inherit any pods, nor do I have any global pods. What might be the reason for this?

如您所见,App target 没有继承任何 Pod,我也没有任何全局 Pod。这可能是什么原因?

采纳答案by David Bemerguy

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.

我不知道原因,但是如果您打开 cocoapods 创建的应用程序的 Pods-[AppName].debug.xcconfig 文件,您会发现 OTHER_LDFLAGS 并且您会看到它链接到您在框架中链接的相同框架。因此,如果您删除 -framework [Duplicated framework],警告就会消失。

Seems to be a cocoapods error

似乎是 cocoapods 错误

回答by David Bemerguy

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:

我还发现了另一个有人编写的脚本,可以自动修复错误。它只是使我在上面回答的相同。将其添加到您的 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

回答by Galvin

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

更新:我为我的解决方案写了一篇博客文章:https: //medium.com/@GalvinLi/tinysolution-fix-cocoapods-duplicate-implement-warning-5a2e1a505ea8

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

和一个演示项目: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.)

auto_process_target(,,)是关键功能,只需更改它以适合您的项目,一切都应该正常工作。(因为我对多应用程序目标使用一个框架,所以我将应用程序目标参数设为一个数组。)

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_LDFLAGSwhen you pod installor pod update. Then the warning gone.

如果一切正常。您将看到Update xxxx OTHER_LDFLAGS当您pod install或 时pod update。然后警告消失了。

enter image description here

enter image description here

回答by Mateo Marin

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

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

回答by F?rat Yenidünya

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

我遇到了同样的问题,在我的例子中只是定义了“use_frameworks!” 作为全球解决了这个问题。

After Podfile changes you should,

Podfile 更改后,您应该,

  1. Clean project
  2. Quit from xcode
  3. Delete derived data
  4. Pod install
  1. 清洁工程
  2. 退出 xcode
  3. 删除派生数据
  4. Pod 安装

similar Podfile to mine below,

类似于下面的 Podfile,

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