1) 给你的项目添加一个新的目标,类型为“Aggregate”,例如你可以将其命名为“Update Info.plist Prefix Header”,只需在对话框中将其用作“Product Name”即可。
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应用程序的Build Phases。
5) 将之前创建的聚合目标添加为依赖目标(将其添加到“Target Dependencies”中)。这意味着Xcode在构建iOS目标之前始终会首先构建此目标。
6) 打开您的iOS应用程序的Build Settings。
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文件,然后在将其复制到应用程序之前,它将通过C预处理器(使用PCH文件作为前缀头)运行Info.plist文件。预处理器将替换SVN_REVISION,因为它在您的PCH文件中定义为宏。
重要提示
有些人可能认为使用$(DERIVED_FILE_DIR)
而不是$(CONFIGURATION_TEMP_DIR)
是一个更好的想法。理论上,他们是正确的,但实际上存在一个问题:派生文件目录对于每个目标都不同,而配置临时目录是相同的(它仅对每个构建配置不同)。当使用派生文件目录时,PCH文件被写入聚合目标的派生文件目录中,但是在构建iOS应用程序时,Xcode将在iOS应用程序的派生文件目录中搜索此文件,因此它将无法找到该文件。
有些人可能也认为只需将更新前缀头的Run Script阶段作为您的iOS应用程序的第一个构建阶段而不是创建单独的目标会更好(这也将解决上述派生文件目录问题)。在理论上很好的想法,在实践中却行不通:如果要求预处理,则Info.plist在执行第一个脚本阶段之前就已被预处理了,因此如果PCH文件不存在或尚未更新,则构建将以错误终止或过时的SVN版本将写入plist文件。这就是为什么需要一个单独的目标来完成这项任务,并保证在实际目标之前进行构建。