6

私は Swift の初心者です。チャット アプリケーションを作成しています。アプリがフォアグラウンドまたは最小化されたときに通知を送信する必要があります。

しかし、アプリが最小化されているときに通知が届きません (USB が接続されている場合に機能します。

  1. 有効なリモート通知

  2. Xcode セットアップでのバックグラウンド フェッチ

  3. 有効化されたプッシュ通知

  4. 本番 APns 証明書

通知コード:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let gcmMessageIDKey = "gcm.message_id"

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

        FirebaseApp.configure()

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

        if #available(iOS 10.0, *) {

            UNUserNotificationCenter.current().delegate = self

            let authOptions: UNAuthorizationOptions = [.alert, .sound, .badge]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()

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

        return true
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {

        Messaging.messaging().appDidReceiveMessage(userInfo)         
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        Messaging.messaging().appDidReceiveMessage(userInfo)

        let action = userInfo["action"] as! String
        let notification = UILocalNotification()
        notification.fireDate = NSDate() as Date
        notification.alertTitle = "test"
        notification.alertBody = "test"
        notification.alertAction = "Ok"
        UIApplication.shared.applicationIconBadgeNumber =  1
        UIApplication.shared.scheduleLocalNotification(notification)

        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)")

        // With swizzling disabled you must set the APNs token here.
        Messaging.messaging().apnsToken = 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

        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

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

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

        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }

        print(userInfo)

        completionHandler()
    }
    @objc func tokenRefreshNotification(_ notification: Notification) {
            guard let token = InstanceID.instanceID().token() else {
            print("No firebase token, aborting registering device")
            return
        }
        print("No firebase token, aborting registering device")           
    }
}   

extension AppDelegate : MessagingDelegate {
    // [START refresh_token]
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("Firebase registration token: \(fcmToken)")
        Messaging.messaging().subscribe(toTopic: "/topics/channel_18")           
    }

    func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
        print("Received data message: \(remoteMessage.appData)")
    }        
}

FCM ペイロード:

 {
     "to" : "/topics/channel_18",
     "data" : {
      "action" : "NOTIFY",
      "message" : "{"text":"test" }"
     },
     "content_available" : true
    }

優先度を高くしてサウンドオプションを試しましたが、どれも機能しません。

クライアントの要求に従って「通知」キーを使用していないことに注意してください。FCMペイロードでデータメッセージのみを使用しています

USB接続なしでアプリがバックグラウンドにあるときに通知を機能させるのを手伝ってください。

4

1 に答える 1