samedi 25 avril 2015

iOS 8 push notification action buttons - code in handleActionWithIdentifier does not always run when app is in background


I am adding two action buttons to my push notifications on iOS 8: an Accept button and a Deny button. Neither button will open the app, but different server requests will be made depending on which button is pressed. Here's my setup:

+ (void)requestForPushNotificationToken {
    UIApplication *application = [UIApplication sharedApplication];
    // if ios 8 or greater
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc] init];
        [acceptAction setActivationMode:UIUserNotificationActivationModeBackground];
        [acceptAction setTitle:@"Accept"];
        [acceptAction setIdentifier:@"ACCEPT_ACTION"];
        [acceptAction setDestructive:NO];
        [acceptAction setAuthenticationRequired:NO];

        UIMutableUserNotificationAction *denyAction = [[UIMutableUserNotificationAction alloc] init];
        [denyAction setActivationMode:UIUserNotificationActivationModeBackground];
        [denyAction setTitle:@"Deny"];
        [denyAction setIdentifier:@"DENY_ACTION"];
        [denyAction setDestructive:NO];
        [denyAction setAuthenticationRequired:NO];

        UIMutableUserNotificationCategory *actionCategory = [[UIMutableUserNotificationCategory alloc] init];
        [actionCategory setIdentifier:@"ACTIONABLE"];
        [actionCategory setActions:@[acceptAction, denyAction]
                        forContext:UIUserNotificationActionContextDefault];

        NSSet *categories = [NSSet setWithObject:actionCategory];

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

Then, in my delegate method, I am specifying actions to be taken when user pressed one of the action buttons:

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
    if ([identifier isEqualToString:@"ACCEPT_ACTION"]) {
        // Sending a request to the server here
    }
    else if ([identifier isEqualToString:@"DENY_ACTION"]) {
        // Sending a request to the server here
    }

    if (completionHandler) {
        completionHandler();
    }
}

The ideal scenario is that the user does not need to launch the app in the whole process; pressing Accept or Deny will make different calls to the server. With the code above, I am seeing very unstable behaviors with the button actions:

  • A lot of times, the code in the action handler doesn't execute when app is in background and no server calls are made at all; when this happens, if I tap on my app icon and launch my app, the handler code will immediately be run upon launching the app.
  • Occasionally, the handler code gets triggered and everything works fine. Server requests are made as soon as I press one of the action buttons.
  • If I put breakpoints in my Xcode and step through the handler code, the success rate is also 100%. I do not need to launch my app, and handler code gets executed when button is pressed.

Could anyone please help me figure out what's causing such unstable behavior? Thanks in advance.


Aucun commentaire:

Enregistrer un commentaire