我本来想在stackoverflow上问这个问题,但我刚刚想明白了。无论如何,为了子孙后代,我会发布这篇文章,因为这个bug花了我好几天的时间,我在这个网站上找不到任何关于它的提及。
在制作了两个不同的方案并根据AppDelegate中的方案选择了不同的plist后,我无法通过FCM发送推送通知。选择我的plist的代码如下所示:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
let defaults = UserDefaults.standard
// NOTE: DONT call registrationDataManager here or any other VC that uses Firebase before it's configured
let gcmMessageIDKey = "gcm.message_id"
let window: UIWindow? = nil
//XXX OVERRIDE INIT BREAKS SWIZZLING -- DO NOT USE
override init() {
super.init()
let buildFor = ProcessInfo.processInfo.environment["BUILD_FOR"]! as String
var firebasePlistFileName = "GoogleService-Info"
if buildFor == "PROD" {
//firebasePlistFileName = "GoogleService-Info-Production"
firebasePlistFileName = "RELEASE-NEW-GoogleService-Info"
print("--- USING PRODUCTION / RELEASE PLIST")
}
else {
firebasePlistFileName = "DEBUG-NEW-GoogleService-Info"
print("--- USING DEBUG PLIST")
}
let filePath = Bundle.main.path(forResource: firebasePlistFileName, ofType: "plist")
guard let fileopts = FirebaseOptions(contentsOfFile: filePath!) else {
assert(false, "Couldn't load config file")
return
}
FirebaseApp.configure(options: fileopts)
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// FirebaseApp.configure()
}
如果你尝试执行上述操作,你可能会注意到一个类似的错误
[AppDelegateSwizzler] App Delegate does not conform to UIApplicationDelegate protocol firebase
您应该做什么而不是:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let buildFor = ProcessInfo.processInfo.environment["BUILD_FOR"]! as String
var firebasePlistFileName = "GoogleService-Info"
if buildFor == "PROD" {
//firebasePlistFileName = "GoogleService-Info-Production"
firebasePlistFileName = "RELEASE-NEW-GoogleService-Info"
print("--- USING PRODUCTION / RELEASE PLIST")
}
else {
firebasePlistFileName = "DEBUG-NEW-GoogleService-Info"
print("--- USING DEBUG PLIST")
}
let filePath = Bundle.main.path(forResource: firebasePlistFileName, ofType: "plist")
guard let fileopts = FirebaseOptions(contentsOfFile: filePath!) else {
assert(false, "Couldn't load config file")
}
FirebaseApp.configure(options: fileopts)
}
//....
这是假设您已经进入方案,编辑了具有环境变量BUILD_FOR的方案,并且为您的生产/发布方案将其设置为PROD,然后将基于此指向正确的GoogleServices信息plist文件名。这是用Firebase实现多个plist而不搞砸一切的一种方法。
要点——不要使用overrideinit,除非你想解决自己的问题,或者你比我更了解你在做什么