首页 文章

didReceiveRemoteNotification未调用,iOS 10

提问于
浏览
63

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

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

但是在iOS 10上,我注意到当用户通过点击通知启动应用程序时, didReceiveRemoteNotification 方法会触发 NOT . 只有在收到通知时才会调用它 . 因此,在通知启动应用程序后,我无法执行任何进一步操作 .

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

8 回答

  • 15

    type converson

    enter image description here

    for Swift3

    enter image description here

    样本见this

    导入UserNotifications框架并在Appdelegate中添加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,  .providesAppNotificationSettings]) { (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)")
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) {
    let navController = self.window?.rootViewController as! UINavigationController
    let notificationSettingsVC = NotificationSettingsViewController()
    navController.pushViewController(notificationSettingsVC, animated: true)
    }
    

    有关Apple API中可以看到的更多信息Reference


    目标C.

    AppDelegate.h有以下几行:

    Step-1

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

    Step-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)
    

    Step-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 |  UIUserNotificationTypeprovidesAppNotificationSettings) 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);
        }  
    
        - (void)userNotificationCenter:(UNUserNotificationCenter *)center 
       openSettingsForNotification:(UNNotification *)notification{
            Open notification settings screen in app
       }
    
  • 6

    我有同样的问题 . 出现了通知 Banner ,但未调用 -application:didReceiveRemoteNotification:fetchCompletionHandler: 方法 . 对我有用的解决方案是添加 - application:didReceiveRemoteNotification: 方法的实现并将调用转发到 -application:didReceiveRemoteNotification:fetchCompletionHandler:

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

    Source .

  • 127

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

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

  • 6

    Swift code

    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)
    }
    
  • 0

    工作版 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)
        {
            let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
            let token = tokenParts.joined()
            print("Registration succeeded!")
            print("Token: ", token)
    
            //send tokens to backend server
        }
    
        //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)")
        }
    
    
    }
    
  • 2

    顺便说一句,这个问题似乎在iOS 10.1中得到修复 . 我在10.1上测试了我的应用程序,一切正常

  • 7

    Swift 4 and IOS 12.

    虽然可能有多种原因(已经在其他答案中提到)为什么会出现这个问题,但在我个人的情况下,解决方案与发送推送通知时的有效负载有关:

    您需要将json有效内容上的“content-available”键设置为1 .

    例如:

    {"aps":{"alert":"Test", "content-available":1 ,"badge":1,"sound":"default"}}

  • 5

    swift 4, 如果你使用的是 ios 11 or xcode version greater than 9.0 那么你必须使用 UNUserNotification delegate 方法来调用 didReceiveRemoteNotification

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    
    //Your code to handle events
    
    }
    

相关问题