Примечание: решение внизу.
Исходная проблема. Я следовал инструкциям на firebase, чтобы настроить push-уведомления в iOS.Я успешно получаю уведомления на телефон и буду отображаться в верхней части телефона, если приложение закрыто, но если я нахожусь в приложении, уведомление никогда не отображается.Я вижу распечатку в терминале, хотя знаю, что она получает уведомление.
Идеальной функциональностью может быть: 1) если приложение закрыто или находится в фоновом режиме, когда пользователь щелкает уведомление, когда оно открывает приложение, то во всплывающем оповещении в приложении будет отображаться уведомление с кнопкой «ОК», чтобы нажать
2) если приложение находится на переднем плане, уведомление отображается в виде всплывающего оповещения с нажатием кнопки «ОК».
Ниже приведен код AppDelegate.swift, который при запуске и отправке уведомления яполучить уведомление, но я также получаю следующую ошибку при попытке отобразить предупреждение. Предупреждение. Попытка представить UIAlertController в Company.AuthorizationCheckViewController, вид которого не находится в иерархии окон!
Спасибо за любую помощь, которую вы можете предоставить.
import UIKit
import GoogleMaps
import Sentry
import UserNotifications
import Firebase
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let userDefaults = UserDefaults.standard
FirebaseApp.configure()
Messaging.messaging().delegate = self
if #available(iOS 10.0, *) {
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)
}
application.registerForRemoteNotifications()
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication) {
}
func applicationWillEnterForeground(_ application: UIApplication) {
VersionCheck.shared.IsUpdateRequired()
}
func applicationDidBecomeActive(_ application: UIApplication) {
}
func applicationWillTerminate(_ application: UIApplication) {
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
if let messageID = userInfo["gcm.message_id"] {
print("Message ID: \(messageID)")
}
let message : [String : Any] = userInfo["aps"] as! [String : Any]
let messageAlert : [String : Any] = message["alert"] as! [String : Any]
let lBody : String = messageAlert["body"] as! String
let lTitle : String = messageAlert["title"] as! String
print("body 1 = \(lBody)") //this works!
print("title = \(lTitle)") //this works!
let alert = UIAlertController(title: lTitle, message: lBody, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil);
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let message : [String : Any] = userInfo["aps"] as! [String : Any]
let messageAlert : [String : Any] = message["alert"] as! [String : Any]
let lBody : String = messageAlert["body"] as! String
let lTitle : String = messageAlert["title"] as! String
print("body 2 = \(lBody)")
print("title = \(lTitle)")
let alert = UIAlertController(title: lTitle, message: lBody, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil);
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
}
}
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
let message : [String : Any] = userInfo["aps"] as! [String : Any]
let messageAlert : [String : Any] = message["alert"] as! [String : Any]
let lBody : String = messageAlert["body"] as! String
let lTitle : String = messageAlert["title"] as! String
print("body 3 = \(lBody)")
print("title = \(lTitle)")
let alert = UIAlertController(title: lTitle, message: lBody, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
completionHandler([UNNotificationPresentationOptions.alert])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let messageID = userInfo["gcm.message_id"] {
print("Message ID: \(messageID)") //can use the id later to privent multiple popups of the same message
}
let message : [String : Any] = userInfo["aps"] as! [String : Any]
let messageAlert : [String : Any] = message["alert"] as! [String : Any]
let lBody : String = messageAlert["body"] as! String
let lTitle : String = messageAlert["title"] as! String
print("body 4 = \(lBody)")
print("title = \(lTitle)")
let alert = UIAlertController(title: lTitle, message: lBody, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
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: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)whenever a new token is generated.
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
}
}
Решение:
Я добавил PresentedViewController?к коду, и это позволило всплывающее окно предупреждения для отображения.Кроме того, добавив UIBackgroundFetchResults.newData в завершениеHandler, я смог отобразить уведомление в приложении
новый код выглядит следующим образом
let alert = UIAlertController(title: lTitle, message: lBody, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.window?.rootViewController?.presentedViewController?.present(alert, animated: true, completion: nil)
completionHandler(UIBackgroundFetchResult.newData)