【问题标题】:iOS- How to integrate push notification in iOS 10?iOS - 如何在 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 吗?

【问题讨论】:

    标签: ios objective-c iphone apple-push-notifications usernotificationsui


    【解决方案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 我更新了我的答案谢谢你指出来。
    猜你喜欢
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    相关资源
    最近更新 更多