如何使用 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
问题
是不是FirebaseStorageUI.podspec文件有问题或者
是可可的限制pods?
我的 Podfile 是不是错了?
最后我解决了这个问题 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
我在业余时间做一个应用,想问你一个问题,我的工作区有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
问题
是不是FirebaseStorageUI.podspec文件有问题或者 是可可的限制pods?
我的 Podfile 是不是错了?
最后我解决了这个问题 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