xcode UNUserNotificationCenter 确实收到了响应,完成处理程序从未被称为 iOS10,swift 2.3

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38954496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 18:20:20  来源:igfitidea点击:

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

xcodenotificationsios10

提问by Async-

I am scheduling new notifications in iOS10, like this:

我正在 iOS10 中安排新通知,如下所示:

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 <= 1){
                content.body = NSString.localizedUserNotificationStringForKey("IOS10: Your \(event.title) is about to start", arguments: nil)
            }else{
                content.body = NSString.localizedUserNotificationStringForKey("IOS10: You have \(event.title) in \(Int(minutesBefore)) minutes", arguments: nil)

            }
            content.sound = UNNotificationSound.defaultSound()

            let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)
            let identifier = NSString.localizedUserNotificationStringForKey("sampleRequest\(event.UUID)", arguments: nil)
            let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)

            //setting the delegate
            center.delegate = self

            center.addNotificationRequest(request, withCompletionHandler: { (error) in
                // handle the error if needed
                log.error(error?.localizedDescription)
                print("SCHEDULING >=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:

我能够安排通知,并在适当的时间接收本地通知。但是:我根据教程使用的委托方法从未执行过,但是每次点击通知时都会执行 didReceiveLocalNotification:

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?

didReceiveLocalNotification 不是被弃用了吗?如何使这些方法被调用?

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. 我将 UNUserNotificationCenter.delegate 的分配添加到 applicationDidFinishLaunchingWithOptions。
  2. 我还尝试将这些方法(委托方法)从 NotificationsController.swift 类的扩展中移出,并将此类设置为 UNUserNotificationCenterDelegate。也没有对我来说有效。

采纳答案by livsik

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

更新 2:在 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()
}

}

回答by user2084611

Use belwo delegate method for Swift 2.3:

在 Swift 2.3 中使用 belwo 委托方法:

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

回答by Avijit Nagare

Make sure your AppDelegate implementing UNUserNotificationCenterDelegateprotocol.

确保您的 AppDelegate 实现UNUserNotificationCenterDelegate协议。

For Swift

对于斯威夫特

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

For Objective-c

对于Objective-c

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

Assigning delegate to self will trigger following methods.

将委托分配给 self 将触发以下方法。

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

回答by user1140780

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.

我已经找到了答案。在使用 Swift 2.3 和最低部署目标为 iOS 9.3 的 Xcode 8 上运行应用程序时调用下面的委托方法。

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

In swift 3.0 Use,

在 swift 3.0 使用中,

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

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

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

回答by spassas

According to the UNUserNotificationCenterDelegate docs:

根据UNUserNotificationCenterDelegate 文档

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.

重要的

在您的应用程序完成启动之前,您必须尽快将您的委托对象分配给 UNUserNotificationCenter 对象。例如,在 iOS 应用程序中,您必须在 applicationWillFinishLaunching( :) 或 applicationDidFinishLaunching(:) 方法中分配它。

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

因此,这可能是设置通知中心委托太晚的问题。

回答by Matias Tebele

For Swift 3.0

对于 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()
}

回答by Caleb Hensley

Check to make sure that only your AppDelegate is set as the UNUserNotificationCenter Delegate.

检查以确保只有您的 AppDelegate 被设置为 UNUserNotificationCenter Delegate。

Are you using...

你正在用吗...

UNUserNotificationCenter.current().delegate = self

... more than once? I was trying to catch notifications with different outcomes in all of my view controllers by changing the delegate in each one and having each use this function:

... 不止一次?我试图通过更改每个视图控制器中的委托并让每个视图控制器使用此功能来捕获所有视图控制器中具有不同结果的通知:

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

The issue for me was that I hadn't implemented their functionality yet, and so the original userNotificationCenter function "didReceive" in my AppDelegate wasn't being called. This may be why yours isn't getting called.

我的问题是我还没有实现他们的功能,所以我的 AppDelegate 中的原始 userNotificationCenter 函数“didReceive”没有被调用。这可能就是为什么你的没有被调用的原因。

回答by crow

You are using incorrect function signatures

您使用了不正确的函数签名

The correct function signatures in swift are:

swift 中正确的函数签名是:

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

}

回答by bartosss

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

文档说在 applicationWillFinishLaunching(:) 或 applicationDidFinishLaunching(:) 中设置委托。所以在 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.

设置此委托后,将调用以下 willPresent 函数。

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