Ios 在新Firebase中,如何在xcode中使用多个配置文件?
嘿,我正在玩新的firebase iOS SDK,在我的项目中,我只有一个目标,我创建了两个配置,调试和发布,具有不同的绑定器标识符,但从firebase下载的配置文件似乎只支持一个绑定器标识符 那么有人知道如何在多包标识符xcode项目中使用firebase吗Ios 在新Firebase中,如何在xcode中使用多个配置文件?,ios,xcode,firebase,Ios,Xcode,Firebase,嘿,我正在玩新的firebase iOS SDK,在我的项目中,我只有一个目标,我创建了两个配置,调试和发布,具有不同的绑定器标识符,但从firebase下载的配置文件似乎只支持一个绑定器标识符 那么有人知道如何在多包标识符xcode项目中使用firebase吗 谢谢 我已经实现了类似的东西,因为我已经为一个目标实现了两个方案,它们具有不同的bundle标识符。在我下面的例子中,我有两个不同的方案,一个用于UAT,一个用于PROD 创建两个GoogleService-Info.json文件,并将
谢谢 我已经实现了类似的东西,因为我已经为一个目标实现了两个方案,它们具有不同的bundle标识符。在我下面的例子中,我有两个不同的方案,一个用于UAT,一个用于PROD 创建两个GoogleService-Info.json文件,并将它们放入不同文件夹中的项目目录(而不是Xcode项目),例如
ROOT/config/UAT/GoogleService-Info.json
ROOT/config/PROD/GoogleService-Info.json
然后将这些文件添加到Xcode项目中,如下所示:
现在,您需要在构建阶段添加一个运行脚本。这需要在编译源代码阶段之前添加:
此运行脚本获取位于适当位置的json文件并将其复制到build app目录中,这意味着Firebase/Google将以与在单个标识符设置中识别文件相同的方式对其进行识别
isUAT=`expr "$GCC_PREPROCESSOR_DEFINITIONS" : ".*UAT=\([0-9]*\)"`
RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/PROD
if [ $isUAT = 1 ]; then
RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/UAT
fi
BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Copying all files under ${RESOURCE_PATH} to ${BUILD_APP_DIR}"
cp -v "${RESOURCE_PATH}/"* "${BUILD_APP_DIR}/"
我估计您也可以将同样的逻辑用于Google Analytics,它使用类似的json配置文件设置。更新:请参阅Firebase官方文档 更新为更简单的解决方案:
我的第一次尝试没有解决问题: 我将第二个GoogleService-Info.json重命名为其他名称,并使用以下代码从AppDelegate配置Firebase
// Swift code
#if STAGING
let firebasePlistFileName = "GoogleService-Staging-Info"
#else
let firebasePlistFileName = "GoogleService-Info"
#endif
let firbaseOptions = FIROptions(contentsOfFile: NSBundle.mainBundle().pathForResource(firebasePlistFileName, ofType: "plist"))
FIRApp.configureWithOptions(firbaseOptions)
如果我运行暂存目标,我将收到Firebase关于“找不到配置文件:'GoogleService Info.plist'”的投诉。但它说“Firebase Analytics v.3300000已启动”
正如我在Firebase仪表板上检查的那样,生产和登台应用程序都记录了传入的用户事件
上述configureWithOptions方法没有在Firebase文档中记录,我通过检查其源代码找到了它。我不确定这样称呼会有什么负面影响。我很想听听其他的方法。如果您有一个目标,更好的方法就是正确地命名您的配置并按如下方式加载它们。似乎在UAT环境下工作良好 示例:Swift 3.0
var fireBaseConfigFile = Bundle.main.path(forResource: "GoogleService-Info-PROD", ofType: "plist")
#if UAT
fireBaseConfigFile = Bundle.main.path(forResource: "GoogleService-Info-UAT", ofType: "plist")
#endif
guard let firOptions = FIROptions(contentsOfFile: fireBaseConfigFile) else {
assert(false, "Failed to load Firebase config file")
return
}
FIRApp.configure(with: firOptions)
使用不同的名称将两个Google服务列表添加到您的项目中: 然后,对于每个构建方案,选择编辑方案并为环境变量添加唯一值,如下所示: 例如,另一个构建方案的build_FOR环境变量将设置为“DEV” 然后,您将在App Delegate中检查此变量,并根据构建的方案配置FIRApp:
let buildFor = ProcessInfo.processInfo.environment["BUILD_FOR"]! as String
var firebasePlistFileName = "GoogleService-Info"
if buildFor == "PROD" {
firebasePlistFileName = "GoogleService-Prod-Info"
}
let firbaseOptions = FIROptions(contentsOfFile: Bundle.main.path(forResource: firebasePlistFileName, ofType: "plist"))
FIRApp.configure(with: firbaseOptions!)
我确实用不同的名称存储了2条谷歌服务信息:
用于生产GoogleService Info.plist
用于开发GoogleService Info Debug.plist
if [ "${CONFIGURATION}" == "Release" ]; then
cp -r "${PROJECT_DIR}/PathToYourGoogleServiceInfoFile/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
echo "Production plist copied"
elif [ "${CONFIGURATION}" == "Debug" ]; then
cp -r "${PROJECT_DIR}/PathToYourGoogleServiceInfoFile/GoogleService-Info-Debug.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
echo "Development plist copied"
fi
使用Objective-C,在AppDeltage.m中:
NSString *filePath;
#ifdef DEBUG
filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-Debug" ofType:@"plist"];
#else
filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-Production" ofType:@"plist"];
#endif
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
[FIRApp configureWithOptions:options];
Firebase包括如何立即执行此操作。我在我的应用程序中使用了这种方法,效果非常好
更具体地说,我在XCode中定义了一个自定义Swift标志“BUILD_TYPE”,并为每个方案定义了该标志的唯一值。然后,在我的AppDelegate中,我通过这个Swift标志值告诉Firebase在运行时要加载的GoogleService-\u__;.plist
文件:
let filePath = Bundle.main.path(forResource: "GoogleService-" + Bundle.main.infoDictionary!["BUILD_FLAVOR"] as! String, ofType: "plist")
guard let fileopts = FirebaseOptions.init(contentsOfFile: filePath!) else {
fatalError("Couldn't load config file")
}
FirebaseApp.configure(options: fileopts)
我看到很多使用目标的响应,但如果您想根据方案进行区分,可以访问: 编辑方案…>选择方案>生成>后期操作
- 添加一个运行脚本
- 从以下位置提供生成设置:(选择要创建的目标)
- 添加以下脚本
路径更改为\u GOOGLE\u PLISTS
样本:
最新语法用于为2个目标(2个Plist文件)配置firebase
firebasePlistFileName变量只是根据当前配置(即开发或生产)获取PList名称。方案的目标是否不同,或者它们是否都在同一目标中?@IanBarber否我只有一个目标,我创建了两个配置,调试和发布,使用不同的绑定器标识符。如果您有不同的目标,则更新的答案有效。原来的答案对我不起作用。Firebase配置仍试图打开Google服务信息文件。谢谢FIRApp.configureWithOptions记录在这里:您的原始答案现在可以与最新版本的Firebase一起使用。如果有人感兴趣,这里有configureWithOptions文档::Firebase包括如何立即执行此操作。非常接近你所拥有的。非常感谢。Firebase官方文档对于一个目标应用程序是错误的,如果您重命名两个文件,他们的方法将无法工作。我还没有验证这一点,但如果Firebase现在可以做到这一点,我建议您这样做。请注意-例如,didFinishLauchingWithOptions函数,但不要在override init方法中执行此操作,除非您想中断Swizzling这是我第一次发现的最简单的方法,并且工作得非常完美。我就这个方法写了一个简短的要点:Thank you@TheiOSChap,you make my Day you不应该在运行时做那种事情,因为它会影响您的生产分析。这个解决方案的问题是需要在应用程序包中同时包含这两个文件。我建议使用这种方法,但将prod文件命名为“GoogleService Info.plist”,以便它与默认值匹配,并且不会影响产品分析。非常感谢。在ca
PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/MVCVMRC/Supporting Files/FirebasePlist"
cp -r "$PATH_TO_GOOGLE_PLISTS/Brazil/GoogleService-Info-preprod.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
func configureFirebase() {
let firebasePlistFileName = ConfigurationManager.sharedManager().firebasePlistName()
if let path = Bundle.main.path(forResource: firebasePlistFileName, ofType: "plist") {
if let firbaseOptions = FirebaseOptions(contentsOfFile: path) {
FirebaseApp.configure(options: firbaseOptions)
}
}
}