Search code examples
iosobjective-ciphoneapple-push-notificationsurbanairship.com

interactive notification UIMutableUserNotificationAction authenticationRequired is not working on one iphone ios 8.4


We are using interactive notifications on iOS 8, I set the authenticationRequired to Yes for interactive notification action so user should unlock his phone first to choose a action.

We published our app to HockeyApp for test. It is installed on three different iPhone 6 all with latest iOS 8.4 all iphones have passcode and TouchID enabled for unlocking the phone. on two iphones it works as expected when a push comes with screen locked for choosing Accept action for example user should unlock his phone first (via Passcode or TouchID)

but on one iphone it doesn't require unlocking! at user can perform actions. the weird thing is user needs touchID or passcode for unlocking his phone but for notification action it doesn't. here is our code but I Guess our code is fine since it works as expected on two phones, but here is the code just in case we are missing something: (We are using UrbanAirship for push)

UAConfig *config = [UAConfig defaultConfig];
[UAirship push].userNotificationTypes = (UIUserNotificationTypeAlert |
                                         UIUserNotificationTypeBadge |
                                         UIUserNotificationTypeSound);
[UAirship takeOff:config];
[UAirship push].userPushNotificationsEnabled = YES;
[UAirship push].backgroundPushNotificationsEnabled = YES;


UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc] init];
acceptAction.destructive = NO;
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
acceptAction.authenticationRequired = YES;
acceptAction.title = @"Accept";
acceptAction.identifier = NotificationAuthAcceptAction;

UIMutableUserNotificationAction *declineAction = [[UIMutableUserNotificationAction alloc] init];
declineAction.destructive = NO;
declineAction.activationMode = UIUserNotificationActivationModeBackground;
declineAction.authenticationRequired = YES;
declineAction.destructive = YES;
declineAction.title = @"Decline";
declineAction.identifier = NotificationAuthDeclineAction;

UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
[category setActions:@[acceptAction, declineAction] forContext:UIUserNotificationActionContextMinimal];
[category setActions:@[acceptAction, declineAction] forContext:UIUserNotificationActionContextDefault];
category.identifier = NotificationAuthCategory;

[UAirship push].userNotificationCategories = [NSSet setWithArray:@[category]];
[[UAirship push] updateRegistration];

Solution

  • This is an iOS 8 bug (Radar #18385104). When you compare two UIUserNotificationActions using the isEqual method, a few of the properties are set to the object you are comparing it to. Since all of the categories must be put into a set, the isEqual method is for each object, so the authorizationRequired and destructive properties can be modified for any of the actions.

    The good news is this issue seems to be fixed in iOS 9.

    Here is a unit test that shows the behavior - https://github.com/urbanairship/ios-library-dev/blob/6.1.0/AirshipLib/AirshipLogicTests/IOS8BugsTests.m