Remote Notification iOS 8

Objective CIos8Apple Push-Notifications

Objective C Problem Overview


How can I get the Device Token for remote notification in iOS 8? I used the method didRegisterForRemoteNotificationsWithDeviceToken in AppDelegate in iOS < 8, and it returned the device token. But in iOS 8, it does not.

Objective C Solutions


Solution 1 - Objective C

Read the code in UIApplication.h.

You will know how to do that.

First:

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

add Code like this

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
#ifdef __IPHONE_8_0
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert       | UIUserNotificationTypeBadge       | UIUserNotificationTypeSound) categories:nil];
  [application registerUserNotificationSettings:settings];
#endif
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}

if you not using both Xcode 5 and Xcode 6 ,try this code

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge      |UIRemoteNotificationTypeSound      |UIRemoteNotificationTypeAlert) categories:nil];
  [application registerUserNotificationSettings:settings];
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}

(Thanks for @zeiteisen @dmur 's remind)


Second:

Add this Function

#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    //register to receive notifications
    [application registerForRemoteNotifications];
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
    else if ([identifier isEqualToString:@"answerAction"]){
    }
}
#endif

And your can get the deviceToken in

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

if it still not work , use this function and NSLog the error

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

Solution 2 - Objective C

The way to register for iOS 8 and keep supporting older versions

UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge                                                                                         |UIUserNotificationTypeSound                                                                                         |UIUserNotificationTypeAlert) categories:nil];
    [application registerUserNotificationSettings:settings];
} else {
    UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
    [application registerForRemoteNotificationTypes:myTypes];
}

and in the app delegate add

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

iOS8 can receive silent notificaions without asking for permission. Call - (void)registerForRemoteNotifications. After this application:didRegisterForRemoteNotificationsWithDeviceToken: will be called

Note: the callback with the token is only called if the application has successfully registered for user notifications with the function below or if Background App Refresh is enabled.

Check the Settings for you app if any notification type is enabled. If not, you will not get a device token.

You are now able to obtain silent notifications with

aps {
content-available: 1
}

in the notification payload

But notifications that appear still needs permission. Call

UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:notificationSettings];

This code should ask for permission.

You should now be ready to get push notifications

Solution 3 - Objective C

In my case I had made the necessary updates to request push notification access for iOS 7 and iOS 8, however I had not implemented the new callback for when an iOS 8 user grants access. I needed to add this method to my app delegate.

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

Solution 4 - Objective C

If you are using Xamarin.iOS to build your mobile application, you can use this snippet of code to request push notification registration

if (UIDevice.CurrentDevice.CheckSystemVersion(8,0))
{
    UIUserNotificationType userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
    UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(userNotificationTypes, null);
    UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
else
{
    UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
    UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
} 

Also you will need to override DidRegisterUserNotificationSettings method to get the device token returned from the APNS server:

public override void DidRegisterUserNotificationSettings(UIApplication application, UIUserNotificationSettings notificationSettings)
{
    application.RegisterForRemoteNotifications();
}

Solution 5 - Objective C

The answer of Madao (https://stackoverflow.com/a/24488562/859742) is right but....

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge

should be more "correct"

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];

Those flags have the same bit mask values and thats why both would work but UIUserNotificationSettings requires UIUserNotificationType not UIRemoteNotificationType.

Apart from that I would call

[application registerUserNotificationSettings:settings];

In the AppDelegate method (depending on the granted rights),

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings

Solution 6 - Objective C

I thing the better way to keep backward compatibility we can go with this approach, it is working for my case hope work for you. Also pretty easy to understand.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
    }

Solution 7 - Objective C

UIUserNotificationType types = UIUserNotificationTypeBadge |
    UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
    
    UIUserNotificationSettings *mySettings =
    [UIUserNotificationSettings settingsForTypes:types categories:nil];
    
    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
    
    [application registerForRemoteNotifications];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionquang thangView Question on Stackoverflow
Solution 1 - Objective CMadaoView Answer on Stackoverflow
Solution 2 - Objective CzeiteisenView Answer on Stackoverflow
Solution 3 - Objective CKyle CleggView Answer on Stackoverflow
Solution 4 - Objective CMichael KniskernView Answer on Stackoverflow
Solution 5 - Objective CIlker BaltaciView Answer on Stackoverflow
Solution 6 - Objective CHussain KMR BehesteeView Answer on Stackoverflow
Solution 7 - Objective CDevang TandelView Answer on Stackoverflow