didReceiveRemoteNotification이 호출되지 않음, iOS 10
iOS 9.3에서 didReceiveRemoteNotification
메서드는 다음 두 경우 모두에서 호출됩니다.
1) 푸시 알림이 수신 된 경우 2) 사용자가 알림을 탭하여 앱을 실행하는 경우.
그러나 iOS 10에서는 사용자가 알림을 탭하여 앱을 시작할 때 didReceiveRemoteNotification
메서드가 실행 되지 않는다는 것을 알았습니다 . 알림을받을 때만 호출됩니다. 따라서 알림에서 앱을 시작한 후에는 더 이상 조치를 취할 수 없습니다.
이것에 대한 수정은 무엇입니까? 어떤 생각?
유형 수렴
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)
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
}
나는 같은 문제가 있었다. 알림 배너가 나타나지만 -application:didReceiveRemoteNotification:fetchCompletionHandler:
메서드가 호출되지 않았습니다. 나를 위해 일한 해결책은 - 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
신속한 코드 :
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 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)")
}
}
BTW,이 문제는 iOS 10.1에서 수정 된 것 같습니다. 10.1에서 내 앱을 테스트했는데 모두 잘 작동합니다.
Swift 4 및 IOS 12.
이 문제가 발생할 수있는 여러 가지 이유 (다른 답변에서 이미 언급 됨)가있을 수 있지만, 제 개인적인 경우에는 푸시 알림을 보낼 때 솔루션이 페이로드와 관련이있었습니다.
json 페이로드의 "content-available"키를 1로 설정해야합니다.
예 :
{ "aps": { "alert": "Test", "content-available": 1 , "badge": 1, "sound": "default"}}
빠른 4, 당신이 사용하는 경우 9.0보다 IOS 11 엑스 코드 버전 이상을 다음 사용해야합니다 UNUserNotification 위임 통화에 방법 didReceiveRemoteNotification을
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//Your code to handle events
}
참고 URL : https://stackoverflow.com/questions/39382852/didreceiveremotenotification-not-called-ios-10
'developer tip' 카테고리의 다른 글
두 개의 맥. (0) | 2020.11.13 |
---|---|
python argparse를 접두사없이 상호 배타적 인 그룹 인수로 만드는 방법은 무엇입니까? (0) | 2020.11.13 |
adb에서 패키지의 실행 가능한 활동 이름 가져 오기 (0) | 2020.11.13 |
Pycharm : Python 파일의 일부만 실행 (0) | 2020.11.13 |
NotificationChannel에서 사운드 비활성화 (0) | 2020.11.13 |