iOS - 如何在 iOS 10 中集成推送通知?

Posted

技术标签:

【中文标题】iOS - 如何在 iOS 10 中集成推送通知?【英文标题】:iOS- How to integrate push notification in iOS 10? 【发布时间】:2016-09-01 09:19:33 【问题描述】:

我在 ios 8,9 中使用了以下代码:

 UIMutableUserNotificationAction *action1;
    action1 = [[UIMutableUserNotificationAction alloc] init];
    [action1 setActivationMode:UIUserNotificationActivationModeBackground];
    [action1 setTitle:@"REJECT"];
    [action1 setIdentifier:NotificationActionOneIdent];
    [action1 setDestructive:NO];
    [action1 setAuthenticationRequired:NO];

    UIMutableUserNotificationAction *action2;
    action2 = [[UIMutableUserNotificationAction alloc] init];
    [action2 setActivationMode:UIUserNotificationActivationModeBackground];////UIUserNotificationActivationModeBackground
    [action2 setTitle:@"ACCEPT"];
    [action2 setIdentifier:NotificationActionTwoIdent];
    [action2 setDestructive:NO];
    [action2 setAuthenticationRequired:NO];

    UIMutableUserNotificationCategory *actionCategory;
    actionCategory = [[UIMutableUserNotificationCategory alloc] init];
    [actionCategory setIdentifier:NotificationCategoryIdent];
    [actionCategory setActions:@[action1, action2]
                    forContext:UIUserNotificationActionContextDefault];

    NSSet *categories = [NSSet setWithObject:actionCategory];

    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:
                                        UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:categories];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];

委托方法处理:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

//Handle according to app state

并且 //处理动作

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler 
//Handle action as well

如何在 iOS 10 中使用 UserNotifications 和 UserNotificationsUI 框架做同样的事情?我还需要支持 iOS 8 和 iOS 9 吗?

【问题讨论】:

【参考方案1】:

类型转换

适用于 Swift3

-

样品见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 有以下几行:

第一步

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

第二步

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  
            dispatch_async(dispatch_get_main_queue(), ^
                [[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 12,这两种方法:

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

【讨论】:

对于将项目升级到 XCode 8 的用户,请确保在链接库中包含 UserNotifications.framework。 跟随案例,注意方法 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler never be called.. can你告诉我怎么了? @Stony - 你是否在功能中启用了后台模式 @Anbu.Karthik 是的,我启用了“远程通知”。我敢肯定 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler 可以在收到推送通知时调用。但我不知道该方法 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler 的用途,因为我从未见过它被调用。 if( options != nil ) NSLog( @"registerForPushWithOptions:" );什么是选项变量?我没有得到..【参考方案2】:

1st) 在项目的常规设置中将 UserNotifications.framework 添加到 Linked Frameworks Libraries p>

2nd) 像这样将这些行添加到您的 AppDelagte

#import <UserNotifications/UserNotifications.h>
@interface AppDelegate () <UIApplicationDelegate,UNUserNotificationCenterDelegate>

3rd) 获得响应

- (void)userNotificationCenter:(UNUserNotificationCenter *)center  
willPresentNotification:(UNNotification *)notification  withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler  
NSLog( @"for handling push in foreground" );  
// Your code
NSLog(@"%@", notification.request.content.userInfo); //for getting response payload data
  

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response  withCompletionHandler:(void (^)())completionHandler     
 NSLog( @"for handling push in background" );  
// Your code
NSLog(@"%@", response.notification.request.content.userInfo); //for getting response payload data
 

【讨论】:

“notification.request.content.userInfo”中没有第一个参数 应该是:response.notification.request.content.userInfo @biloshkurskyi.ss 我更新了我的答案谢谢你指出来。

以上是关于iOS - 如何在 iOS 10 中集成推送通知?的主要内容,如果未能解决你的问题,请参考以下文章

如何从iOS中的设置处理推送通知允许

ejabberd 和推送通知

如何在 iOS 的自定义 ViewController 中集成 Firebase 通知?

如何在 node.js 中集成 FCM 以进行推送通知?

QuickBlox 向离线用户推送通知问题

在 iphone 中解析推送通知