3

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.

enter image description here

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

Github

I've uploaded the code https://github.com/rchampa/CleanExample

Questions

  • Is there something wrong with the FirebaseStorageUI.podspec file or is a limitation of cocoapods?

  • Is my Podfile wrong?

Ricardo
  • 7,921
  • 14
  • 64
  • 111

1 Answers1

0

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.

  • Pods-DataCleanExample.debug.xcconfig
  • Pods-DataCleanExample.release.xcconfig
  • Pods-PresentationCleanExample.debug.xcconfig
  • Pods-PresentationCleanExample.release.xcconfig

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

Github

I've uploaded the code https://github.com/rchampa/CleanExample

Ricardo
  • 7,921
  • 14
  • 64
  • 111