UNUserNotificationCenter did receive response with completion handler is never called iOS10, swift 2.3

匿名 (未验证) 提交于 2019-12-03 01:25:01

问题:

I am scheduling new notifications in iOS10, like this:

func scheduleNotification (event : Meeting, todaysBadgeCounter: Int) {      if #available(iOS 10.0, *) {          let minutesBefore = 10         //interval in seconds from current point in time to notification         let interval : NSTimeInterval = NSTimeInterval(secondsFromNowTo(event.startTime.dateByAddingTimeInterval(-minutesBefore * 60)))          //only schedule in the future         if(interval > 0){               let category = NotificationsController.notificationCategory              let center = NotificationsController.notificationCenter             center.setNotificationCategories([category])             let content = UNMutableNotificationContent()              content.title = NSString.localizedUserNotificationStringForKey(event.title, arguments: nil)             if(minutesBefore =iOS10:", event.title, ", interval:", interval)             })         }   //return category @available(iOS 10.0, *) class var notificationCategory : UNNotificationCategory {     struct Static {         static let callNow = UNNotificationAction(identifier: NotificationActions.callNow.rawValue, title: "Call now", options: [])         static let clear = UNNotificationAction(identifier: NotificationActions.clear.rawValue, title: "Clear", options: [])         static let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "CALLINNOTIFICATION", actions: [callNow, clear], intentIdentifiers: [], options: [])      }     return Static.category } 

I am able to schedule notifications, and receive local notifications at the right time. BUT: my delegate methods that I used according to the tutorial are never executed, however the didReceiveLocalNotification is executed each time I tap on the notification:

extension NotificationsController: UNUserNotificationCenterDelegate {  @available(iOS 10.0, *) func userNotificationCenter(center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {      print("IOS10 delivered")      // Response has actionIdentifier, userText, Notification (which has Request, which has Trigger and Content)     switch response.actionIdentifier {     case NotificationActions.NotifyBefore.rawValue:         print("notify")         break      case NotificationActions.callNow.rawValue:         print("callNow")         break     case NotificationActions.clear.rawValue:         print("clear")     default: break     } }  @available(iOS 10.0, *) func userNotificationCenter(center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {          // Delivers a notification to an app running in the foreground.         print("IOS10 delivered 2222")      } } 

Wasn't didReceiveLocalNotification deprecated? How to make these methods to be called?

UPDATE:

I updated my code with some suggestions from here, namely:

  1. I added assigning of the UNUserNotificationCenter.delegate to the applicationDidFinishLaunchingWithOptions.
  2. I also tried moving these methods (delegate methods) out of the extension to the NotificationsController.swift class, and setting this class as UNUserNotificationCenterDelegate. Did not work for me either.

回答1:

Request identifier is not the notification category.

Just add this line:

content.categoryIdentifier = identifier 

Update: Just made a simple app. Everything seems to working fine:

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {  var window: UIWindow?  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {      UNUserNotificationCenter.current().delegate = self      UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in         if granted {             self.registerCategory()             self.scheduleNotification(event: "test", interval: 3)             self.scheduleNotification(event: "test2", interval: 5)         }     }      return true }  func registerCategory() -> Void{      let callNow = UNNotificationAction(identifier: "call", title: "Call now", options: [])     let clear = UNNotificationAction(identifier: "clear", title: "Clear", options: [])     let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "CALLINNOTIFICATION", actions: [callNow, clear], intentIdentifiers: [], options: [])      let center = UNUserNotificationCenter.current()     center.setNotificationCategories([category])  }  func scheduleNotification (event : String, interval: TimeInterval) {     let content = UNMutableNotificationContent()      content.title = event     content.body = "body"     content.categoryIdentifier = "CALLINNOTIFICATION"     let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)     let identifier = "id_"+event     let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)      let center = UNUserNotificationCenter.current()         center.add(request, withCompletionHandler: { (error) in     })  }  func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {     print("didReceive")     completionHandler() }  func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {     print("willPresent")     completionHandler([.badge, .alert, .sound]) }  } 

Update 2: Rewritten in Swift 2.3

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {  var window: UIWindow?  func applicationDidFinishLaunching(application: UIApplication) {     UNUserNotificationCenter.currentNotificationCenter().delegate = self     UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert]) { (granted, error) in         if granted {             self.registerCategory()             self.scheduleNotification("test", interval: 3)             self.scheduleNotification("test2", interval: 5)         }     } }   func registerCategory() -> Void{      let callNow = UNNotificationAction(identifier: "call", title: "Call now", options: [])     let clear = UNNotificationAction(identifier: "clear", title: "Clear", options: [])     let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "CALLINNOTIFICATION", actions: [callNow, clear], intentIdentifiers: [], options: [])      let center = UNUserNotificationCenter.currentNotificationCenter()     center.setNotificationCategories([category])  }  func scheduleNotification(event : String, interval: NSTimeInterval) {     let content = UNMutableNotificationContent()      content.title = event     content.body = "body"     content.categoryIdentifier = "CALLINNOTIFICATION"     let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)     let identifier = "id_"+event     let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)      let center = UNUserNotificationCenter.currentNotificationCenter()     center.addNotificationRequest(request) { (error) in      } }  func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {      print("willPresent")     completionHandler([.Badge, .Alert, .Sound]) }  func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {      print("didReceive")     completionHandler() }  } 


回答2:

I have found the answer for this. Below delegate method is called while running app on Xcode 8 with Swift 2.3 and minimum deployment target as iOS 9.3.

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) 

In swift 3.0 Use,

func userNotificationCenter(_ center: UNUserNotificationCenter,                        didReceive response: UNNotificationResponse,             withCompletionHandler completionHandler: @escaping () -> Void) 

Reference: https://developer.apple.com/reference/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter



回答3:

Use belwo delegate method for Swift 2.3:

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) 


回答4:

Make sure your AppDelegate implementing UNUserNotificationCenterDelegate protocol.

For Swift

let center = UNUserNotificationCenter.current() center.delegate = self 

For Objective-c

//set delegate to self [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; 

Assigning delegate to self will trigger following methods.

// App in foreground     private func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {       print("willPresent")       } //On Action click      private func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {       print("didReceive")       } 


回答5:

For Swift 3.0

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


回答6:

You are using incorrect function signatures

The correct function signatures in swift are:

func userNotificationCenter(UNUserNotificationCenter, willPresent: UNNotification, withCompletionHandler: (UNNotificationPresentationOptions) -> Void) {  //your code here  } 

and

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {  //your code here  } 


回答7:

According to the UNUserNotificationCenterDelegate docs:

Important

You must assign your delegate object to the UNUserNotificationCenter object no later before your app finishes launching. For example, in an iOS app, you must assign it in the applicationWillFinishLaunching(:) or applicationDidFinishLaunching(:) method.

So, it could be an issue of setting the Notification Centre delegate too late.



回答8:

The docs says to set the delegate in applicationWillFinishLaunching(:) or applicationDidFinishLaunching(:). So include the following code in AppDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {    UNUserNotificationCenter.current().delegate = self } 

After this delegate is being set, the following willPresent function will be called.

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


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!