iOS- How to integrate push notification in iOS 10?

2019-01-16 16:01发布

问题:

I have used following code for iOS 8,9 as:

 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];

Handle by delegate methods:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
//Handle according to app state
}

And //Handle actions

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

How to do same in iOS 10 using UserNotifications and UserNotificationsUI framework? also i need to support for iOS 8 and iOS 9?

回答1:

type converson

for Swift3

-

for sample see this

import the UserNotifications framework and add the UNUserNotificationCenterDelegate 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 12, 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
   }


回答2:

1st) Add UserNotifications.framework to Linked Frameworks and Libraries in General settings of your project

2nd) Add these lines to your AppDelagte like this

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

3rd) for getting response

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