为什么在使用Xcode进行调试时才会调用ReceiveRemoteNotification方法?

时间:2018-05-17 15:09:05

标签: ios swift xcode firebase firebase-cloud-messaging

我正在使用Swift 4开发iOS 11应用,并使用Firebase Cloud Messaging向用户发送通知。

设置通知的过程是:

1)加入Apple Developer计划。注册我的应用程序的应用程序ID并生成一个带有APNs服务的密钥,就像您在图片上看到的那样:

enter image description here

2)将iOS App添加到我现有的Firebase项目,并上传第一步中生成的Apple Key。

enter image description here

3)准备iOS应用以接收通知:添加了GoogleServices-Info,安装了必需的Firebase pods(Firebase Core和Messaging)。

4)启用所需功能。后台模式和推送通知。

enter image description here



enter image description here

5)最后,我编辑了我的appDelegate.swift,允许接收通知:

import UIKit
import CoreData
import KeychainAccess
import IQKeyboardManagerSwift
import Fabric
import Crashlytics
import Firebase
import FirebaseMessaging
import FirebaseInstanceID
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


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


         // Override point for customization after application launch.

        //FIREBASE CONFIGURATION START
        FirebaseApp.configure()

        UNUserNotificationCenter.current().requestAuthorization( options: [.alert, .badge, .sound]) { (success, error) in
            if error == nil {
                print("Successfull authorization!")
            }
        }
        application.registerForRemoteNotifications()
        NotificationCenter.default.addObserver(self, selector: #selector(refreshToken(notification:)), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)

        UNUserNotificationCenter.current().delegate = self

        //FIREBASE CONFIGURATION END

        if let token = InstanceID.instanceID().token() {
            print("token: '\(token)'")
        }


        return true
    }


    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
        Messaging.messaging().shouldEstablishDirectChannel = false
    }



    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        FBHandler()
    }


    @objc func refreshToken(notification: NSNotification) {
        let refreshToken = InstanceID.instanceID().token()!
        print("*** \(refreshToken) ***")

        FBHandler()
    }

    func FBHandler() {
        Messaging.messaging().shouldEstablishDirectChannel = true
    }

    // MARK: - Handle Silent FCM notifications
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        showLocalNotification()
        print("Entire message \(userInfo)")

        let state : UIApplicationState = application.applicationState
        switch state {
        case UIApplicationState.active:
            print("If needed notify user about the message")
        default:
            print("Run code to download content")
        }


        completionHandler(UIBackgroundFetchResult.newData)
    }

    func showLocalNotification() {
        let notification = UNMutableNotificationContent()
        notification.title = "Nou contingut disponible: Benicolet"
        notification.body = "Restriccions cremes agrícoles"

        let notificationTrigger = 
        UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)

        let request = UNNotificationRequest(identifier: "\(Int(arc4random_uniform(999999)))", content: notification, trigger: notificationTrigger)

        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
    }


// Make local notification to appear even when app is open
extension AppDelegate: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print(response.notification.request.content.userInfo)
        completionHandler()
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void {
        completionHandler([.alert, .badge, .sound])
    }
}

我的目标是接收静默通知,执行一些逻辑,然后显示本地通知。每次我通过方法didReceiveRemoteNotification向我的应用发送通知时都会发生这种情况。

目前我只需要能够使用showLocalNotification方法接收静音通知并显示本地通知。

问题是只有当我的iPhone连接到Xcode(调试)时发送通知时才会触发此方法。在这种状态下,代码工作正常,但如果我拔掉电缆,在我使用Xcode重新运行应用程序之前不再触发通知

我使用自己的服务器发送通知,设置Firebase topic'priority': 'High''content_available':true

Simmilar尚未解决的问题:

didReceiveRemoteNotification:fetchCompletionHandler not called when not attached to xcode iOS 8.0.2

APNS: didReceiveRemoteNotification:fetchCompletionHandler did not run when app is in background (unless xcode is debugging)

didReceiveRemoteNotification:fetchCompletionHandler not being called in background with content-available flag (gets called when connected to XCode)

didReceiveRemoteNotification:fetchCompletionHandler: only called in background when connected to xcode

0 个答案:

没有答案