未调用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)正常alert
, badge
和sound
选项b)包括content-available
选项(设置为1
或true
)c)包括mutable-content
选项(设置为1
或true
) 。 另外,技术上d)你有content-available
和mutable-content
,但这只会触发两种情况。
对于a) alert
, sound
, badge
信息:
这与本地通知的工作方式相同。
对于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];