【问题标题】:Use different GoogleService-Info.plist for single project in xcode using swift4使用 swift4 在 xcode 中为单个项目使用不同的 GoogleService-Info.plist
【发布时间】:2019-10-30 18:16:30
【问题描述】:

我有一个项目,但有 4 个不同的环境(开发、分期、QA、生产)。我已经从移动设备的设置中给出了他们的(环境的 web 服务 url)路径。现在我想为所有这些不同的环境使用不同的 GoogleService-info.plist。就像我从后端选择 Dev 时,项目应该只使用 Dev 项目的 GoogleService-Info.plist。这些 GoogleService-Info.plist 是在 4 个不同的帐户上创建的。项目应该以编程方式采用 GoogleService-info.plist 的路径。我试过下面的代码

1] 通过参考this url,我创建了两个文件夹 Dev 和 QA(目前)并尝试通过编程方式给出它们的路径

#if DEV
    print("[FIREBASE] Development mode.")
    filePath = Bundle.main.path(forResource: "GoogleService-Info", 
ofType: "plist", inDirectory: "Dev")
    #elseif QA
    print("[FIREBASE] QA mode.")
    filePath = Bundle.main.path(forResource: "GoogleService-Info", 
ofType: "plist", inDirectory: "QA")
    #endif
    let options = FirebaseOptions.init(contentsOfFile: filePath)!
    FirebaseApp.configure(options: options)

但是会报错

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

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

这一行

2] 其次,我通过 GoogleService-Info-QA.plist 更改了 GoogleService-Info.plist 的名称,并尝试以编程方式访问此文件

private func configureFirebase() {
    guard   let plistPath = Bundle.main.path(forResource: 
"GoogleService-Info-QA", ofType: "plist"),
        let options =  FirebaseOptions(contentsOfFile: plistPath)
        else { return }
    FirebaseApp.configure(options: options)
}

但是会报错

Terminating app due to uncaught exception 'FIRAppNotConfigured', 
reason: 'Failed to get default Firebase Database instance. Must 
call `[FIRApp configure]` (`FirebaseApp.configure()` in Swift) 
before using Firebase Database.

【问题讨论】:

  • 你的第二个错误表明你没有在你的appdelegate FirebaseApp.configure()中配置firebase
  • 是的,它是正确的,因为我想以编程方式提供 GoogleService-Info.plist 路径。并且编译器无法找到该路径。我不知道如何以编程方式给出该路径

标签: swift firebase firebase-realtime-database macros


【解决方案1】:

将此代码 sn-p 放在应用程序的 didFinishLaunchingWithOptions 委托函数中的 AppDelegate.swift 中,位于 return true 之前的某个位置

//Configure Firebase based on the app's environment
#if DEV
   guard let filePath = Bundle.main.path(forResource: "GoogleService-Info-DEV", ofType: "plist") else { return }
   let options = FIROptions(contentsOfFile: filePath)
   FIRApp.configure(with: options!)
#elseif QA
   guard let filePath = Bundle.main.path(forResource: "GoogleService-Info-QA", ofType: "plist")  else { return }
   let options = FIROptions(contentsOfFile: filePath)
   FIRApp.configure(with: options!)
#endif

您需要确保您的 plist 文件已相应命名,并确保它们是您的目标的一部分:

  • 选择 GoogleService-Info-DEV 文件,并在右侧的 FileInspector 中确保选中您应用目标的复选框。对 GoogleService-Info-QA 文件执行相同操作。

您的文件应放置在主文件夹中,就像放置普通的 Google-Info.plist 文件一样。

【讨论】:

    【解决方案2】:

    对于此确认,您必须执行以下步骤:

    1. 转到项目设置
    2. 选择你的开发目标
    3. 转到构建阶段
    4. 单击图标并创建名为 GOOGLESERVICE_INFO_PLIST 的新运行脚本
    5. 使用以下脚本

    //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}/projectFolder/Firebase/Dev/${GOOGLESERVICE_INFO_PLIST}
    GOOGLESERVICE_INFO_PROD=${PROJECT_DIR}/projectFolder/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
    • 最后一步:确保您已将 GoogleService-Info.plist 放置在项目中正确的位置路径,您可以找到附图以供参考。

    GOOGLESERVICE_INFO_DEV=${PROJECT_DIR}/projectFolder/Firebase/Dev/${GOOGLESERVICE_INFO_PLIST} GOOGLESERVICE_INFO_PROD=${PROJECT_DIR}/projectFolder/Firebase/Prod/${GOOGLESERVICE_INFO_PLIST}

    projectFolder 是您当前的项目文件夹

    【讨论】:

      【解决方案3】:

      我得到了解决方案。我通过其各自的环境重命名了 GoogleService-Info.plist 文件。并在 Build Phases -> Copy Bundle Resources 中添加了这些文件。然后根据选择的环境添加以下代码

       guard let plistPath = Bundle.main.path(forResource: "nameOfTheGoogleService-Info.plistFileAsPerTheEnvironment", ofType: "plist"),
                      let options =  FirebaseOptions(contentsOfFile: plistPath)
                      else { return }
                  if FirebaseApp.app() == nil{
                  FirebaseApp.configure(options: options)
                  }
      

      较小的变化是,当用户更改应用程序的环境时,他应该从后台删除应用程序并再次打开它。然后 AppDeleagte 根据其选择的环境采用相应 GoogleService-Info.plist 的路径

      【讨论】:

        猜你喜欢
        • 2017-08-04
        • 2017-01-14
        • 1970-01-01
        • 2018-03-06
        • 2022-01-06
        • 2016-10-03
        • 1970-01-01
        • 2018-01-01
        • 2017-10-19
        相关资源
        最近更新 更多