1) 为您的“聚合”类型的项目添加一个新目标,例如,您可以将其命名为“更新 Info.plist Prefix Header”;只需在对话框中将其用作“产品名称”。
2) 使用以下源代码向这个新目标添加一个运行脚本构建阶段:
#!/bin/sh
SVN_REVISION=$(git svn find-rev HEAD)
echo "#define SVN_REVISION $SVN_REVISION" > "$SCRIPT_OUTPUT_FILE_0"
3) 将输出文件添加到您的脚本中,为其命名
$(CONFIGURATION_TEMP_DIR)/InfoPlist.pch
4) 打开 iOS 应用程序的构建阶段。
5)将您之前创建的聚合目标添加为依赖目标(将其添加到“目标依赖项”)。这意味着 Xcode 将始终先构建此目标,然后再构建您的 iOS 目标。
6) 打开 iOS 应用程序的构建设置。
7)搜索设置“Info.plist Preprocessor Prefix File”并将其更改为与步骤(3)中用于输出文件的值完全相同的值。
8) 搜索设置“Preprocess Info.plist File”并确保它已启用。
9) 打开您当前的 Info.plist 文件并将 CFBundleVersion 的值更改为SVN_REVISION
. 不要使用$(SVN_REVISION) 或 ${SVN_REVISION};这不是构建设置或环境变量替换,这是预处理器替换,所以只需使用 SVN_REVISION。
就是这样。每次构建 iOS 应用时,Xcode 首先构建聚合目标,它会更新 PCH 文件,当它构建 iOS 应用时,它会通过 C 预处理器运行 Info.plist 文件(使用 PCH 文件作为前缀header) 在将其复制到您的应用程序之前。预处理器将替换 SVN_REVISION,因为它在您的 PCH 文件中定义为宏。
重要笔记
有些人可能认为使用$(DERIVED_FILE_DIR)
而不是$(CONFIGURATION_TEMP_DIR)
. 好吧,理论上他们是对的,但实际上只有一个问题:每个目标的派生文件目录不同,而配置临时目录是相同的(只是每个构建配置不同)。使用派生文件目录时,PCH 文件被写入聚合目标的派生文件目录,但在构建 iOS 应用程序时,Xcode 会在 iOS 应用程序的派生文件目录中搜索此文件,因此找不到文件。
有些人可能还认为将更新前缀标头的运行脚本阶段添加为 iOS 应用程序的第一个构建阶段而不是为其创建单独的目标是一个更好的主意(这也将解决提到的派生文件目录问题多于)。再一次,理论上的好主意,但在实践中不能工作:如果请求预处理,Info.plist 在第一个脚本阶段甚至执行之前被预处理,所以如果 PCH 文件不存在或尚未更新,要么构建因错误而终止,或者将过时的 SVN 修订版写入 plist 文件。这就是为什么您需要一个单独的目标来保证在您的实际目标之前构建此任务。