未调用didReceiveRemoteNotification,iOS 10


76

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

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

但在iOS上10,我注意到,该didReceiveRemoteNotification方法不,当用户通过点击通知启动应用程序触发。仅在收到通知时调用。因此,从通知启动应用程序后,我无法采取任何进一步的措施。

该如何解决?任何想法?


使用ObjC或Swift
gurmandeep

Answers:


136

类型转换

在此处输入图片说明

对于Swift3

在此处输入图片说明

--

样品请看这里

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

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参考。


目标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)  

第三步

- (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
   }

15
请不要针对多个问题重新发布答案。每个答案都应针对特定问题进行量身定制,并且在适用的情况下,应将问题标记为重复。
马特

1
您不需要使用UserNotificationCenter请求授权。仅注册为代表即可解决此问题。
phatmann '16

2
抱歉,收到didReceive Notification后如何获取userInfo?
斯维特拉娜

3
@Svitlana-您可以在此处获得NSLog(@“%@”,response.notification.request.content.userInfo);
Anbu.Karthik '16

您是否还不需要从后台模式启用“远程通知” 。我实际上对启用图像中所示的“推送通知”与此处所示的“远程通知”之间的区别感到困惑。如果我只听您说,不启用“远程通知”,会发生什么情况?
亲爱的

15

我有同样的问题。出现通知横幅,但未-application:didReceiveRemoteNotification:fetchCompletionHandler:调用方法。对我有效的解决方案是添加- application:didReceiveRemoteNotification:method的实现并转发给-application:didReceiveRemoteNotification:fetchCompletionHandler:

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

来源


14

Swift 4和IOS 12。

尽管可能有多种原因(已经在其他答案中提到)可能会发生此问题,但就我个人而言,解决方案与发送推送通知时的有效负载有关:

您需要在json上设置“ content-available”键有效负载为1。

例如:

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


8

迅捷代码

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

7

工作版本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)")
    }


}

您调用application.registerForRemoteNotifications()不会等待requestAuthorization。可以吗
Shivam Pokhriyal


5

顺便说一句,此问题似乎已在iOS 10.1中修复。我在10.1上测试了我的应用,一切正常


1

SWIFT 4,如果你使用的是IOS或者11版本的Xcode大于9.0,那么你必须使用UNUserNotification委托方法调用didReceiveRemoteNotification

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

//Your code to handle events

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.