如何使用 cocoapods 避免多项目工作区中类的重复

How to avoid duplication of clases in a multiproject workspace using cocoapods

我在业余时间做一个应用,想问你一个问题,我的工作区有3个子项目:presentation、domain和data,每个都是静态框架,有自己的pods,一切都很酷,但现在我有一个问题,我不知道如何解决。我有几个 firebase 依赖项,其中一些必须在 Presentation 中,其他必须在 Data 中,执行时会出现问题,因为它给我一个错误:

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.

所以我在 FirebaseUI/Storage 的 podspec 中看到的是以下内容: 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'

这让我觉得 cocoapods 没有正确解决依赖关系 Firebase/Storage。

问题是,这只是我从 Firebase 获得的数千个重复的 class 中的一个,用于遵循上图。 我想有一种方法可以只注入一次 Firebase 依赖项,从而避免 class 重复,但我不知道怎么做。

我的播客文件:

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

我已经上传了代码https://github.com/rchampa/CleanExample

问题

最后我解决了这个问题 post https://medium.com/@GalvinLi/tinysolution-fix-cocoapods-duplicate-implement-warning-5a2e1a505ea8 因为它让我理解了问题。

如果我没理解错的话OTHER_LDFLAGS 正在重复添加框架。

然后为了避免原始消息问题Class *** is implemented in both我在目标'CleanExample'中安装所有pods并从以下文件中删除OTHER_LDFLAGS行。

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

播客文件

# 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

我已经上传了代码https://github.com/rchampa/CleanExample