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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54506458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 10:54:03  来源:igfitidea点击:

How to change $(PRODUCT_BUNDLE_IDENTIFIER) in Xcode?

iosxcodefirebaseflutterandroid-productflavors

提问by FlutterFirebase

I am build different flavor of Flutter app with different Firebase environment (development and production). I need set different bundle ID for development and production in Xcode for iOS apps.

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

I am use schemes to configure the different flavor (in Build Settings I add environment value for every configuration).

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

But I have big issue with change $(PRODUCT_BUNDLE_IDENTIFIER). I need add suffix .developmentto normal app id for development app id.

但是我对 change 有很大的问题$(PRODUCT_BUNDLE_IDENTIFIER)。我需要.development为开发应用程序 id添加后缀到普通应用程序 id。

I have try follow this method(use User Defined Settings) and change info.plistto get variable from User Defined Settings but it not work.

我尝试遵循此方法(使用用户定义的设置)并更改info.plist为从用户定义的设置中获取变量,但它不起作用。

Error is:

错误是:

The operation couldn't be completed. Application “$(EXAMPLE_BUNDLE_ID)" is unknown to FrontBoard.

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

So it seem when pass in User Defined Setting it is not interpolate correct.

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

I have also try mix method of add default PRODUCT_BUNDLE_IDENTIFIERand User Defined Settings. For example: com.example.app$(EXAMPLE_BUNDLE_ID)where EXAMPLE_BUNDLE_ID= .development

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

I also try reference User Defined Setting $(EXAMPLE_BUNDLE_ID)by direct add it to Bundle Identifier in Target General tab under ‘Identity'. But this then change to : -- EXAMPLE_BUNDLE_ID-

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

I have also try in info.plistuse $(PRODUCT_BUNDLE_IDENTIFIER)$(EXAMPLE_BUNDLE_ID)for Bundle Identifier value. But this give similar error:

我也尝试info.plist使用$(PRODUCT_BUNDLE_IDENTIFIER)$(EXAMPLE_BUNDLE_ID)Bundle Identifier 值。但这给出了类似的错误:

The operation couldn't be completed. Application “com.example.app$(EXAMPLE_BUNDLE_ID)" is unknown to FrontBoard.

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

Again this look like interpolation issue.

这再次看起来像插值问题。

Anyone know solution? I have look but cannot find answer.

有谁知道解决办法?我看过了,但找不到答案。

This easy for android because just use applicationIdSuffix ".development”in productFlavors. But I cannot find way like this for Xcode.

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

回答by shadowsheep

Do you need to have different package name(Android) and bundle id(iOS) because you need to use Firebase Authplugin?

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

In this case for iOS project you shold consider using PlistBuddyand you could set it adding a Run Scriptin your XCode build phaseslike that

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

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

enter image description here

enter image description here

Anyway if you don't use Firebase Auth, you can have the same bundle id in different firebase projects.

无论如何,如果您不使用Firebase Auth,则可以在不同的 firebase 项目中使用相同的包 ID。

If you need then to differenziate firebase projects file between staging and production, you could have a look here:

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

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

如何根据构建风格在开发和生产 Firebase 项目之间进行选择?

UPDATE

更新

So following OP chat, knowing that he's following this tutorialto setup flutter flavorsI've tryed myself to see where we were stuck.

因此,在 OP 聊天之后,知道他正在按照本教程进行设置,flutter flavors我已经尝试自己查看我们遇到的问题。

Starting point is the following:

起点如下:

  • TwoFirebase project
  • Use of Firebase Authmodule (so the need to change the bundle id between projects)
  • And of course two different GoogleService-Info.plist
  • Firebase project
  • Firebase Auth模块的使用(所以需要在项目之间更改bundle id)
  • 当然还有两个不同的 GoogleService-Info.plist

I start with Xcode bundle idand GoogleService-Info.plistset to production (just an option)

我从 Xcode 开始bundle idGoogleService-Info.plist设置为生产(只是一个选项)

enter image description here

enter image description here

Then I've save both GoogleServices-Info-staging.plistand GoogleServices-Info-production.plistsave in my ios/Runner folder

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

enter image description here

enter image description here

Then I setup this build script before the script for Compile Sources

然后我在脚本之前设置了这个构建脚本 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

And I called it Setup Firebase Environment(you can call it what you want)

我叫它Setup Firebase Environment(你可以随心所欲地称呼它)

enter image description here

enter image description here

This script store also some logs (with timestamp) in a file called environment.txtinside iosfolder in order to easy check what xcode build has done

该脚本还将一些日志(带时间戳)存储在一个名为environment.txtinsideios文件夹的文件中,以便轻松检查 xcode 构建已完成的操作

enter image description here

enter image description here

And now about Schemesand Build Configurations:

现在关于SchemesBuild Configurations

I've done twoBuild Configurationthat are the exact copy of my Debug Build Configurationand I called them

我做了两个Build Configuration完全相同的副本,我Debug Build Configuration打电话给他们

enter image description here

enter image description here

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

The rule of thumb is to name the build configurations as 'Debug-<your flavor>'and you need to have a scheme for every flavorsyou have, so I have these:

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

  • Runner-stagingwhose Run calls Debug-Runner-stagingbuild configuration
  • Runner-productionwhose Run calls Debug-Runner-productionbuild configuration
  • Runner-staging其 Run 调用Debug-Runner-staging构建配置
  • Runner-production其 Run 调用Debug-Runner-production构建配置

enter image description here

enter image description here

enter image description here

enter image description here

So now if I call flutter run --flavor Debug-stagingI have a build that runs on my stagingfirebase project.

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

and if I call flutter run --flavor Debug-productionI have a build that runs on my productionfirebase project.

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

enter image description here

enter image description here

enter image description here

enter image description here

UPDATE 2

更新 2

Just for completness you could change bundle id also here:

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

enter image description here

enter image description here

Anyway it seems that there's a strange behaviorthat once you build a flavoura second time fluttercommand build correctly the flavor but run the previos build flavor.

无论如何,似乎有一种奇怪的行为,一旦您构建flavour第二次flutter命令,就会正确构建风味,但运行 previos 构建风味

As building with XCodeand switching with schemes all works as expected (even the run of the right application) I guess that this could be a flutter command issue. So I suggest you trying file an issue herelinking also this SO question/answer.

由于XCode使用方案构建和切换都按预期工作(甚至运行正确的应用程序),我想这可能是一个颤振命令问题。因此,我建议您尝试在此处提交一个问题,并链接此 SO 问题/答案。

UPDATE 3

更新 3

After a bit of intel I've found that flutter toolsset the applicaiton launching environment before building the project. So when we change CFBundleIdentifierinside Info.plistthe first time, the second time we launch flutter runit takes the previous modified value and try launching this bundle id while during build we are changing it because we are building a different variant.

经过一番了解后,我发现flutter tools在构建项目之前设置了应用程序启动环境。因此,当我们第一次更改CFBundleIdentifierinsideInfo.plist时,我们第二次启动flutter run它时会使用之前修改过的值并尝试启动此包 ID,而在构建期间我们正在更改它,因为我们正在构建不同的变体。

A possible solution could be to launch a scriptthat change the CFBundleIdentifierinside Info.plistbefore calling fluetter run.

一个可能的解决办法是推出一个脚本这改变CFBundleIdentifier内部Info.plist调用之前fluetter run

For example starting with a Info.plistwith a production bundle id of com.example.flutterAppAuthFlavourswe could do something like that

例如Info.plist,以生产包 id开头,com.example.flutterAppAuthFlavours我们可以做类似的事情

enter image description here

enter image description here

enter image description here

enter image description here

Here I've used sedcommand just to think different, but you could call always our belowed PlistBuddyto make the change before calling flutter run.

在这里,我使用sed命令只是为了不同的想法,但是您可以PlistBuddy在调用flutter run.