28

显然文件被缓存了,所以它只有在它被改变时才会被构建。我设置了环境变量来增加我的版本号,等等,并独立于 plist 更新它们(实际上是在项目构建设置中)。是否有一个脚本可以用作脚本构建阶段来强制 Info.plist 更新?还有什么方便的方法?

4

10 回答 10

20

选择“编辑方案”,然后从左侧的控件中选择“构建”。

然后,添加一个 Pre-actions 步骤,确保在“Provide build settings from”下拉菜单中选择了相关方案,然后将其添加到下面的编辑窗口中:

rm "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"

这将删除 的缓存版本Info.plist,导致 XCode 在您每次点击 build 时重新构建它。

或者,如果您让 Xcode 预处理模板 Info.plist 文件,只需使用

touch ${PROJECT_DIR}/${INFOPLIST_FILE}

也可以。

调试预操作脚本

当您犯错时,预操作步骤不会提供任何信息。您可以通过将此行添加到脚本来调试构建变量的使用

echo "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}" > ~/debug.txt

然后检查 的内容~/debug.txt以验证预操作脚本是否已运行,并查看您是否使用了正确的路径。

于 2013-09-05T13:42:36.303 回答
16

我也自动设置了我的版本号。我创建了一个运行脚本构建阶段。关键是更新Info.plist的目标构建目录副本而不是构建目录之一。您还需要在复制捆绑阶段之后拥有运行脚本。可以直接编辑捆绑文件,因为在代码签名之前。您不想生成重新发明轮子的文件。

这是我的脚本:

# ---------------------------- IMPORTANT ----------------------------
# You must set GITHash to something like 'Set by build script' in the file
# file '<Project Name>-Info.plist' in the 'Supporting Files' group
# -------------------------------------------------------------------
#
# Get the version number from the tag in git and the number of commits as the build number
#
appVersion=$(git describe --long | cut -f 1 -d "-") 
appBuild=$(git describe --long | cut -f 2 -d "-") 
gitHash=$(git describe --long | cut -f 3 -d "-")
echo "From GIT Version = $appVersion Build = $appBuild"

#
# Set the version info in plist file
#
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $appVersion" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :GITHash $gitHash" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
echo "Updated ${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"

仅供参考,我还使用以下代码自动设置版本并在 About 选项卡上构建

NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *appDisplayName = infoDictionary[@"CFBundleDisplayName"];
NSString *majorVersion = infoDictionary[@"CFBundleShortVersionString"];
NSString *minorVersion = infoDictionary[@"CFBundleVersion"];

self.appDescription.text = [NSString stringWithFormat:@"Dirty Dog Software\n%@\nVersion: %@(%@)",
                       appDisplayName, majorVersion, minorVersion];                           
于 2013-05-02T07:16:36.687 回答
12

您可以尝试使用touch命令来更新时间戳,我认为这是 Xcode 用来确定是否应该重建它的,例如

$ touch Info.plist
于 2010-09-16T19:50:18.930 回答
9

一种方法是让运行脚本构建阶段Info.plistInfo.plist.template文件生成,然后rm Info.plist在创建包之后。来自Dave DeLong在他的博客上发表的评论想法。

如果缓存非常严重(即缓存,即使您没有在文件历史记录中打开 Info.plist),您可能也希望rm在此脚本中缓存版本。

于 2011-02-28T23:51:58.977 回答
5

在 Xcode 4 中,您可以使用预构建操作来触摸 info plist。

注意:这与运行脚本构建阶段不同。预构建操作发生在 Xcode 检查信息 plist 之前,运行脚本构建阶段似乎发生在 Xcode 已经检查过信息 plist 之后(这就是为什么它只每隔一次工作一次)。

  1. 转到编辑方案 > 构建 > 预操作
  2. 单击“+”按钮并选择“新建运行脚本操作”
  3. 在“提供构建设置来自”下拉列表中选择您的目标
  4. touch "${SRCROOT}/${INFOPLIST_FILE}"在脚本框中添加
于 2012-07-18T16:44:28.393 回答
1

在目标的“获取信息”窗口的“构建”选项卡中有一个选项,在“打包”标记为“预处理 Info.plist 文件”的下方,您可以检查该选项。我相信每次构建都会更新文件。

于 2010-09-16T20:05:46.160 回答
1

使用 Xcode 8.3.2

受到@LeeH 2013 年回答的启发,我想出了两个解决方案来重建 Info.plist。

解决方案一:最简单优雅

最简单的解决方案是通过触摸您的目标来强制 Xcode 读取您的自定义变量Info.plist

添加构建阶段,请参见下面的屏幕截图(最初为解决方案 2截图),然后添加以下行:

touch $INFOPLIST_FILE

就这些!现在 Xcode 应该强制将您的自定义变量重新加载到Info.plist文件中。

此解决方案与@lukelutman 建议的相同,但使用构建阶段。预操作脚本对我不起作用。

解决方案 2:更复杂和 hacky

另一种解决方案是删除构建目录中的缓存Info.plist

我写了这个超级简单的小 bash 脚本

#!/bin/bash
info_plist="$CONFIGURATION_BUILD_DIR/$PRODUCT_NAME.app/Info.plist"
echo "Removing Info.plist from build dir in order to force rebuild of it and reading of correct xcconfig variables, plist path $info_plist"
rm "$info_plist"

然后我保存它并从目标的构建阶段调用它。我把它作为第一个构建阶段。

在此处输入图像描述

背景:

我有三种不同的配置:ConfigAlphaAppStore我正在使用通用链接、推送通知和其他需要使用权利文件的东西。但我不想拥有三个授权文件,每个配置一个。

我的项目已经严重依赖配置文件 ( .xcconfig)。MyAppsProductName.entitlements我实际上使用自定义配置变量设置了权利文件 ( )。

但是我想在运行时读取相同的配置变量,我想如果将它们添加到我的目标 Info.plist 中,我可以做到这一点。哪个有效!

但我注意到,当我更改.xcconfig文件中的值时,Info.plist文件并没有更改值。我注意到,如果我执行了一个干净的构建,那么Info.plist得到的值会根据.xcconfig文件中的值进行更新。Xcode 确实缓存了Info.plist文件。

所以上面的这些解决方案解决了这个问题。希望能帮助到你!:)

讨论

我不知道解决方案 2是否比解决方案 1有任何优势……可能不是?任何输入任何人?

于 2017-08-24T12:40:14.650 回答
0

确保您还刷新了 plist 的视图。
在 Xcode 中查看 plist 时,只需单击 plist 中根元素旁边的显示三角形 ( Information Property List)。然后再次单击它以展开它。
您会看到这些值已被刷新。我正在运行一个类似的脚本,并认为它只是间歇性地工作,直到我意识到 plist 视图根本没有刷新。

于 2011-07-17T02:06:23.743 回答
0

另一种方法是创建一个只有构建阶段的“聚合”目标。使用它来触摸 Info.plist 文件。使该目标成为构建您的应用程序的目标的依赖项。

因为它是一个单独的目标并且是您的应用目标的依赖项,所以它甚至会在您的应用目标的 Info.plist 文件被检查之前构建。(如其他地方所述,应用程序目标本身的构建阶段发生得太晚,在 Info.plist 文件的修改时间已经检查过之后。)

于 2013-04-29T19:58:13.840 回答
0

对于那些难以让项目进行自动版本控制的人,我创建了一个macOS GitHub 项目,该项目演示了如何以一种非常简单、直接的方式实现它,这要感谢 @GayleDDS 和 Daniel Farrelly 的想法以及他关于版本控制和我自己的一些实现。我认为您可以毫不费力地将其翻译到您在其他平台上的项目中。

这是一个关于如何在项目中复制它的小指南(Xcode 8)。

  1. 为减少您出错的机会,请确保您已事先将所有目标添加到您的项目中。
  2. 转到菜单File > New File...然后向下滚动并选择Configuration Settings File
  3. 命名它BuildNumber并且不要忘记将此配置文件添加到您想要保持同步的所有目标;通过在保存此文件之前单击相应的复选框来执行此操作
  4. 您应该会在项目中看到一个名为BuildNumber.xcconfigshow up的文件
  5. 将以下文本添加到此文件:CURRENT_PROJECT_VERSION = 1. 如果你愿意,你可以从另一个号码开始。这将是您的内部版本号,每次构建时都会增加。但是,请不要更改变量的名称
  6. 如果您有多个目标,请将以下脚本添加到通过导航到Project > Target > Build Phases 构建的第一个目标
  7. 导航到菜单编辑器 > 添加构建阶段 > 添加运行脚本阶段
  8. 一个运行脚本阶段应该已经添加到您的目标中;所以将它拖到目标依赖项下(这个细节很重要!)。
  9. 现在是有趣的部分,我将几乎逐行解释脚本:

首先在脚本的第一行创建 PlistBuddy 的路径:

plistbuddy="/usr/libexec/PlistBuddy"

添加第 2 行以读取配置文件,然后读取您在步骤 5 中设置的 CURRENT_PROJECT_VERSION 变量。

OLD_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print $3 }'`

第 3-11 行使用增加的值设置 NEW_VERSION,然后使用新的内部版本号保存配置文件;剩下的几行是将营销版本和内部版本号保存到 plist 中:

NEW_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print $3 + 1 }'`
sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $NEW_VERSION/" "$SRCROOT/BuildNumber.xcconfig"
CURRENT_PROJECT_VERSION=$NEW_VERSION
BUILD_STR="Build $NEW_VERSION"
COPYRIGHT_STR="© 2017 MyCompany.net"
APP_VERSION_STR="1.3.5"
$plistbuddy -c "Set :CFBundleShortVersionString $APP_VERSION_STR" "${SRCROOT}/$TARGETNAME/Info.plist"
$plistbuddy -c "Set :CFBundleVersion $BUILD_STR" "${SRCROOT}/$EXECUTABLE_NAME/Info.plist"
$plistbuddy -c "Set :NSHumanReadableCopyright $COPYRIGHT_STR" "$INFOPLIST_FILE"

我还在第 8-11 行展示了如何使用 Xcode 为其脚本设置的不同环境变量。您可以添加额外的行来编辑其他目标的 info.plist,然后保持主应用程序的版本及其助手同步。转到GitHub,下载项目并使用它,然后根据您的需要进行调整。使用 Xcode 进行愉快的自动版本控制。

于 2017-01-07T20:45:52.760 回答