I'm making an app in my spare time and I wanted to ask you a question, my workspace has 3 subprojects: presentation, domain and data, each one is a static framework and has its own pods, and all very cool, but now I have a problem that I don't know how to solve it. I have several firebase dependencies that some of them must be in Presentation and others in Data, the problem comes when executing because it gives me an error :
Class PodsDummy_FirebaseUI is implemented in both /Users/.../Debug-iphonesimulator/PresentationCleanExample.framework/PresentationCleanExample (0x104ffada0) and /Users/.../data/Containers/Bundle/Application/A15FF8B8-7B67-4512-8DFD-04F008175660/CleanExample.app/CleanExample (0x100c6e288). One of the two will be used. Which one is undefined.
So what I've see in the podspec of FirebaseUI/Storage is the following: https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseStorageUI.podspec
s.dependency 'Firebase/Storage'
s.dependency 'GTMSessionFetcher/Core', '~> 1.5.0'
s.dependency 'SDWebImage', '~> 5.6'
This makes me think that cocoapods is not resolving the dependency Firebase/Storage properly.
And the problem is that this is only one of the thousands of duplicate classes that I have from Firebase for following the diagram above. I suppose there is a way to inject the Firebase dependency only once and thus avoid class duplication, but I don't know how.
My Podfile:
platform :ios, '13.6'
workspace 'CleanExample'
use_frameworks!
def firebase_pods
pod 'Firebase/Core', '7.11.0'
pod 'Firebase/Auth', '7.11.0'
pod 'Firebase/Firestore', '7.11.0'
pod 'Firebase/Storage', '7.11.0'
pod 'FirebaseFirestoreSwift', '7.11.0-beta'
end
target 'CleanExample' do
project 'CleanExample'
firebase_pods
pod 'FirebaseUI/Storage'
end
target 'PresentationCleanExample' do
project 'PresentationCleanExample/PresentationCleanExample.xcodeproj'
# firebase_pods
pod 'FirebaseUI/Storage'
end
target 'DomainCleanExample' do
project 'DomainCleanExample/DomainCleanExample.xcodeproj'
end
target 'DataCleanExample' do
project 'DataCleanExample/DataCleanExample.xcodeproj'
firebase_pods
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
end
end
end
I've uploaded the code https://github.com/rchampa/CleanExample
Is there something wrong with the FirebaseStorageUI.podspec file or is a limitation of cocoapods?
Is my Podfile wrong?
Finally I solved my problem inspired by this post https://medium.com/@GalvinLi/tinysolution-fix-cocoapods-duplicate-implement-warning-5a2e1a505ea8 because it let me understand the problem.
If i understand correctly OTHER_LDFLAGS is adding the frameworks by duplicate.
Then to avoid the original message problem Class *** is implemented in both
I install all the pods in the target 'CleanExample' and remove the OTHER_LDFLAGS line from the following files.
Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
# Inspired by https://medium.com/@GalvinLi/tinysolution-fix-cocoapods-duplicate-implement-warning-5a2e1a505ea8
platform :ios, '13.6'
workspace 'CleanExample'
use_frameworks!
def data_pods
pod 'Firebase/Core', '7.11.0'
pod 'Firebase/Auth', '7.11.0'
pod 'Firebase/Firestore', '7.11.0'
pod 'Firebase/Storage', '7.11.0'
pod 'FirebaseFirestoreSwift', '7.11.0-beta'
end
def presentation_pods
pod 'FirebaseUI/Storage', '10.0.2'
pod 'Firebase/Storage', '7.11.0'
pod 'lottie-ios'
end
target 'CleanExample' do
project 'CleanExample'
presentation_pods
data_pods
end
target 'PresentationCleanExample' do
project 'PresentationCleanExample/PresentationCleanExample.xcodeproj'
presentation_pods
end
target 'DomainCleanExample' do
project 'DomainCleanExample/DomainCleanExample.xcodeproj'
end
target 'DataCleanExample' do
project 'DataCleanExample/DataCleanExample.xcodeproj'
data_pods
end
post_install do |installer|
removeOTHERLDFLAGS(['PresentationCleanExample', 'DataCleanExample'], installer)
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
end
end
end
def removeOTHERLDFLAGS(target_names, installer)
pods_targets_names = target_names.map{ |str| 'Pods-' + str }
handle_app_targets(pods_targets_names, 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 handle_app_targets(names, installer)
puts "handle_app_targets"
puts "names: #{names}"
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 = ""
new_xcconfig = xcconfig.sub(old_line, new_line)
File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
end
end
end
I've uploaded the code https://github.com/rchampa/CleanExample