3

我开发了一个 iOS 项目,它是一个处理不同服务器的类库。每个使用该库的应用程序只需要一台服务器。服务器类型可在编译时通过预处理器定义进行配置。

在我的库的 podspec 中,我为每个服务器定义了各种子规范,如下所示:

s.name = "ServerLib"
[...]
s.subspec 'ServerA' do |a|
    a.source_files = 'Classes/A/**/*.{h,m}'
    a.xcconfig = { "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) ServerA=1" }
end

s.subspec 'ServerB' do |b|
    b.source_files = 'Classes/B/**/*.{h,m}'
    b.xcconfig = { "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) ServerB=1" }
end

我的应用程序是一个多客户应用程序,每个客户有一个目标。每个客户都使用图书馆项目中的特定服务器。所以,我的 Podfile 看起来像这样:

platform :ios, '5.0'

pod 'MyCore'
pod '3rdPartyLib'

target :'Customer1', :exclusive => true do
    pod 'ServerLib/ServerA'
end

target :'Customer2', :exclusive => true do
    pod 'ServerLib/ServerB'
end

pod install脚本的作用是将子规范中定义的所有标志合并为每个 pod-customerN.xcconfig 文件中的一个值

GCC_PREPROCESSOR_DEFINITIONS = $(inherited) 3RD_PARTY_FLAGS $(inherited) ServerA=1 $(inherited) ServerB=1

有什么建议可以规避 Cocoapods 的这种错误(?)行为吗?据我了解文档,子规范属性应该只继承其父规范而不是同级子规范。

4

1 回答 1

2

找到了一种解决方法,可能不是那么优雅:

由于pod install将所有编译器标志合并为一个,我不得不GCC_PREPROCESSOR_DEFINITIONS从库的podspec文件中删除 。但是如果没有这个定义,我的库就无法构建。

在 Xcode 中,这可以通过将定义添加到每个库的目标来轻松解决。但是当我在应用程序中使用我的库时,Pods 项目是根据不包含所需标志的 Podspec 生成的。

解决方案是使用post_install应用程序的 Podfile 中的钩子来操作 Pods 项目生成的 xcconfig。

post_install do |installer|

    file_names = ['./Pods/Pods-ServerA.xcconfig',
                  './Pods/Pods-ServerB.xcconfig']

    # rename existing pre-processor definitions
    file_names.each do |file_name|
        text = File.read(file_name)
        File.open(file_name, 'w') { |f| f.puts text.gsub(/GCC_PREPROCESSOR_DEFINITIONS/, "GCC_PREPROCESSOR_DEFINITIONS_SHARED")}
    end

    # merge existing and required definition for ServerA
    File.open('./Pods/Pods-ServerA.xcconfig', 'a') { |f|
        f.puts "\nGCC_PREPROCESSOR_DEFINITIONS=$(GCC_PREPROCESSOR_DEFINITIONS_SHARED) ServerA=1"
    }

    # merge existing and required definition for ServerB
    File.open('./Pods/Pods-ServerB.xcconfig', 'b') { |f|
        f.puts "\nGCC_PREPROCESSOR_DEFINITIONS=$(GCC_PREPROCESSOR_DEFINITIONS_SHARED) ServerB=1"
    }

end

代码有点冗长,因为我不熟悉 Ruby,但它可以工作。只要变量和库遵循命名方案,就应该很容易自动化这个重命名附加过程。

于 2013-09-24T09:15:55.817 回答