ios 对不同的构建方案使用不同的 GoogleService-Info.plist

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37615405/
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-08-31 09:15:05  来源:igfitidea点击:

Use different GoogleService-Info.plist for different build schemes

iosgoogle-cloud-messaginggoogle-signin

提问by nwaxgui

I am using a build scheme for prod and one for staging (with 2 different bundle identifiers) and I am trying to use a separate GoogleService-Info.plist for each scheme. Is there any way to manually select the plist file to use when initialising GCM (and goole login)? Or is its possible to avoid using the plist and do the setup manually?

我正在为 prod 使用一个构建方案,一个用于暂存(具有 2 个不同的包标识符),并且我正在尝试为每个方案使用单独的 GoogleService-Info.plist。有什么方法可以在初始化 GCM(和 goole 登录)时手动选择要使用的 plist 文件?或者是否可以避免使用 plist 并手动进行设置?

Thanks!

谢谢!

回答by Vasily Bodnarchuk

Details

细节

Tested on:

测试:

  • Xcode 9.2
  • Xcode 10.2 (10E125)
  • Xcode 11.0 (11A420a)
  • Xcode 9.2
  • Xcode 10.2 (10E125)
  • Xcode 11.0 (11A420a)

Solution

解决方案

  1. Create folder with all your Google.plist files (with different names) in project
  1. 在项目中创建包含所有 Google.plist 文件(具有不同名称)的文件夹

enter image description here

在此处输入图片说明

  1. Add run script
  1. 添加运行脚本

enter image description here

在此处输入图片说明

Do not forget to change PATH_TO_GOOGLE_PLISTSvalue

不要忘记更改PATH_TO_GOOGLE_PLISTS

Code

代码

PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/SM2/Application/Firebase"

case "${CONFIGURATION}" in

   "Debug_Staging" | "AdHoc_Staging" )
        cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-dev.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;

   "Debug_Poduction" | "AdHoc_Poduction" | "Distribution" | "Test_Poduction" )
        cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-prod.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;

    *)
        ;;
esac

Build schemes names

构建方案名称

enter image description here

在此处输入图片说明

回答by Essam Elmasry

@inidona 's answer worked for me. After I converted it to Swift

@inidona 的回答对我有用。在我将它转换为 Swift 之后

for Swift 2.3:

对于 Swift 2.3:

let filePath = NSBundle.mainBundle().pathForResource("GoogleService-Info", ofType: "plist")
let options = FIROptions(contentsOfFile: filePath)
FIRApp.configureWithOptions(options)

for Swift 3.0:

对于 Swift 3.0:

let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FIROptions(contentsOfFile: filePath)
FIRApp.configure(with: options)

for Swift 4.0:

对于 Swift 4.0:

let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FirebaseOptions(contentsOfFile: filePath)
FirebaseApp.configure(options: options!)

回答by Bruno Lemos

Check this article: https://medium.com/@brunolemos/how-to-setup-a-different-firebase-project-for-debug-and-release-environments-157b40512164

查看这篇文章:https: //medium.com/@brunolemos/how-to-setup-a-different-firebase-project-for-debug-and-release-environments-157b40512164

On Xcode, create two directories inside your project: Debugand Release. Put each GoogleService-Info.plistfile there.

在 Xcode 上,在您的项目中创建两个目录:DebugRelease. 把每个GoogleService-Info.plist文件放在那里。

On AppDelegate.m, inside the didFinishLaunchingWithOptionsmethod, put the code:

AppDelegate.m, 在didFinishLaunchingWithOptions方法内部,放置代码:

Objective-C

目标-C

  NSString *filePath;
#ifdef DEBUG
  NSLog(@"[FIREBASE] Development mode.");
  filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist" inDirectory:@"Debug"];
#else
  NSLog(@"[FIREBASE] Production mode.");
  filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist" inDirectory:@"Release"];
#endif

  FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
  [FIRApp configureWithOptions:options];

Swift 4

斯威夫特 4

var filePath:String!
#if DEBUG
    print("[FIREBASE] Development mode.")
    filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist", inDirectory: "Debug")
#else
    print("[FIREBASE] Production mode.")
    filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist", inDirectory: "Release")
#endif

let options = FirebaseOptions.init(contentsOfFile: filePath)!
FirebaseApp.configure(options: options)

Drag & drop both Debugand Releasefolders to the Build Phases > Copy Bundle Resources:

DebugRelease文件夹拖放到Build Phases > Copy Bundle Resources:

Build Phases >Copy Bundle Resources

构建阶段 >复制捆绑资源

That's it :)

就是这样 :)

回答by inidona

I think you can use this way to configure your GoogleService-Info.plist dynamicly and use different names for different bundle identifiers.

我认为您可以使用这种方式动态配置您的 GoogleService-Info.plist 并为不同的包标识符使用不同的名称。

ciao Andreas

乔安德烈亚斯

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"];
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
[FIRApp configureWithOptions:options];

回答by abbood

I noticed that google expects the filename to be GoogleServiceInfo.plist in the code:

我注意到 google 期望代码中的文件名是 GoogleServiceInfo.plist:

 * The method |configureWithError:| will read from the file GoogleServices-Info.plist bundled with
 * your app target for the keys to configure each individual API. To generate your
 * GoogleServices-Info.plist, please go to https://developers.google.com/mobile/add
 *
 * @see GGLContext (Analytics)
 * @see GGLContext (SignIn)
 */
@interface GGLContext : NSObject

the key phrase is this one

关键词是这个

read from the file GoogleServices-Info.plist bundled with your app target

从与您的应用程序目标捆绑的文件 GoogleServices-Info.plist 中读取

So I simply copied the same file and put it into different directories, and bounded it to different targets:

所以我只是简单地复制了同一个文件并将其放入不同的目录中,并将其绑定到不同的目标:

enter image description here

在此处输入图片说明

回答by Onato

If the GoogleService-Info.plisthas a different name it will affect your analytics results. Firebase will warn you about this. https://github.com/firebase/firebase-ios-sdk/issues/230#issuecomment-327138180. For this reason, none of these runtime-solutions will provide the best analytics results.

如果GoogleService-Info.plist名称不同,则会影响您的分析结果。Firebase 会就此向您发出警告。https://github.com/firebase/firebase-ios-sdk/issues/230#issuecomment-327138180。出于这个原因,这些运行时解决方案都不会提供最好的分析结果。

There are two solutions that won't mess with Analytics.

有两种解决方案不会干扰 Analytics。

  1. Use a different target with each schemeand associate each version of GoogleService-Info.plistwith its own target. See Target Membershipin the File inspectoron the right hand side in Xcode. For further info See this question.

  2. Use a build phase script to copy the correct versionof GoogleService-Info.plistinto the build directory. I use a different bundle ID for staging and production. This enables me to have both versions of the app installed in parallel. It also means with the script below I can name my different GoogleService-Info.plistfiles with the bundle ID. For example:

    • GoogleService-Info-com.example.app.plist
    • GoogleService-Info-com.example.app.staging.plist
  1. 对每个方案使用不同的目标,并将每个版本GoogleService-Info.plist与其自己的目标相关联。请参阅Xcode 右侧文件检查器中的目标成员资格。有关更多信息,请参阅此问题

  2. 使用构建阶段脚本将正确版本复制GoogleService-Info.plist到构建目录中。我使用不同的包 ID 进行暂存和生产。这使我能够同时安装两个版本的应用程序。这也意味着使用下面的脚本,我可以GoogleService-Info.plist使用包 ID命名我的不同文件。例如:

    • GoogleService-Info-com.example.app.plist
    • GoogleService-Info-com.example.app.staging.plist

Build Phase Script

构建阶段脚本

PATH_TO_CONFIG=$SRCROOT/Config/GoogleService-Info-$PRODUCT_BUNDLE_IDENTIFIER.plist
FILENAME_IN_BUNDLE=GoogleService-Info.plist
BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo cp $PATH_TO_CONFIG "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"
cp $PATH_TO_CONFIG "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"

Note: You will have to change PATH_TO_CONFIGto suit you setup.

注意:您必须更改PATH_TO_CONFIG以适合您的设置。

Build Phase Script

构建阶段脚本

回答by pierre23

You cannot avoid to use the plist with Firebase. The best solution I found so far for you it would be to add both files and name it

您无法避免在 Firebase 中使用 plist。到目前为止,我为您找到的最佳解决方案是添加两个文件并为其命名

GoogleService-Info_stage.plist

GoogleService-Info_stage.plist

and

GoogleService-Info_prod.plist

GoogleService-Info_prod.plist

Then from your code you can call the correct file. This way won't crash your app if you don't have the file. Just replace FILENAME with GoogleService-Info_prod or GoogleService-Info_stage.

然后从您的代码中您可以调用正确的文件。如果您没有该文件,这种方式不会使您的应用程序崩溃。只需将 FILENAME 替换为 GoogleService-Info_prod 或 GoogleService-Info_stage。

if let configFile = Bundle.main.path(forResource: "FILENAME", ofType: "plist"), 
    let options = FirebaseOptions(contentsOfFile: configFile)   
{
   FirebaseApp.configure(options: options)
}

回答by Bj?rn Egil

This answer is very much inspired by @abbood's answer, but a bit more specific on how to do it.

这个答案很大程度上受到@abbood答案的启发,但更具体地说明了如何去做。

For each of your targets, e.g. dev, stg, prod:

对于您的每个目标,例如 dev、stg、prod:

  • Download the corresponding GoogleService-Info.plistto a separate folder named after your target
  • In Xcode, right-click your app folder and choose Add files to "your app"enter image description here
  • Select the folder containing the target's GoogleService-Info.plist, make sure Copy items if neededand Create groupsare selected, check only the corresponding target in the list of targets, and press Addenter image description here
  • 下载对应的GoogleService-Info.plist以您的目标命名的单独文件夹
  • 在 Xcode 中,右键单击您的应用程序文件夹并选择 Add files to "your app"在此处输入图片说明
  • 选择包含目标的文件夹GoogleService-Info.plist,确定Copy items if neededCreate groups被选中,在目标列表中只勾选相应的目标,然后按Add在此处输入图片说明

That's it. Now you should have something similar to this structure

就是这样。现在你应该有类似这个结构的东西

enter image description here

在此处输入图片说明

When you build a target, the correct GoogleService-Info.plistwill be used.

当您构建目标时,GoogleService-Info.plist将使用正确的。

回答by Knight Fighter

Late but I think I must post this answer to help new developers, I found a very good article that resole my problem and I promise it can help you as well :)
Check thisarticle that resolve your problem as well.

迟到了,但我想我必须发布这个答案来帮助新开发人员,我找到了一篇很好的文章来解决我的问题,我保证它也可以帮助你:)
检查这篇文章也可以解决你的问题。

Step 1:
Copy the GoogleService-Info.plistcorresponding to your Firebase development environment into the Devdirectory. Similarly, copy the GoogleService-Info.plistcorresponding to your Firebase production environment in the Proddirectory. Make sure to uncheck “Copy items if needed”and all targets under “Add to targets”.

第一步:
将你的Firebase开发环境对应的GoogleService-Info.plist复制到Dev目录下。同理,将你的Firebase生产环境对应的GoogleService-Info.plist复制到Prod目录下。确保取消选中“需要时复制项目”“添加到目标”下的所有目标。

(Step 1 image link (I do not able to add image because of less reputations))

(Step 1 image link (I do not able to add image because of less reputations))

Step 2:
In the Xcode project navigator, select the app target. Switch to the Build Phases tab at the top, then add a New Run Script Phase. Name the phase “Setup Firebase Environment GoogleService-Info.plist”, or something to that effect, and place it before the “Copy Bundle Resources”step.

第 2 步:
在 Xcode 项目导航器中,选择应用程序目标。切换到顶部的 Build Phases 选项卡,然后添加一个New Run Script Phase。将阶段命名为“Setup Firebase Environment GoogleService-Info.plist”或类似名称,并将其放在“Copy Bundle Resources”步骤之前。

Step 3:
Implement a shell script that will copy the appropriate GoogleService-Info.plistinto the app bundle based on the build configuration. Copy and paste the following shell script into the run script phase you just created:

第 3 步:
实现一个 shell 脚本,该脚本将根据构建配置将适当的GoogleService-Info.plist复制到应用程序包中。将以下 shell 脚本复制并粘贴到您刚刚创建的运行脚本阶段:

# Name of the resource we're selectively copying
GOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist

# Get references to dev and prod versions of the GoogleService-Info.plist
# NOTE: These should only live on the file system and should NOT be part of the target (since we'll be adding them to the target manually)
GOOGLESERVICE_INFO_DEV=${PROJECT_DIR}/${TARGET_NAME}/Firebase/Dev/${GOOGLESERVICE_INFO_PLIST}
GOOGLESERVICE_INFO_PROD=${PROJECT_DIR}/${TARGET_NAME}/Firebase/Prod/${GOOGLESERVICE_INFO_PLIST}

# Make sure the dev version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_DEV}"
if [ ! -f $GOOGLESERVICE_INFO_DEV ]
then
    echo "No Development GoogleService-Info.plist found. Please ensure it's in the proper directory."
    exit 1
fi

# Make sure the prod version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_PROD}"
if [ ! -f $GOOGLESERVICE_INFO_PROD ]
then
    echo "No Production GoogleService-Info.plist found. Please ensure it's in the proper directory."
    exit 1
fi

# Get a reference to the destination location for the GoogleService-Info.plist
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Will copy ${GOOGLESERVICE_INFO_PLIST} to final destination: ${PLIST_DESTINATION}"

# Copy over the prod GoogleService-Info.plist for Release builds
if [ "${CONFIGURATION}" == "Release" ]
then
    echo "Using ${GOOGLESERVICE_INFO_PROD}"
    cp "${GOOGLESERVICE_INFO_PROD}" "${PLIST_DESTINATION}"
else
    echo "Using ${GOOGLESERVICE_INFO_DEV}"
    cp "${GOOGLESERVICE_INFO_DEV}" "${PLIST_DESTINATION}"
fi

回答by Sune Kj?rg?rd

Here's how to do it in Xamarin C#:

以下是在 Xamarin C# 中执行此操作的方法:

string plistPath = NSBundle.MainBundle.PathForResource ("GoogleService-Info", "plist");
Options options = new Options (plistPath);
App.Configure (options);

Remember to include the Firebase namespace:

请记住包含 Firebase 命名空间:

using Firebase.Analytics;