因此,我正在使用 SwiftUI 2 和新的应用程序生命周期构建 iOS 应用程序,尝试实现 AppsDelegate 和 Firebase 推送通知
这是我的代码示例
import SwiftUI
@main
struct App: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView().environmentObject(AppSettings())
}
}
}
和 AppDelegateimport Firebase
import FirebaseMessaging
import UserNotifications
import Foundation
import UIKit
class AppDelegate: NSObject {
let gcmMessageIDKey = "gcm.message_id"
private func setupFirebase(application: UIApplication) {
FirebaseApp.configure()
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
Messaging.messaging().delegate = self
application.registerForRemoteNotifications()
}
}
extension AppDelegate: UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
setupFirebase(application: application)
return true
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
}
}
@available(iOS 10, *)
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
// print(userInfo)
completionHandler([.banner, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
completionHandler()
}
}
但是当我测试来自 firebase 控制台的通知时,它并没有到来。
最佳答案
我能够让你的代码工作。我认为 Firebase 在调整 AppDelegate
时存在问题.
如果您通过添加键 FirebaseAppDelegateProxyEnabled
来禁用 swizzling给您的Info.plist
,使其成为 Boolean
并将其设置为 NO
.
然后在你的AppDelegate
您需要添加以下内容,以便它向 Firebase 注册 APNS token 。:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
要使 Firebase 云消息传递工作,它需要在 APNS token 与其 token 之间建立链接。如果没有链接,那么您将无法发送消息。请注意,通过禁用 swizzling,将会有某些属性
您将不得不手动更新。
您应该阅读 documentation小心。在撰写此答案时,有 几个地方如果禁用 swizzling,则需要更新。
有三 在 AppDelegate 中。第一个如上所示,另外两个在这里,用于接收后台消息。
您将以下行添加到委托(delegate)方法中:
Messaging.messaging().appDidReceiveMessage(userInfo)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo) // <- this line needs to be uncommented
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo) // <- this line needs to be uncommented
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
有两个 在 UNUserNotificationCenterDelegate 中。将以下行添加到委托(delegate)方法的位置Messaging.messaging().appDidReceiveMessage(userInfo)
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo) // <- this line needs to be uncommented
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([[.alert, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo) // <- this line needs to be uncommented
// Print full message.
print(userInfo)
completionHandler()
}
}
上述代码取自 Firebase 的云消息传递文档。他们在代码注释中非常清楚,如果您禁用了 swizzling,需要做什么。根据您在项目中可能包含的其他 Firebase 模块,您可能需要手动更新其他值。这是您需要仔细检查文档和代码示例的地方,以了解您必须进行哪些更改。
关于SwiftUI 2 Firebase 推送通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64506267/