[TIMOB-20272] iOS: Interactive notifications with activationMode background don't work when app is not already in memory
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Critical |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2017-08-11T18:16:21.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 6.2.0 |
Components | iOS |
Labels | core, defect, ios |
Reporter | Steven van Loef |
Assignee | Hans Knöchel |
Created | 2016-01-12T17:04:47.000+0000 |
Updated | 2017-08-11T18:38:11.000+0000 |
Description
For interactive notifications to work you have to listen for event 'localnotificationaction' (and/or remotenotificationaction for push notifications). I have an action set to activationMode: Ti.App.iOS.USER_NOTIFICATION_ACTIVATION_MODE_BACKGROUND which should allow execution of some code without launching the app to foreground. This only seems to work when the app is already/still in memory.
Expected behavior would be that it always works even if the app has never been started yet. This works fine with WhatsApp for example. Looking at the ObjC code (mainly in TiApp.m) for this and placing some debug logging here and there I don't see how this can work. The code in TiApp.m triggers the fireevent but at that time the JS part of the app has not fully loaded yet, causing the event to be missed in JS because the listener could not be setup yet.
Another issue that will cause this not to work is that when handling an interactive notification in the background is that the full app is loaded (at least attempted). This will fail because UI interaction is not allowed when in background.
Code in TiApp.m that should handle this:
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
and
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler
Hello, Can you provide a sample case of the issue that's not working when the app in not in the memory or not started yet. Please provide a sample code and steps to follow to properly reproducing the issue. Thanks.
Hi Sharif, I took the example code from http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Interactive_Notifications and added an if statement to also check for the 'reject' action and if picked log it to the console. Here is a demo of it: https://www.dropbox.com/s/z8bv3xg43d2sb95/appc5830.gif Steps I did: 1) open app, trigger notification, kill app, wait for notification, pick 'Accept' action, app opens, alert is NOT displayed (not expected) 2) kill app, open app, trigger notification, kill app, wait for notification, pick 'Reject' action, app does not open because this is a background action, in console 'reject action in background' should be displayed: not happening (not expected) 3) kill app, open app, trigger notification, wait for notification, pick 'Accept' action, app opens, alert IS displayed (expected) 4) kill app, open app, trigger notification, wait for notification, pick 'Reject' action, in console 'reject action in background' is displayed (expected) So step 3 and 4 work as expected, this is because the app is already loaded in memory. Step 1 and 2 do not work as expected, not even step 1 where the app opens, no alert is shown. For step 2 nothing happens, well almost nothing. If you run this on device and check the device log while performing this step you'll notice that iOS does start the app after tapping the Reject action. This is where "- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler" gets called by iOS. But at that point the JS code has not loaded yet, the event listener has not been added yet, but the ObjC code already sends the notification to a place that's not alive yet. Regards, Steven
Log of simulator:
Just noticed something interesting. It seems like the 'localnotificationaction' event is never called in background but the 'notification' event is and it has the same data. Is this then the correct way to handle these cases? If so, the documentation needs to be clear on that: use 'notification' event to handle background (and when app is not yet loaded) trigger actions and use 'localnotificationaction' for other cases. Also which event should be used when handling remote interactive notification actions (push notifications) in this case? I mean what is the equivalent for 'notification' when dealing with remote notifications (and the app is not in memory yet)?
Hello, Starting with Release 3.4.0, you can create interactive notifications, where users can respond to application notifications without launching the application to the foreground. The user needs to reveal notification actions in the notification, then press a notification action to respond to the notification. This feature is available on devices running iOS 8 or later. To create an interactive notification, the applications needs to: 1. Create and configure notification actions 2. Create notification categories and assign notification actions to them 3. Register the notification categories 4. Monitor the localnotificationaction event to respond to local notifications and the remotenotificationaction event to respond to push notifications. Yes, When the app in not in the memory yet, it should be recommended to use push notification. Thanks.
Why did you close this issue? This is not solved. The previous comment is not a solution. I'm using push notifications, some of which have interactive actions. The remotenotificationaction event never gets called when the app is not in memory for actions that have activationMode of Ti.App.iOS.USER_NOTIFICATION_ACTIVATION_MODE_BACKGROUND like I mentioned before and showed in the example. Same thing for the localnotificationaction event, it is never called when app is not in memory. Please reopen this ticket to get this solved.
Just validated it using the below code and reproduced the issue, when the app was closed before. It's a valid issue, will move it to TIMOB. Demo:
*PR*: https://github.com/appcelerator/titanium_mobile/pull/9040 *Test-Cases*: 1) Notifications
2) User Activities
3) Shortcut-Items
Basically what happens is what [~ludolphus] suspected: The boot-delegates are fire before the
Ti.App.iOS
namespace is able to register the events. We used some delays 1-2sec for background-mode events and user-activities before, but that was no suitable solution anymore. The way it is now implemented, we are able to queue the events and process them when the Core is ready (which makes the events fire earlier now). Thanks again [~ludolphus] for the help on tracking things down! *EDIT*: For the QE: As I also fixed thebackgroundtransfer
,shortcutitemclick
andcontinueactivity
events, please test those events as well. I've validate all notifications so far, but need to set-up test-cases for the above as well.[~hknoechel] can you please do 6.2.0 backport?
PR (6_2_X): https://github.com/appcelerator/titanium_mobile/pull/9295
FR passed, PR merged for the backport version. Fix found in SDK 6.2.0.v20170810134640. Awaiting for build issues on master to be fixed before merging on master. Edit 8/11: PR merged on master. Closing ticket as fix also seen on 7.0.0.v20170811094808.