didReceiveRemoteNotification 未调用,iOS 10 [英] didReceiveRemoteNotification not called, iOS 10
问题描述
在 iOS 9.3 中,didReceiveRemoteNotification
方法在以下两种情况下都会被调用.
1) 收到推送通知时2) 当用户通过点击通知启动应用时.
但在 iOS 10 上,我注意到 didReceiveRemoteNotification
方法在用户通过点击通知启动应用程序时不会触发.只有在收到通知时才会调用它.因此,从通知启动应用程序后,我无法执行任何进一步操作.
应该怎么解决这个问题?有什么想法吗?
类型转换
适用于 Swift3
-
示例见这个
<块引用>导入UserNotifications
框架并在Appdelegate中添加UNUserNotificationCenterDelegate
导入用户通知@UIApplicationMain类 AppDelegate:UIResponder、UIApplicationDelegate、UNUserNotificationCenterDelegatefunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) ->布尔{//在应用程序启动后覆盖自定义点.//创建通知中心让中心 = UNUserNotificationCenter.current()center.delegate = 自己//设置类型为声音或徽章center.requestAuthorization(options: [.sound,.alert,.badge, .providesAppNotificationSettings]) { (granted, error) in//根据授权启用或禁用功能}application.registerForRemoteNotifications()返回真}func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {//let chars = UnsafePointer((deviceToken as NSData).bytes)var 标记 = ""对于 i 在 0..
<块引用>
使用这个委托接收通知
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {print("处理从前台推送")//当应用程序在前台时处理推送的自定义代码打印(\(notification.request.content.userInfo)")}func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping() -> Void) {打印(处理从后台推送或关闭")//如果你在 didReceiveRemoteNotification 中设置了一个成员变量,你就会知道这是来自关闭的还是后台的打印(\(response.notification.request.content.userInfo)")}func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) {让 navController = self.window?.rootViewController as!导航控制器让 notificationSettingsVC = NotificationSettingsViewController()navController.pushViewController(notificationSettingsVC,动画:真)}
有关更多信息,请参阅 Apple API 参考
<小时>目标 C
AppDelegate.h 有以下几行:
第一步
//在你的项目UserNotifications"中添加框架#import @interface AppDelegate : UIResponder
第 2 步
AppDelegate.m
//定义宏#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;如果(SYSTEM_VERSION_LESS_THAN(@10.0")){[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeprovidesAppNotificationSettings) category:nil]];[[UIApplication sharedApplication] registerForRemoteNotifications];//如果(选项!=零)//{//NSLog( @"registerForPushWithOptions:" );//}} 别的 {UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];center.delegate = self;[中心 requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL 授予,NSError * _Nullable 错误) {如果(!错误){//需要让应用对推送通知做任何事情[[UIApplication sharedApplication] registerForRemoteNotifications];NSLog( @"推送注册成功" );} 别的 {NSLog( @"推送注册失败" );NSLog( @"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription );NSLog( @"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );}}];}返回是;}
<块引用>
这将作为调用 registerForRemoteNotifications 的结果触发:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{//我们为向 AWS 中间人注册设备而执行的自定义操作}
<块引用>
然后,当用户点击通知时,会触发:
当应用程序处于前台或后台但未关闭时,这将在 iOS 10 中触发
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void(^)(UIBackgroundFetchResult))completionHandler{//iOS 10 将通过其他方法处理通知如果(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@10.0")){NSLog( @"iOS version >= 10. 让 NotificationCenter 处理这个.");//设置一个成员变量来告诉新委托这是背景返回;}NSLog( @"HANDLE PUSH, didReceiveRemoteNotification: %@", userInfo );//自定义代码来处理通知内容if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive ){NSLog( @"INACTIVE" );完成处理程序( UIBackgroundFetchResultNewData );}else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground ){NSLog(@"背景");完成处理程序( UIBackgroundFetchResultNewData );}别的{NSLog(@"前景");完成处理程序( UIBackgroundFetchResultNewData );}}
或使用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{[自我应用程序:应用程序 didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult 结果) {}];}
<块引用>
那么对于iOS 10,这两个方法:
- (void)userNotificationCenter:(UNUserNotificationCenter *)centerwillPresentNotification:(UNNotification *)通知withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{NSLog(@"处理前台推送");//当应用程序在前台时处理推送的自定义代码NSLog(@"%@", notification.request.content.userInfo);}- (void)userNotificationCenter:(UNUserNotificationCenter *)centerdidReceiveNotificationResponse:(UNNotificationResponse *)responsewithCompletionHandler:(void (^)())completionHandler{NSLog(@"处理后台推送或关闭");//如果你在 didReceiveRemoteNotification 中设置了一个成员变量,你就会知道这是来自关闭的还是后台的NSLog(@"%@", response.notification.request.content.userInfo);}- (void)userNotificationCenter:(UNUserNotificationCenter *)centeropenSettingsForNotification:(UNNotification *)notification{在应用程序中打开通知设置屏幕}
In iOS 9.3, the didReceiveRemoteNotification
method gets called on both of the following occasions.
1) When the push notification is received 2) When the user launches the app by tapping on the notification.
But on iOS 10, I notice that the didReceiveRemoteNotification
method does NOT fire when the user launches the app by tapping on the notification. It's called only when the notification is received. Hence, I cannot do any further action after the app is launched from notification.
What should be the fix for this? Any idea?
type converson
for Swift3
-
for sample see this
import the
UserNotifications
framework and add theUNUserNotificationCenterDelegate
in 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!")
}
receive the Notifications using this delegates
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)
}
for more Information you can see in Apple API Reference
objective C
AppDelegate.h has these lines:
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;
}
This will fire as a result of calling registerForRemoteNotifications:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// custom stuff we do to register the device with our AWS middleman
}
Then, when a user taps a notification, this fires:
This will fire in iOS 10 when the app is foreground or background, but not closed
-(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 );
}
}
or use
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
}];
}
Then for iOS 10, these two methods:
- (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
}
这篇关于didReceiveRemoteNotification 未调用,iOS 10的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!