didReceiveRemoteNotification 未调用,iOS 10
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39382852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
didReceiveRemoteNotification not called, iOS 10
提问by smartsanja
In iOS 9.3, the didReceiveRemoteNotification
method gets called on both of the following occasions.
在 iOS 9.3 中,该didReceiveRemoteNotification
方法在以下两种情况下都会被调用。
1) When the push notification is received 2) When the user launches the app by tapping on the notification.
1) 当收到推送通知时 2) 当用户通过点击通知启动应用程序时。
But on iOS 10, I notice that the didReceiveRemoteNotification
method does NOTfire 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.
但在iOS上10,我注意到,该didReceiveRemoteNotification
方法不不,当用户通过点击通知启动应用程序触发。只有在收到通知时才会调用它。因此,从通知启动应用程序后,我无法执行任何进一步操作。
What should be the fix for this? Any idea?
应该怎么解决这个问题?任何的想法?
回答by Anbu.Karthik
type converson
类型转换
for Swift3
对于 Swift3
-
——
for sample see this
样品见这个
import the
UserNotifications
framework and add theUNUserNotificationCenterDelegate
in Appdelegate
导入
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!")
}
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
有关更多信息,您可以在 Apple API参考中看到
objective C
目标C
AppDelegate.h has these lines:
AppDelegate.h 有以下几行:
Step-1
第1步
//Add Framework in your project "UserNotifications"
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
Step-2
第2步
AppDelegate.m
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
步骤 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:
这将作为调用 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
然后,当用户点击通知时,会触发:
当应用程序处于前台或后台但未关闭时,这将在 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 );
}
}
or use
或使用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
}];
}
Then for iOS 10, these two methods:
那么对于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
}
回答by Aleksander Grzyb
I had the same problem. Notification banner appeared, but -application:didReceiveRemoteNotification:fetchCompletionHandler:
method was not called. The solution for me that worked was to add implementation of - application:didReceiveRemoteNotification:
method and forward call to -application:didReceiveRemoteNotification:fetchCompletionHandler:
:
我有同样的问题。出现通知横幅,但未-application:didReceiveRemoteNotification:fetchCompletionHandler:
调用方法。对我来说有效的解决方案是添加- application:didReceiveRemoteNotification:
方法的实现并将调用转发到-application:didReceiveRemoteNotification:fetchCompletionHandler:
:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result){}];
}
来源。
回答by Fidel
Swift 4 and IOS 12.
Swift 4 和 IOS 12。
While there might be multiple reasons (Already mentioned on other answers) why this issue could happen, in my personal case the solution was related to the payload when sending the push notification:
You need to set the "content-available"key on the json payload to 1.
e.g:
{"aps":{"alert":"Test","content-available":1, "badge":1,"sound":"default"}}
虽然可能有多种原因(已在其他答案中提到)为什么会发生此问题,但在我个人情况下,解决方案与发送推送通知时的有效负载有关:
您需要在 json 上设置“content-available”键有效载荷为 1。
例如:
{"aps":{"alert":"Test", "content-available":1, "badge":1,"sound":"default"}}
回答by Naishta
Working version iOS 11, Swift 4, Xcode 9. Just copy paste the below code in AppDelegate.
工作版本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)")
}
}
回答by Adam Bardon
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)
}
回答by Yongxiang Ruan
It is an iOS bug. It will be fixed in iOS 10.1. But just wait for 10.1 release in Oct instead of implementing a new library and remove it later.
这是一个iOS错误。它将在 iOS 10.1 中修复。但是只需等待 10 月发布 10.1,而不是实现新库并稍后将其删除。
回答by smartsanja
BTW, this issue seems to be fixed in iOS 10.1. I tested my app on 10.1, all work fine
顺便说一句,这个问题似乎在 iOS 10.1 中得到了修复。我在 10.1 上测试了我的应用程序,一切正常
回答by Hiren Rathod
swift 4,if you are using ios 11 or xcode version greater than 9.0then you must have use UNUserNotification delegatemethod to call the didReceiveRemoteNotification
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
}