Sunday, July 27, 2014

How to support push notification for iOS7 and iOS8?

iOS8 interactive notification

The whole concept is to quickly respond to a notification without context switch. iOS8 interactive notification also called actionable notification allows you to respond to messages, reminders and invites without having to leave your app or unlock your phone.

Deprecated API

Since iO8, registerForRemoteNotificationTypes has been deprecated in favour of registerUserNotificationSettings: with registerForRemoteNotifications. The API unifies notification settings whether it's a remote or user notification.

What about if...

You want to register for remote notification and you ...
use Xcode5 with iOS7
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
use Xcode6 with iOS8
    UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
use Xcode6 with iOS7
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
use Xcode6 with iOS7 or iOS8
Testing wether or not the registerUserNotificationSettings: API is available at runtime, means you're running on iOS8.
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    }
use (Xcode6 with iOS8 or iOS7) and (Xcode5 with iOS7)
The macro __IPHONE_OS_VERSION_MAX_ALLOWED conditionally compiles the code so that the new Xcode6 compiler won't complain about the deprecations and the XCode5 won't complain about nonexistent symbols. for Xcode6 running on iOS7 we use the trick explained in previous section.
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    }
#else
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
#endif

11 comments:

  1. Do you know if an app built with XCode 5 (and using registerForRemoteNotificationTypes) will still work on iOS8? Or will APNS stop working when the user upgrades to iOS8?

    ReplyDelete
  2. in order to deploy to ios8 you need to upgrade to Xcode6 and you will run into a compilation issue with registerForRemoteNotificationTypes

    ReplyDelete
    Replies
    1. Ok, but I mean an app previously built with XCode 5, in the app store. How will that work when a user updates to iOS 8? Haven't found any clear answer on that.

      Delete
    2. I was also wondering the same thing. Did you ever find out?

      Delete
    3. Yes, an app built with XCode5 with the old way of using APNS will work as before on iOS 8, I have verified this on a real device.

      Delete
  3. It helps me. Thanks.
    Regarding the last piece of code, we have checked #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
    we need not check this again: if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {

    ReplyDelete
  4. Ist there anywhere a full code/tutorial for notifications in ios7 & ios8? I don´t get it done :-(

    ReplyDelete
  5. Check my other post: http://corinnekrych.blogspot.fr/2014/07/ios8-interactive-notification-available.html

    ReplyDelete
  6. Thank you for this useful information, very helpful

    ReplyDelete
  7. Does "application" refere to AppDelegate reference ?

    ReplyDelete
  8. Better you'd written :

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {

    before this changes I wasn't able to go inside if block code though I have iOS-8 running on my device.

    ReplyDelete

Note: Only a member of this blog may post a comment.