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
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.
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
I was facing the same problem and in my case just defining "use_frameworks!" as global resolved the problem.
After Podfile changes you should,
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
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
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