UNUserNotificationCenter didRecieve Ответ не вызывается, если приложение завершено

Функция UNUserNotificationCenter не вызывается при нажатии кнопки " Действия" в чате в уведомлении после 3D Touch, если приложение не активно (даже в фоновом режиме или, скажем, не работает). Я использовал "присоединиться к процессу по имени" в XCode для отладки приложения, когда приложение было прекращено. Вот код:

import UIKit
import Mixpanel
import UserNotifications

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        //setup mixpanel

        self.handlePushNotificationWithUserInfo(launchOptions: launchOptions)

        //ask for push notification perms
        return true
    }

Когда всплывающее уведомление (отправлено из MixPanel) эта функция вызывается первой,

Звоните 1:

    func handlePushNotificationWithUserInfo(launchOptions: [NSObject: AnyObject]?) {
        //Handle PushNotification when app is opened
    }

Тогда это идет сюда,

Звоните 2:

    //register for notification
    func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {

        if #available(iOS 10.0, *) {
            let center = UNUserNotificationCenter.current()
            center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
                // Enable or disable features based on authorization.
            }
            center.delegate = self

            let actionChat = UNNotificationAction(identifier: Constants.ActionType.CHAT.rawValue, title: "Chat", options: [.foreground])
            let categoryOptions = UNNotificationCategoryOptions(rawValue: 0)
            let customerSupportCategory = UNNotificationCategory(identifier: Constants.NotificationType.CUSTOMER_SUPPORT.rawValue, actions: [actionChat], intentIdentifiers: [], options: categoryOptions)
            center.setNotificationCategories([customerSupportCategory])
        }

        application.registerForRemoteNotifications()
    }

Звоните 3:

    // remote notification
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        ....Some Code....
    }

Но ниже функция не вызывается. Но если приложение работает в фоновом режиме, то вызывается функция ниже, и все работает нормально. ПРОЧЕЕ приложение выходит на передний план, а чат - нет.

    // action buttons in enhanced Notification
    @available(iOS 10, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
        guard let action = Constants.ActionType(rawValue: response.actionIdentifier) else {
            completionHandler()
            return
        }
        switch action {
        case .CHAT:
            _ = self.handleRemoteUrl(NSURL(string: "chat") as? URL)
        default:
            _ = self.handleRemoteUrl(NSURL(string: "chat") as? URL)
        }
        completionHandler()
    }

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

Эта функция никогда не вызывается, возможно, потому что она устарела в iOS 10 по сравнению с userNotificationCenter(), не уверен. Пожалуйста, объясните это также..

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
        ....Some Code....
    }

Я использую iPhone 6s iOS 10 в качестве устройства отладки.XCode 8 бета-3

3 ответа

Из моих собственных экспериментов, получение локальных уведомлений в Swift 3 и Xcode 8 выглядит следующим образом:

Соответствие

  • Соответствовать UNUserNotificationCenterDelegate

    class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { .... }
    
  • Зарегистрироваться в качестве представителя Центра уведомлений:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
        let center = UNUserNotificationCenter.current()
        center.delegate = self
    
        return true
    }
    

Методы делегирования

  • Отвечать на пропущенные уведомления (например, приложение просмотра пользователя при отправке уведомления)

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
        print(notification.request.content.userInfo)
    }
    
  • Отвечать на действующие уведомления (например, уведомление, открытое пользователем)

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

Обновление Swift 3.1

  • Соответствует UNUserNotificationCenterDelegate

  • Зарегистрироваться в качестве представителя Центра уведомлений:

UNUserNotificationCenter.current().delegate = self
  • Методы делегирования
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    print(response.notification.request.content.categoryIdentifier)
}

public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    print(notification.request.content.categoryIdentifier)
}

Когда приложение не запущено или не уничтожено пользователем, а уведомление получено, тогда в таком сценарии вам нужно обработать didFinishLaunchingWithOptions и проверить, открывается ли приложение через уведомление, и действовать соответствующим образом.

// Проверить, запущен ли из уведомления

if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
       notificationReceived(notification)
    }
Другие вопросы по тегам