【问题标题】:How to change $(PRODUCT_BUNDLE_IDENTIFIER) in Xcode?如何在 Xcode 中更改 $(PRODUCT_BUNDLE_IDENTIFIER)?
【发布时间】:2019-06-27 14:55:44
【问题描述】:

我正在使用不同的 Firebase 环境(开发和生产)构建不同风格的 Flutter 应用程序。我需要在 Xcode for iOS 应用程序中为开发和生产设置不同的包 ID。

我使用方案来配置不同的风格(在构建设置中,我为每个配置添加环境值)。

但我对更改 $(PRODUCT_BUNDLE_IDENTIFIER) 有很大的疑问。我需要将后缀 .development 添加到普通应用 id 以获取开发应用 id。

我尝试关注this method(使用用户定义的设置)并更改info.plist 以从用户定义的设置中获取变量,但它不起作用。

错误是:

操作无法完成。应用 FrontBoard 不知道“$(EXAMPLE_BUNDLE_ID)”。

因此,当传入用户定义的设置时,它似乎插值不正确。

我也尝试过添加默认PRODUCT_BUNDLE_IDENTIFIER 和用户定义设置的混合方法。例如:com.example.app$(EXAMPLE_BUNDLE_ID) 其中EXAMPLE_BUNDLE_ID = .development

我还尝试参考用户定义设置$(EXAMPLE_BUNDLE_ID),将其直接添加到“身份”下的“目标常规”选项卡中的“捆绑标识符”中。但这随后更改为:-- EXAMPLE_BUNDLE_ID-

我还尝试在info.plist 中使用$(PRODUCT_BUNDLE_IDENTIFIER)$(EXAMPLE_BUNDLE_ID) 作为捆绑标识符值。但这给出了类似的错误:

操作无法完成。应用 FrontBoard 不知道“com.example.app$(EXAMPLE_BUNDLE_ID)”。

这看起来像插值问题。

有人知道解决方案吗?我已经看了但找不到答案。

这对 android 来说很容易,因为只需在 productFlavors 中使用 applicationIdSuffix ".development”。但我无法为 Xcode 找到这样的方法。

【问题讨论】:

    标签: ios xcode firebase flutter android-productflavors


    【解决方案1】:

    您是否需要使用不同的package name (Android) 和bundle id (iOS),因为您需要使用Firebase Auth 插件?

    在这种情况下,对于 iOS 项目,您应该考虑使用 PlistBuddy,您可以将其设置为在您的 XCode build phases 中添加一个 Run Script,就像这样

    if [ "${CONFIGURATION}" = "Debug" ]; then
    /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.developmento.appName" "$PROJECT_DIR/Runner/Info.plist"
    echo "Changed bundle id for developement $PROJECT_DIR/Runner/Info.plist"
    else
    echo "Nothing to do"
    fi
    

    无论如何,如果你不使用Firebase Auth,你可以在不同的firebase项目中拥有相同的bundle id。

    如果您需要在 staging 和 production 之间区分 firebase 项目文件,您可以在这里查看:

    How to choose between development and production firebase project based on build flavours?

    更新

    所以跟随 OP 聊天,知道他在关注这个 tutorial 来设置 flutter flavors 我已经尝试自己看看我们卡在哪里了。

    起点如下:

    • 两个 Firebase project
    • 使用Firebase Auth模块(所以项目之间需要改变bundle id)
    • 当然还有两个不同的GoogleService-Info.plist

    我首先将 Xcode bundle idGoogleService-Info.plist 设置为生产(只是一个选项)

    然后我将 GoogleServices-Info-staging.plistGoogleServices-Info-production.plist 都保存在我的 ios/Runner 文件夹中

    然后我在 Compile Sources 的脚本之前设置这个构建脚本

    # Type a script or drag a script file from your workspace to insert its path.
    if [ "${CONFIGURATION}" == "Debug" ] || [ "${CONFIGURATION}" == "Debug-Runner-staging" ]; then 
    
    echo "Setting up staging firebase environment"
    /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.staging.flutterAppAuthFlavours" "${PROJECT_DIR}/Runner/Info.plist"
    cp -r "${PROJECT_DIR}/Runner/GoogleService-Info-staging.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist" 
    echo "$(date) staging flavour - Configuration: ${CONFIGURATION}" > "${PROJECT_DIR}/environment.txt"
    
    elif [ "${CONFIGURATION}" == "Debug-Runner-production" ]; then 
    
    echo "Setting up production firebase environment"
    /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.example.flutterAppAuthFlavours" "${PROJECT_DIR}/Runner/Info.plist" 
    cp -r "${PROJECT_DIR}/Runner/GoogleService-Info-production.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
    echo "$(date) production flavour - Configuration:  ${CONFIGURATION}" > "${PROJECT_DIR}/environment.txt"
    
    fi
    

    我叫它Setup Firebase Environment(你可以随便叫它)

    此脚本还将一些日志(带有时间戳)存储在 ios 文件夹内名为 environment.txt 的文件中,以便轻松检查 xcode 构建完成了什么

    现在关于SchemesBuild Configurations

    我已经完成了两个 Build Configuration,它们与我的Debug Build Configuration 完全相同,我称它们为

    • Debug-Runner-staging
    • Debug-Runner-production

    经验法则是将构建配置命名为'Debug-<your flavor>',并且您需要为您拥有的每一种风格制定一个方案,所以我有这些:

    • Runner-staging 其 Run 调用 Debug-Runner-staging 构建配置
    • Runner-production 其 Run 调用 Debug-Runner-production 构建配置

    所以现在如果我打电话给flutter run --flavor Debug-staging,我有一个在我的 staging firebase 项目上运行的构建。

    如果我打电话给flutter run --flavor Debug-production,我有一个在我的生产 firebase 项目上运行的构建。

    更新 2

    为了完整起见,您也可以在此处更改捆绑包 ID:

    无论如何,似乎有一个奇怪的行为,一旦你第二次构建flavourflutter 命令正确构建风味但运行previos 构建风味

    随着使用XCode 构建并使用方案切换,所有工作都按预期工作(即使是正确的应用程序的运行)我猜这可能是一个颤动的命令问题。所以我建议你尝试提交一个问题here 也链接这个 SO 问题/答案。

    更新 3

    经过一点英特尔,我发现flutter tools 在构建项目之前设置了应用程序启动环境。因此,当我们第一次在Info.plist 中更改CFBundleIdentifier 时,第二次启动flutter run 时,它会采用先前修改的值并尝试启动此捆绑ID,而在构建期间我们正在更改它,因为我们正在构建一个不同的变体。

    一种可能的解决方案是启动一个脚本,在调用fluetter run 之前更改Info.plist 中的CFBundleIdentifier

    例如,从 Info.plist 开始,生产捆绑包 id 为 com.example.flutterAppAuthFlavours,我们可以这样做

    这里我使用sed 命令只是为了想不同,但您可以在调用flutter run 之前调用我们下面的PlistBuddy 进行更改。

    【讨论】:

    • 感谢您的回复!是的,因为我使用Firebase Auth 进行谷歌登录。我尝试过你建议使用PlistBuddy,但仍然无法正常工作。如果离开构建脚本最后得到错误:The project's Bundle ID is inconsistent with either the Bundle ID in 'GoogleService-Info.plist’, or the Bundle ID in the options if you are using a customized options 我检查了GoogleService-Info.plist,它有正确的 Bundle ID。我还检查了 Xcode,它有正确的包 ID。所以我很困惑。 Xcode info.plist 中的 Bundle ID 与 GoogleService-Info.plist 中的 Bundle ID 匹配,但有此错误消息。
    • 感谢更新!但仍然有问题和奇怪的行为。也许这可以解释一些事情。例如,当运行flutter run --flavor development 然后退出并运行flutter run --flavor production 时,它会构建正确的应用程序但打开错误的应用程序。也许这就是我得到错误的原因:The project's Bundle ID is inconsistent with either the Bundle ID in 'GoogleService-Info.plist’?也许我们更改捆绑包 ID 的方式有问题?
    • @FlutterFirebase 如果您遵循我的指南并遵循我的道路,一切正常。如您所见,我亲自对其进行了测试。没有错误的人。检查您的设置并放置日志。尽量按照我的例子做。
    • 谢谢。我严格按照。它有时工作没有错误!但是当做更多run 它在构建后打开错误的应用程序。尝试更改不同捆绑包的应用名称以便查看。
    • @FlutterFirebase 真的吗?尝试在 flutter run 之前执行 flutter cleanflutter stop
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 2015-11-24
    • 1970-01-01
    相关资源
    最近更新 更多