如何在Cocoapod子规范中定义不同的xcconfig参数?

时间:2013-03-27 09:08:02

标签: objective-c configuration-management cocoapods xcconfig

我开发了一个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错误(?)行为的任何建议?据我了解文档,subspec属性应仅从其父规范继承而不是同级别的子规范。

1 个答案:

答案 0 :(得分:2)

找到一种解决方法,也许不那么优雅:

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

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

解决方案是使用应用程序的Podfile中的post_install挂钩来操作生成的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,但它有效。只要变量和库遵循命名方案,就可以轻松地自动执行此重命名附加过程。