如何在 Xcode 中更改 $(PRODUCT_BUNDLE_IDENTIFIER)?

Posted

技术标签:

【中文标题】如何在 Xcode 中更改 $(PRODUCT_BUNDLE_IDENTIFIER)?【英文标题】:How to change $(PRODUCT_BUNDLE_IDENTIFIER) in Xcode? 【发布时间】: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 找到这样的方法。

【问题讨论】:

【参考方案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

以上是关于如何在 Xcode 中更改 $(PRODUCT_BUNDLE_IDENTIFIER)?的主要内容,如果未能解决你的问题,请参考以下文章

当项目中发生更改时,Xcode 如何编译文件?

如何在 Xcode 中更改 PDFView 注释背景颜色?

Xcode:如何在应用程序中一次更改所有字体?

如何在 Xcode 中更改 Git 的用户名?

如何在 Xcode swift 中更改图片方向

如何在 Xcode 4 中更改 Localizable.strings 文件的文本编码?