推送通知已收到,但未显示在设备 ios 中

K. *_*tra 5 ios swift firebase-cloud-messaging

我正在开发一个使用 FCM 发送推送通知的应用程序。我已按照必要的步骤配置推送通知,即生成证书以添加权利并在后台模式下打开远程通知,还在 firebase 控制台中上传了具有正确密码的 .p12 证书。我为此使用的代码是

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

let gcmMessageIDKey = "gcm.message_id"

/// This method will be called whenever FCM receives a new, default FCM token for your
/// Firebase project's Sender ID.
/// You can send this token to your application server to send notifications to this device.
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String)
{
    debugPrint("--->messaging:\(messaging)")
    debugPrint("--->didRefreshRegistrationToken:\(fcmToken)")
}

@available(iOS 10.0, *)
public func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)
{
    debugPrint("--->messaging:\(messaging)")
    debugPrint("--->didReceive Remote Message:\(remoteMessage.appData)")
    let action_url = remoteMessage.appData["action_url"]! as! String
    if let remoteDiscussion = action_url.slice(from: "https://xxxxxxxx.in/d/", to: "-"){
        discussion = remoteDiscussion
        window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "notificationDetailedItemNavigation") as! UINavigationController
    }
}

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
    [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    debugPrint("###> 1 AppDelegate DidFinishLaunchingWithOptions")
    self.initializeFCM(application)
    if let token = InstanceID.instanceID().token(){
        debugPrint("GCM TOKEN = \(String(describing: token))")
    }
    return true
}

func applicationDidEnterBackground(_ application: UIApplication) {
    //FIRMessaging.messaging().disconnect()

    debugPrint("###> 1.2 AppDelegate DidEnterBackground")
    //        self.doServiceTry()
}


func applicationDidBecomeActive(_ application: UIApplication) {
    //        connectToFcm()
    application.applicationIconBadgeNumber = 0
    debugPrint("###> 1.3 AppDelegate DidBecomeActive")
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
{
    debugPrint("didFailToRegisterForRemoteNotificationsWithError: \(error)")
}

func application(received remoteMessage: MessagingRemoteMessage)
{
    debugPrint("remoteMessage:\(remoteMessage.appData)")
}

func initializeFCM(_ application: UIApplication)
{
    print("initializeFCM")
    //-------------------------------------------------------------------------//
    if #available(iOS 10.0, *) // enable new way for notifications on iOS 10
    {
        let center = UNUserNotificationCenter.current()
        center.delegate = self
        center.requestAuthorization(options: [.badge, .alert , .sound]) { (accepted, error) in
            if !accepted
            {
                print("Notification access denied.")
            }
            else
            {
                print("Notification access accepted.")
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                    Messaging.messaging().subscribe(toTopic: "/topics/Men")
                }
            }
        }
    }
    else
    {
        let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound];
        let setting = UIUserNotificationSettings(types: type, categories: nil);
        UIApplication.shared.registerUserNotificationSettings(setting);
        UIApplication.shared.registerForRemoteNotifications();
    }

    FirebaseApp.configure()
    Messaging.messaging().delegate = self
    Messaging.messaging().shouldEstablishDirectChannel = true

    NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotificaiton), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)
}

func tokenRefreshNotificaiton(_ notification: Foundation.Notification)
{
    if let refreshedToken = InstanceID.instanceID().token()
    {
        debugPrint("InstanceID token: \(refreshedToken)")
    }
    //        connectToFcm()
}

//    func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings)
//    {
//        debugPrint("didRegister notificationSettings")
//        if (notificationSettings.types == .alert || notificationSettings.types == .badge || notificationSettings.types == .sound)
//        {
//            application.registerForRemoteNotifications()
//        }
//    }

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if application.applicationState == .active {
        if let aps = userInfo["data"] as? NSDictionary {
            if let action_url = aps["action_url"] as? String {
                //                    let alert = UIAlertController(title: "Notification", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)
                //                    let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
                //                    alert.addAction(action)
                //                    self.window?.rootViewController?.present(alert, animated: true, completion: nil)
                print(action_url)
            }
        }
    }
    completionHandler(.newData)
}

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
{
    debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: NSDATA")

    let token = String(format: "%@", deviceToken as CVarArg)
    debugPrint("*** deviceToken: \(token)")
    Messaging.messaging().apnsToken = deviceToken as Data
    debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
    Messaging.messaging().subscribe(toTopic: "/topics/Men")
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
    debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: DATA")
    let token = String(format: "%@", deviceToken as CVarArg)
    debugPrint("*** deviceToken: \(token)")
    //        #if RELEASE_VERSION
    //            FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.prod)
    //        #else
    //            InstanceID.instanceID().setAPNSToken(deviceToken as Data, type:InstanceIDAPNSTokenType.sandbox)
    //        #endif
    Messaging.messaging().apnsToken = deviceToken
    debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
}
//-------------------------------------------------------------------------//

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 notification
    // Print message ID.

    Messaging.messaging().appDidReceiveMessage(userInfo)

    if let messageID = userInfo["gcm.message_id"] {
        debugPrint("Message ID: \(messageID)")
    }

    // Print full message.
    print(userInfo)
}

func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
    return true
}

func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
    return true
}

//------------------------------------------------------------------
}

 // [START ios_10_message_handling]
 @available(iOS 10, *)
 extension AppDelegate {

// Receive displayed notifications for iOS 10 devices.
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)

    // Change this to your preferred presentation option
    completionHandler([.alert, .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()
}
}
Run Code Online (Sandbox Code Playgroud)

在 did receive 方法上,我已经实现了打印收到的消息并实例化一个工作正常的 viewController,每当我从邮递员发送通知(如果应用程序正在运行)时,它都会打开目标视图控制器,但通知不会到来。

我在 StackOverflow 上查了很多解决方案,但无法找出问题所在。我被困在这里大约两周了,有人可以帮忙吗?

Xcode 日志

Dev*_*del 2

适用于iOS10及以上版本

使用UNUserNotificationCenterDelegate

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {


    completionHandler([.alert, .badge, .sound])

    let userInfo:NSDictionary = notification.request.content.userInfo as NSDictionary
    print(userInfo)
    let dict:NSDictionary = userInfo["aps"] as! NSDictionary
    let data:NSDictionary = dict["alert"] as! NSDictionary

    RNNotificationView.show(withImage: UIImage(named: "image_Logo_Small"),
                            title: data["title"] as? String,
                            message: data["message"] as? String,
                            duration: 2,
                            onTap: {
                                print("Did tap notification")
    })
}
Run Code Online (Sandbox Code Playgroud)

这是显示本机和 RNNotifcation 用法的代码,我保留在一个代码中,以便您可以在需要时使用(ios9/ios10)。您将需要根据您的有效负载更改需要显示的方面。

适用于iOS10以下

当您的应用程序位于前台时,将不会显示默认的推送通知。

当您的应用程序关闭或处于后台时,会显示推送通知。要在应用程序处于后台时显示推送,您必须在“后台模式”中选择“远程通知”。

现在为解决您的疑虑,

  1. 您可以创建一个与推送通知相同的视图,
  2. 在其中显示通知内容。
  3. 像推送通知一样为您的视图设置动画,您也可以在点击通知时保持操作。

如果您正在寻找第三方库,那么我会推荐:https://github.com/souzainf3/RNNotificationView