How to Handle Usernotifications Actions in iOS 10

How to handle UserNotifications Actions in iOS 10

I haven't checked whole code of yours, but at least, these function headers need to be changed as follows:

func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {

func didReceive(_ response: UNNotificationResponse,
completionHandler done: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {

Simple rule:
Remove private, add @escaping.

You may have received wrong suggestions from Xcode, but with making them private, Objective-C entry points are not generated. iOS runtime uses Objective-C selectors internally, so it cannot find your methods, thus, they are not executed.

Push notification issue with iOS 10

For iOS 10 using xCode 8 GM.

I have resolved my issue with following steps using xCode 8 GM for iOS 10:

1) In the targets, under Capabilities enable Push Notifications to add Push Notifications Entitlements.

2) Implement UserNotifications.framework into your app. Import UserNotifications.framework in your AppDelegate.

#import <UserNotifications/UserNotifications.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>

@end

3) In didFinishLaunchingWithOptions method assign UIUserNotificationSettings and implement UNUserNotificationCenter delegate.

#define SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

if(SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(@"10.0")){
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if( !error ){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
}

return YES;
}

4) Now finally implement this two delegate methods.

//============For iOS 10=============

-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{

//Called when a notification is delivered to a foreground app.

NSLog(@"Userinfo %@",notification.request.content.userInfo);

completionHandler(UNNotificationPresentationOptionAlert);
}

-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{

//Called to let your app know which action was selected by the user for a given notification.

NSLog(@"Userinfo %@",response.notification.request.content.userInfo);

}

Please remain the code as it is you are using for iOS 9,
Only add lines of code to support Push notification for iOS 10 using UserNotifications.framework.

UNNotificationCategory and minimalActions in iOS10

The minimalActions property of UNNotificationCategory existed in earlier betas, but I'm afraid it was removed in Xcode 8 beta 3, which explains why nothing links to that minimalActions page any more. Instead, set the regular actions property, and iOS will either show up to four or the first two depending on the context.

iOS- How to integrate push notification in iOS 10?

type converson

Sample Image

for Swift3

Sample Image

-

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

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
}

Action Button Not Appearing in Notification iOS 10

Actually i didnt swipe the notification. then i found that the button appears only when you swipe the notification. Terrible UI/UX design by Apple.

iOS 10 push notifications - how does willPresentNotification and didReceiveNotificationResponse work?

For remote and local notification in iOS 10 we have UserNotifications.framework. To handle notification there are two delegate methods of UNUserNotificationCenterDelegate available in UserNotifications.framework. You need to do the same code you are doing in didReceiveRemoteNotification method to get userInfo.

This two methods are available to handle userInfo according to your app requirements.

//UNUserNotificationCenterDelegate delegate methods to get userInfo

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {

//Called when a notification is delivered to a foreground app.

let userInfo = notification.request.content.userInfo as? NSDictionary
print("\(userInfo)")

}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

// Called to let your app know which action was selected by the user for a given notification.
let userInfo = response.notification.request.content.userInfo as? NSDictionary
print("\(userInfo)")
}

iOS 10 UNNotificationAction Open App from Background

Ok i have found the solution. We have to set UNNotificationActionOptions :)

UNNotificationActionOptions.foreground

Push Notifications not being received on iOS 10, but working on iOS 9 and before

Ok I have figured it out. I now have my original Push Notifications that was working on iOS 9 working on iOS 10 with Xcode 8 and Swift 2.3.

I implemented this by making the following changes to my AppDelegate:

1) On my project settings, under the Capabilities Tab, I scroll down to "Push Notifications" and turn it to "ON". This automatically generates an entitlements file that contains the key "APS Environment" and with value "development".

2) In AppDelegate.swift I make several code changes. I start by importing the UserNotifications framework:

import UserNotifications

Then I have AppDelegate implement the UNUserNotificationCenterDelegate protocol:

class AppDelegate: /*Some other protocols I am extending...*/, UNUserNotificationCenterDelegate {

Then I add the following method:

func registerForPushNotifications(application: UIApplication) {

if #available(iOS 10.0, *){
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert], completionHandler: {(granted, error) in
if (granted)
{
UIApplication.sharedApplication().registerForRemoteNotifications()
}
else{
//Do stuff if unsuccessful...
}
})
}

else{ //If user is not on iOS 10 use the old methods we've been using
let notificationSettings = UIUserNotificationSettings(
forTypes: [.Badge, .Sound, .Alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)

}

}

Then I call this newly created function inside didFinishLaunchingWithOptions:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
registerForPushNotifications(application)
...
}

I leave my didRegisterForRemoteNotificationsWithDeviceToken method unchanged:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
//Implement this. Do something with the token I receive. Send it to my push notification server to register the device or something else I'd like to do with the token.
}

Now I implement two new methods for iOS 10 to handle the receiving of Push Notifications:

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
//Handle the notification
}

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
//Handle the notification
}

I did not remove any of the methods I have previously implemented for Push Notifications in iOS 9.



Related Topics



Leave a reply



Submit