在自定义 .plist 文件中使用用户定义的构建设置

Posted

技术标签:

【中文标题】在自定义 .plist 文件中使用用户定义的构建设置【英文标题】:Use User-Defined build settings in custom .plist file 【发布时间】:2016-03-08 03:12:00 【问题描述】:

我为我的应用定义了不同的构建配置(Debug、Stage、Prod)并且我使用用户定义的构建设置:

Info.plist 文件中设置 Facebook 登录和其他内容:

在这种情况下,$(USER_DEFINED_SETTINGS) 表示法确实有效。

当我尝试设置 Google SignIn 时,需要使用额外的 .plist 文件 (GoogleService-Info.plist),并且我使用了 User-Defined 设置我在Info.plist 文件中的方式,它不起作用。

如何在自定义.plist 文件中使用用户定义设置?如果我不能,我该如何解决这个问题?

【问题讨论】:

检查 xcconfig 功能。也许它可以帮助***.com/questions/38328837/… 【参考方案1】:

不能自定义 .plist 文件中使用用户定义设置。

但是您可以在构建应用程序时将自定义 .plist 文件复制到正确的位置:

    创建一个新文件夹(例如:Resources/GoogleServiceInfoPlists)。

    复制所有 .plist 文件以进行构建配置。例如:

    GoogleService-Info-Debug.plist

    GoogleService-Info-Stage.plist

    GoogleService-Info-Prod.plist

    添加新的Run Script Phase - Xcode:Target-->Build Phases-->“+”按钮(左上角)。

    使用以下脚本将给定构建配置的 .plist 文件复制(替换)到项目目录:

    cp "$SRCROOT/$PRODUCT_NAME/Resources/GoogleServiceInfoPlists/GoogleService-Info-$CONFIGURATION.plist" "$SRCROOT/$PRODUCT_NAME/GoogleService-Info.plist"
    

    在输出文件下,您还应该输入目标文件,以确保只有在文件被实际复制时才开始下一阶段。

    "$SRCROOT/$PRODUCT_NAME/GoogleService-Info.plist"
    

    重要提示:移动新添加的脚本之前 Copy Bundle Resources 阶段,否则将使用默认文件,忽略替换文件。

使用的变量/路径:

$SRCROOT - 预定义,它指向您的项目位置。

$PRODUCT_NAME - 预定义,产品名称。

$CONFIGURATION - 预定义,这是您的构建配置。默认为:DebugRelease。就我而言:DebugStageProd。您可以在 Xcode 中更改构建配置:Project(不是 Target!)-->Info

注意:

GoogleService-Info.plist 文件必须添加到 Xcode 项目资源(Build Phases-->Copy Bundle Resources),而 Resources/GoogleServiceInfoPlists/GoogleService-Info-* 文件不一定。

如果上述方法不起作用,请尝试单击您不想要的 .plist 文件 > 文件检查器 > 目标成员 > 检查您的主项目,以便在最终输出中将其捆绑在一起。

【讨论】:

+1 虽然我不喜欢解决方案本身,但我找不到任何其他方法来实现它。 Google 至少应该提供通过 API 更改跟踪标识符的方法(而不是自己修改 .plist)。 我认为您可以在自定义 plist 中使用 $USER_DEFINED_SETTINGS ,但在您项目的 Info.plist 中,但我还没有尝试过。 当然可以,但是 Google 登录需要单独的(自定义).plist 文件。 @howly 我的存储库中有 4 个文件GoogleService-Info.plist,我的回答中提到了这 3 个文件。 GoogleService-Info.plist 被其中的 1 个替换(不仅仅是复制),所以 Xcode 不会抱怨它。 @pixelfreak,您是否尝试过单击并拖动构建阶段以确保在文件链接之前进行复制?【参考方案2】:

    创建一个新文件夹(例如:GoogleServiceInfoPlists)。

    复制每个配置的所有.plist文件

例如:

GoogleService-Info-Debug.plist, 
GoogleService-Info-Alpha.plist,
GoogleService-Info-Beta.plist,
GoogleService-Info-Release.plist

    最后添加新的Run Script Phase(Xcode:目标 -> 构建阶段 -> “+”按钮)。

    使用下面的脚本将给定环境的.plist文件复制到构建目录。

脚本:

RESOURCE_PATH=$SRCROOT/$PRODUCT_NAME/GoogleServiceInfoPlists/GoogleService-Info-$CONFIGURATION.plist

BUILD_APP_DIR=$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app

echo "Copying $RESOURCE_PATH to $BUILD_APP_DIR"
cp "$RESOURCE_PATH" "$BUILD_APP_DIR/GoogleService-Info.plist"

PS:您不需要将文件添加到项目中。只需在主目录中创建一个新文件夹即可。

【讨论】:

@Cleversou 我得到了这个问题Could not locate configuration file: 'GoogleService-Info.plist'.你在使用新的构建设置吗? @smj2393 尝试单击您不想要的 .plist 文件 > 文件检查器 > 目标成员 > 检查您的主项目,以便在最终输出中将其捆绑在一起。【参考方案3】:

其实还有更好的解决方案。

您可以使用my swift script 手动替换环境变量(包括用户定义的)。

它有两个参数:输入和输出路径。递归遍历所有输入 plist 值(如果您需要也可以添加要处理的 dict 键),并替换它找到的所有 Env 变量。并写入输出路径。

这就是你在Run script phase 中使用它的方式:

/usr/bin/xcrun --sdk macosx swift "$PROJECT_DIR/scripts/replacePlistEnvironmentVariables.swift"  "$PROJECT_DIR/GoogleService-Info.plist" "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app/GoogleService-Info.plist"

【讨论】:

【参考方案4】:

我将两个具有(相同)名称的文件 GoogleService-Info.plist 放入我的项目中。

一个在根目录,一个在名为'staging'的文件夹中,以避免文件系统中的命名冲突。

将一个目标包含在一个目标中,另一个包含在另一个目标中,这样每个目标都有一个具有正确名称的唯一 plist 文件。

【讨论】:

以上是关于在自定义 .plist 文件中使用用户定义的构建设置的主要内容,如果未能解决你的问题,请参考以下文章

运行时分配操作的快捷方式不会在自定义组件中触发

Flutter NSException:配置失败。可能是由于 GoogleService-Info.plist 中的 GOOGLE_APP_ID 无效或在自定义选项中设置造成的

如何将自定义数组保存/重新加载到 plist

如何在自定义 Xcode 项目模板中创建或定义新目标

在 IBAction 中获取 indexPath.row?

在自定义中从 TextField 中关闭键盘