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


i adding 2 action buttons push notifications on ios 8: accept button , deny button. neither button open app, different server requests made depending on button pressed. here's 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 delegate method, specifying actions taken when user pressed 1 of action buttons:

- (void)application:(uiapplication *)application handleactionwithidentifier:(nsstring *)identifier forremotenotification:(nsdictionary *)userinfo completionhandler:(void (^)())completionhandler {     if ([identifier isequaltostring:@"accept_action"]) {         // sending request server here     }     else if ([identifier isequaltostring:@"deny_action"]) {         // sending request server here     }      if (completionhandler) {         completionhandler();     } } 

the ideal scenario user not need launch app in whole process; pressing accept or deny make different calls server. code above, seeing unstable behaviors button actions:

  • a lot of times, code in action handler doesn't execute when app in background , no server calls made @ all; when happens, if tap on app icon , launch app, handler code run upon launching app.
  • occasionally, handler code gets triggered , works fine. server requests made press 1 of action buttons.
  • if put breakpoints in xcode , step through handler code, success rate 100%. not need launch app, , handler code gets executed when button pressed.

could please me figure out what's causing such unstable behavior? in advance.

i have figured out reason. fact works , doesn't should have given me hint sooner.

according apple documentation of application:handleactionwithidentifier:forremotenotification:completionhandler::

your implementation of method should perform action associated specified identifier , execute block in completionhandler parameter done. failure execute completion handler block @ end of implementation cause app terminated.

i calling completion handler @ end of application:handleactionwithidentifier:forremotenotification:completionhandler method. however, fact sending requests server in handler code means end of implementation not @ end of method; real end lies within callback of requests. way code it, completion handler , callback on 2 different threads, , when completion handler runs before reaches callback, it'll fail.

so solution move completion handler callback methods of request, i.e., real "end of implementation". this:

[myclient sendrequest:userinfo withsuccessblock:^(id responseobject){     nslog(@"accept - success");     if (completionhandler) {         completionhandler();     } } withfailureblock:^(nserror *error, nsstring *responsestring) {     nslog(@"accept - failure: %@",[error description]);     if (completionhandler) {         completionhandler();     } }]; 

Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -