两者都实现了类,将使用两者之一。哪个是未定义的
Posted
技术标签:
【中文标题】两者都实现了类,将使用两者之一。哪个是未定义的【英文标题】:Class is implemented in both, One of the two will be used. Which one is undefined 【发布时间】:2017-10-25 12:22:14 【问题描述】:我对 Cocoapods 中包含的依赖项有疑问。
我有一个框架项目(MyFramework 目标),它也有应用程序目标(MyFrameworkExampleApp)。当我尝试运行该应用程序时,我得到一个充满如下错误的控制台:
类 PodsDummy_AFNetworking 在 /private/var/containers/Bundle/Application/AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/Frameworks/MyFramework.framework/MyFramework (0x1019a0438) 和 /var/containers/ 中实现捆绑包/应用程序/AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/MyFrameworkExampleApp (0x10107c558)。将使用两者之一。哪一个是未定义的。
问题是,错误来自仅包含在 MyFramework 目标中的库
这是我的 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
如您所见,App 目标没有继承任何 pod,我也没有任何全局 pod。这可能是什么原因?
【问题讨论】:
【参考方案1】:我不知道原因,但是如果您打开 cocoapods 创建的应用的 Pods-[AppName].debug.xcconfig 文件,您会发现 OTHER_LDFLAGS 并且您会看到它链接到您在您的应用程序中链接的相同框架框架。因此,如果您删除 -framework [Duplicated framework],警告就会消失。
似乎是 cocoapods 错误
【讨论】:
所以如果你删除 -framework [Duplicated framework] 警告就会消失。 - 这是一个警告,但它实际上会在运行时产生崩溃,例如在使用 ReactiveCocoa 时跨度> 这太疯狂了。这意味着静态/类变量在运行时在框架边界之外不是静态的——这可能会破坏状态并创建各种未定义的行为(例如 Google Maps SDK 以这种方式失败)。解决方法是什么? 这通常不是 CocoaPods 的问题。 这对我有用,但每次你pod install
时它都会重置
我没有使用 pod。怎么办?【参考方案2】:
我还发现了另一个自动修复错误的脚本。就像我上面回答的一样。 将其添加到您的 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
【讨论】:
你能看看github.com/CocoaPods/CocoaPods/issues/…,告诉我我做错了什么吗?【参考方案3】: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
【讨论】:
【参考方案4】:更新: 我为我的解决方案写了一篇博客文章:https://medium.com/@GalvinLi/tinysolution-fix-cocoapods-duplicate-implement-warning-5a2e1a505ea8
还有一个演示项目: https://github.com/bestwnh/TinySolution
我从互联网上得到了解决方案的想法,但找不到一个解决方案,所以我自己做了一个解决方法。也许代码有点长,但它工作。希望它可以帮助某人。
auto_process_target(,,)
是关键功能,只需将其更改为适合您的项目即可,一切正常。 (因为我用一个framework做multi app target,所以我把app 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
如果一切正常。当您 pod install
或 pod update
时,您将看到 Update xxxx OTHER_LDFLAGS
。然后警告消失了。
【讨论】:
该博客链接与该主题无关。 @ClayBridges 非常感谢您通知我。这是一个很大的错误。我更新了正确的链接。 @Galvin 请在github.com/CocoaPods/CocoaPods/issues/…查看我的新回复 @Galvin 嘿 Galvin,你能看看这个问题吗?我真的在努力解决这个问题...***.com/questions/65024153/…【参考方案5】:我遇到了同样的问题,在我的例子中,我只是将 "use_frameworks!" 定义为全局解决了这个问题。
Podfile 更改后,您应该这样做,
-
清理项目
从 xcode 中退出
删除派生数据
Pod 安装
与下面我的类似 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
【讨论】:
不幸的是我没用。【参考方案6】:我发现的大多数解决方案仅在选定的两个目标之间或主要目标与其他目标之间存在共享依赖关系时才能解决问题。但是,我们有一个复杂得多的项目,其中包含多个目标,其中任何两个目标之间都可能出现重复的框架。
基于TadeasKriz's code,我设法实现了一个解决方案,可以检查所有目标之间以及彼此之间的重复。
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)
# 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]
remainingAppPodTargets = targets[i+1..targets.size-1].flat_map(&:pod_targets)
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.
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
用法(把这个放在Podfile
的末尾):
post_install do |installer|
remove_duplicated_frameworks('Pods-YourMainTargetName', installer)
end
您还可以将整个解决方案另存为单独的文件,例如 DuplicatedFrameworksRemover.rb
并将其包含在您的 Podfile
中,使用:
load 'DuplicatedFrameworksRemover.rb'
【讨论】:
那么做完之后,你用什么pod命令呢?删除 Pods 文件夹并执行“pod install”? @justdan0227 是的,只是pod install
【参考方案7】:
我不知道为什么Xcode会出现这个问题,但就我而言,在我的项目目录中查找库并直接复制其名称并将其粘贴到 Bridging-Header 文件中解决了我的问题并且它有效。
【讨论】:
【参考方案8】:我不知道实际问题是什么,但是在将应用程序安装在不同的模拟器上之后。为我工作:)。
【讨论】:
以上是关于两者都实现了类,将使用两者之一。哪个是未定义的的主要内容,如果未能解决你的问题,请参考以下文章
两者都实现了 JavaLaunchHelper 类。将使用两者之一。哪一个是未定义的[重复]
Swift UITest - 将使用两者之一。哪个是未定义的
将使用两者之一。哪一个是未定义的。从表视图导航到 Web 视图
ABC 类在 Py2app 应用程序和系统库中都实现了。将使用两者之一
在 SVG 和画布之间,哪个更适合操作/动画多个图像?也许两者都没有,只使用 css3 转换?
我应该使用 Any() 还是 Count() ?哪个更快?如果 IEnumerable 对象中存在任何数据,两者都会返回相同的输出(真或假)吗? [复制]