未调用iOS 10 UNUserNotificationCenterDelegate。 推送通知无效

撕毁我的头发,以便在iOS10中使用推送通知。 目前的设置:

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

 if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.current() center.delegate = self center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in if error == nil { print("DID REQUEST THE NOTIFICATION") UIApplication.shared.registerForRemoteNotifications() } } print("DID SET DELEGATE") } 

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)

 print("DID REGISTER FOR A REMOTE NOTIFICATION AND THE TOKEN IS \(deviceToken.base64EncodedString())" let request = UpdatePushNotificationSubscription_Request(deviceToken: deviceToken) updatePushNotificationSubscriptionWorker.updateSubscription(request) 

我检查过令牌是否正确上传到后端,确实匹配。

我也实施了:

  @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { print("GOT A NOTIFICATION") } @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { //This is for the user tapping on the notification print("GOT A NOTIFICATION") } 

我已为所有目标设置权限并启用了推送:

在此处输入图像描述

现在当我尝试从后端发送消息时,设备什么也没收到。 代表们没有被召集。 不知道我在这里做错了什么。 推送适用于iOS9和Android设备。 我可能做错了什么指针?

此答案适用于iOS 10+,使用UserNotifications框架。

您需要一个类符合UNUserNotificationCenterDelegate协议。 如果您为此创建一个新类,或将其添加到您的AppDelegate类,则无关紧要。 我建议创建一个专门的课程。 出于本答案的目的,我们假设您为它创建一个UserNotificationController类。

该类可以有以下方法:

optional func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)

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

然后在AppDelegate.application(_:didFinishLaunchingWithOptions:)方法中,需要将UNUserNotificationCenter.current()对象上的delegate设置为UserNotificationController类的实例。 您可能希望使用共享实例。

请求用户授权以使用UNUserNotificationCenter.requestAuthorization(options:completionHandler:)方法启用通知,并在completionHandler中检查granted值。 如果为true ,则通过调用UIApplication.shared.registerForRemoteNotifications()注册远程通知。

现在,当应用程序收到推送通知时,可能会发生几种不同的情况。 我会尝试在这里列出最常见的案例。

本地通知:

如果应用程序位于前台,则应用程序将调用UserNotificationController .userNotificationCenter(_:willPresent:withCompletionHandler:)

如果应用程序在后台(运行与否),则在用户点击通知之前不会调用任何内容,此时应用程序将打开并调用UserNotificationController .userNotificationCenter(_:didReceive:withCompletionHandler:)

远程通知:

有效载荷的内容将影响发生的事情。 有效载荷有三种情况,a)正常alertbadgesound选项b)包括content-available选项(设置为1true )c)包括mutable-content选项(设置为1true ) 。 另外,技术上d)你有content-availablemutable-content ,但这只会触发两种情况。

对于a) alertsoundbadge信息:

这与本地通知的工作方式相同。

对于b) content-available == true:

如果应用程序位于前台,则UserNotificationController .userNotificationCenter(_:willPresent:withCompletionHandler:)

如果应用程序在后台(运行与否),则调用AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:) ,而不是UserNotificationController类中的UserNotificationController方法。

对于c) mutable-content == true:

如果您已将UNNotificationServiceExtension添加到应用程序,它将处理通知并可以修改内容。 无论主应用程序的状态如何,都会发生这种情况。 如果用户点击(可选修改的)通知,则其被处理为类似于上面的本地通知。

如果没有UNNotificationServiceExtension ,通知将被视为上面的普通远程通知。

补充笔记:

使用mutable-content ,必须在有效负载中包含alert信息,否则系统会将其视为不可变,而不是调用UNNotificationServiceExtension 。 您修改的通知仍必须包含alert信息,否则将使用原始通知有效负载。 遗憾的是,没有办法阻止通知出现在用户身上。

当使用content-available ,如果用户上次使用它时强制退出应用程序,系统将不会重新启动应用程序或调用AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:) 。 虽然它仍然会显示任何警报,播放声音,并按照有效负载中的指示更新徽章。

尝试使您的AppDelegate类实现UNUserNotificationCenterDelegate协议,而不是实现协议的单独类。

我有一个单独的代表类,它没有用。 这是我的代码在我工作时的样子:

 import UIKit import UserNotifications @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application UIApplication.shared.registerForRemoteNotifications() let center = UNUserNotificationCenter.current() center.delegate = self //DID NOT WORK WHEN self WAS MyOtherDelegateClass() center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in // Enable or disable features based on authorization. if granted { // update application settings } } return true } func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent: UNNotification, withCompletionHandler: @escaping (UNNotificationPresentationOptions)->()) { withCompletionHandler([.alert, .sound, .badge]) } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive: UNNotificationResponse, withCompletionHandler: @escaping ()->()) { withCompletionHandler() } // and so forth for your other AppDelegate stuff 

也许不设置UNNotificationCategory的intentIdentifiers,如果代码如下:

 UNNotificationCategory* expiredCategory = [UNNotificationCategory categoryWithIdentifier:@"TIMER_EXPIRED" actions:@[snoozeAction, stopAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction]; 

它不会调用UNUserNotificationCenter的委托方法,因此您必须设置这样的intentIdentifiers:

 UNNotificationCategory* expiredCategory = [UNNotificationCategory categoryWithIdentifier:@"TIMER_EXPIRED" actions:@[snoozeAction, stopAction] intentIdentifiers:@[@"a",@"b"] options:UNNotificationCategoryOptionCustomDismissAction];