Я получаю странное поведение в iOS 14 в отношении удаленных уведомлений на iOS и Firebase Cloud Messaging (FCM)
.
УСТРОЙСТВО
Во-первых, я не могу отправлять тестовые уведомления на свое устройство из консоли FCM. Я дословно следил за документацией и несколькими учебными пособиями на всякий случай. Вот мой AppDelegate
:
import SwiftUI
import Firebase
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
FirebaseConfiguration.shared.setLoggerLevel(.min)
Messaging.messaging().delegate = self
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
print("Permission granted: \(granted)")
// 1. Check if permission granted
guard granted else {
print("Permission not granted")
return
}
// 2. Attempt registration for remote notifications on the main thread
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
}
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
completionHandler([[.banner, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
completionHandler()
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase registration token: \(fcmToken ?? "")")
let dataDict:[String: String] = ["token": fcmToken ?? ""]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
func application(application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
}
let gcmMessageIDKey = "gcm_Message_ID_Key"
Другие вещи, которые я пробовал:
Отключение метода swizzling в
Info.pList
(FirebaseAppDelegateProxyEnabled - Boolean - 0)Добавление
Messaging.messaging().appDidReceiveMessage(userInfo)
для обновления соответствующих методов после отключения swizzling в App Delegate.Отправка приложения в фоновый режим (можно ли протестировать его на переднем плане во время работы приложения? Будет ли оно работать на переднем плане, если оно вообще работает?)
СИМУЛЯТОР
Во-вторых, я не могу отправлять уведомления в симулятор, пока не перетащу aps file
из Finder в указанный симулятор. Этот aps file
представляет собой файл JSON, который я могу использовать для тестирования push-уведомлений на симуляторах. Примечание. Клавиша оповещения устарела в iOS 14.
{
"Simulator Target Bundle": "com.Example.app",
"aps": {
"sound": "default",
"badge": 1
}
}
Командная утилита терминала выглядит так
xcrun simctl push <device> com.Example example.apns
где <device>
— идентификатор устройства симулятора (вы также можете использовать booted вместо идентификатора устройства, если открыт только один симулятор), а example.apns
— ваш файл. Я создал свой apns file
в Atom.
Вот что я получаю в журналах:
Это мои отчеты из консоли FCM: