didReceiveRemoteNotification未被调用,iOS 10

在iOS 9.3中, didReceiveRemoteNotification方法会在以下两种情况下被调用。

1)当收到推送通知时2)当用户通过点击通知启动应用程序。

但是在iOS 10上,我注意到didReceiveRemoteNotification方法不会在用户通过点击通知来启动应用程序时触发。 只有在收到通知时才会调用它。 因此,从通知启动应用程序后,我不能做任何进一步的行动。

应该怎样解决这个问题? 任何想法?

键入converson

在这里输入图像描述

为Swift3

在这里输入图像描述

对于样品看到这一点

导入UserNotifications框架并在UNUserNotificationCenterDelegate中添加UNUserNotificationCenterDelegate

 import UserNotifications @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. //create the notificationCenter let center = UNUserNotificationCenter.current() center.delegate = self // set the type as sound or badge center.requestAuthorization(options: [.sound,.alert,.badge]) { (granted, error) in // Enable or disable features based on authorization } application.registerForRemoteNotifications() return true } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // let chars = UnsafePointer<CChar>((deviceToken as NSData).bytes) var token = "" for i in 0..<deviceToken.count { //token += String(format: "%02.2hhx", arguments: [chars[i]]) token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]]) } print("Registration succeeded!") print("Token: ", token) } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) { print("Registration failed!") } 

使用此代表接收通知

  func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) { print("Handle push from foreground") // custom code to handle push while app is in the foreground print("\(notification.request.content.userInfo)") } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { print("Handle push from background or closed") // if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background print("\(response.notification.request.content.userInfo)") } 

有关更多信息,请参阅Apple API 参考


目标C

AppDelegate.h有这些行:

步骤1

 //Add Framework in your project "UserNotifications" #import <UserNotifications/UserNotifications.h> @interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate> 

第2步

AppDelegate.m

  // define macro #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 

步骤3

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { application.applicationIconBadgeNumber = 0; if( SYSTEM_VERSION_LESS_THAN( @"10.0" ) ) { [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; [[UIApplication sharedApplication] registerForRemoteNotifications]; //if( option != nil ) //{ // NSLog( @"registerForPushWithOptions:" ); //} } else { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) { if( !error ) { // required to get the app to do anything at all about push notifications [[UIApplication sharedApplication] registerForRemoteNotifications]; NSLog( @"Push registration success." ); } else { NSLog( @"Push registration FAILED" ); NSLog( @"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription ); NSLog( @"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion ); } }]; } return YES; } 

这将作为调用registerForRemoteNotifications的结果触发:

  - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // custom stuff we do to register the device with our AWS middleman } 

然后,当用户点击一个通知,这发生:

当应用程序处于前景或背景但未关闭时,这将在iOS 10中触发

  -(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // iOS 10 will handle notifications through other methods if( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO( @"10.0" ) ) { NSLog( @"iOS version >= 10. Let NotificationCenter handle this one." ); // set a member variable to tell the new delegate that this is background return; } NSLog( @"HANDLE PUSH, didReceiveRemoteNotification: %@", userInfo ); // custom code to handle notification content if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive ) { NSLog( @"INACTIVE" ); completionHandler( UIBackgroundFetchResultNewData ); } else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground ) { NSLog( @"BACKGROUND" ); completionHandler( UIBackgroundFetchResultNewData ); } else { NSLog( @"FOREGROUND" ); completionHandler( UIBackgroundFetchResultNewData ); } } 

或使用

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) { }]; } 

那么对于iOS 10来说,这两个方法:

 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { NSLog( @"Handle push from foreground" ); // custom code to handle push while app is in the foreground NSLog(@"%@", notification.request.content.userInfo); } - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { NSLog( @"Handle push from background or closed" ); // if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background NSLog(@"%@", response.notification.request.content.userInfo); } 

我有同样的问题。 出现通知横幅,但是-application:didReceiveRemoteNotification:fetchCompletionHandler:方法未被调用。 为我工作的解决方案是添加实施- application:didReceiveRemoteNotification:方法和转发呼吁- application:didReceiveRemoteNotification: -application:didReceiveRemoteNotification:fetchCompletionHandler: ::

 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result){}]; } 

来源 。

这是一个iOS的错误。 它将在iOS 10.1中修复。 但是等待10月份发布的10.1版本,而不是实现一个新的库,并在以后删除它。

https://forums.developer.apple.com/thread/54322

Swift代码

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.currentNotificationCenter() center.delegate = self } // ... return true } @available(iOS 10.0, *) public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { print(response.notification.request.content.userInfo) } @available(iOS 10.0, *) public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { print(notification.request.content.userInfo) } 

顺便说一句,这个问题似乎是在iOS 10.1中解决的。 我测试了我的10.1应用程序,一切正常

工作版本iOS 11,Swift 4,Xcode 9 。 只需将下面的代码粘贴到AppDelegate中。

 import UIKit import UserNotifications @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { if #available(iOS 10, *) { // iOS 10 support //create the notificationCenter let center = UNUserNotificationCenter.current() center.delegate = self // set the type as sound or badge center.requestAuthorization(options: [.sound,.alert,.badge]) { (granted, error) in if granted { print("Notification Enable Successfully") }else{ print("Some Error Occure") } } application.registerForRemoteNotifications() } else if #available(iOS 9, *) { // iOS 9 support UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } else if #available(iOS 8, *) { // iOS 8 support UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } else { // iOS 7 support application.registerForRemoteNotifications(matching: [.badge, .sound, .alert]) } return true } //get device token here func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { var token = "" for i in 0..<deviceToken.count { token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]]) } print("Registration succeeded!") print("Token: ", token) //send tokens to backend server // storeTokens(token) } //get error here func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Registration failed!") } //get Notification Here below ios 10 func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) { // Print notification payload data print("Push notification received: \(data)") } //This is the two delegate method to get the notification in iOS 10.. //First for foreground @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options:UNNotificationPresentationOptions) -> Void) { print("Handle push from foreground") // custom code to handle push while app is in the foreground print("\(notification.request.content.userInfo)") } //Second for background and close @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response:UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { print("Handle push from background or closed") // if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background print("\(response.notification.request.content.userInfo)") } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } }