Problem Description
I've discovered a bug where the app crashes when it receives some (3+) push notifications while the iPhone's screen is turned off and the app is in background.
Steps to reproduce
1. Create a new mobile project
2. Add this code to the app via app.js
var win = Ti.UI.createWindow({backgroundColor:"green"});
win.open();
var callbacks = {
types: [
Titanium.Network.NOTIFICATION_TYPE_BADGE,
Titanium.Network.NOTIFICATION_TYPE_SOUND,
Titanium.Network.NOTIFICATION_TYPE_ALERT
],
success:function(e){
console.log("SUCCESS",e.deviceToken);
subscribeACS(e.deviceToken);
},
error:function(e){
console.log("ERROR",new Date().toTimeString());
},
callback: function(e){
console.log("CALLBACK",new Date().toTimeString());
}
};
if(Ti.App.iOS.registerUserNotificationSettings){
function onUserNotificationSettings(){
delete callbacks.types;
Ti.Network.registerForPushNotifications(callbacks);
Ti.App.iOS.removeEventListener("usernotificationsettings",onUserNotificationSettings);
}
Ti.App.iOS.addEventListener("usernotificationsettings",onUserNotificationSettings)
Ti.App.iOS.registerUserNotificationSettings(callbacks)
}else{
Ti.Network.registerForPushNotifications(callbacks)
}
function subscribeACS(token){
var Cloud = require('ti.cloud');
Cloud.PushNotifications.subscribeToken({
channel: 'testChannel',
device_token: token
}, function (e) {
if (e.success) {
alert('Success');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}
3. Please replace the ACS keys with your own and the GUID with your own.
4. Install to device
ti build -p ios -T device
5. Open App
Allow it to retrieve a device token (used below)
6. Send 2 notifications
for i in seq 1 2
; do curl -X POST -F "channel=testChannel" -F "to_tokens=<DEVICE TOKEN>" -F "payload=$i" "https://api.cloud.appcelerator.com/v1/push_notification/notify_tokens.json?key=<YOUR ACS KEY>&pretty_json=true";done
7. You'll see "CALLBACK..." in console logs
8. Background app with home button
9. Send 3+ noticiations
for i in seq 1 3
; do curl -X POST -F "channel=testChannel" -F "to_tokens=<DEVICE TOKEN>" -F "payload=$i" "https://api.cloud.appcelerator.com/v1/push_notification/notify_tokens.json?key=<ACS KEY>&pretty_json=true";done
10. You should now get the crash in the console
Extra information
After some push notifications, the 'callback' function does not get called anymore. After that, when I turn the screen back on, the app crashes completely with an error in the console.
This happens on at least iPhone 5S, iPhone 6 and iPhone 6 Plus and is a critical bug since it prevents users from receiving important notifications!
I've put together an example app & server and closely documented this issue at:
https://github.com/VanCoding/iOS-Push-Bug
Using this you can reproduce this error on your own.
I'm using SDK 3.4.0.GA btw.
Hello [~VanCoding], I had difficulty testing this and will try again tomorrow. Curious, have you tried 3.4.1.GA? - Seth
Hi Seth I've now tried it with 3.4.1.GA. It's exactly the same :( Please let me know what difficutlies you have, I of course will help you with every single step, if needed. This bug is actually preventing me from publishing my app to the app store since our customer does not want the app to be published with this problem still existing. So I'm a bit in a hurry to fix this and of course have every time you need to me to help you. Sadly, you still have to generate the certificates & provisioning profiles on you own due to apples stupid polices... :( Thanks for working on this issue!
Hi Seth Now that the weekend's over I'm curious if you were able to reproduce the bug. You said that you'll try again. Have you already done it? Thanks :)
Hello [~VanCoding], I'm not entirely sure how to create the pfx you want in your setup step 2. Do I need to use keychain access to create it? Since I'm having trouble using your script I'll use our [ACS](http://docs.appcelerator.com/cloud/latest/#!/api/PushNotifications-method-notify_tokens) notify API to send push notifications in the same frequency. I'll let you know what happens. Thank you, Seth
Hello [~VanCoding] , Here is my test: Device: iPhone 6 (8.1.1) SDK: 3.4.1.GA 1. Open app, green screen shows, I receive device id in logs 2. I lock the phone and send 5 push notifications it quick succession. 3. I do not see any callbacks fired while device is locked. I do however see the callbacks if I repeat these steps while the app is open (expected behavior). I also see the callback if my device is locked, and I swipe to open a specific notification. I can share my slightly modified revision of your code (for using ACS) if you like.
Hi Seth That's strange! As described at the top, I DO get callbacks fired when the device is locked/the app is in background. But after some notifications (this can neen more than 5 notifications, but usually already happens after 3) i stop receiving them. And then, when I unlock the phone (and not open a specific notification), I get the error I mentioned and the app crashes. Its actually easy to generate the pfx file using "openssl pkcs12 -export -in my.cer -inkey my.key -out mycert.pfx", make sure the key and the certificate are both in the pem format. I'm of course interested in your code, maybe it's a problem with the way that node-apn sends the notifications, who knows. But the problem really exists. I've tried iPhone 5S, iPhone 6 & iPhone 6 Plus, so... :S
[~VanCoding], Do you leave the app and lock the device or just lock the device? While i work on creating the pfx you might want to check that your payload matches our documentation: http://docs.appcelerator.com/cloud/latest/#!/api/PushPayload Thanks, Seth
It actually does not matter if i first put the app to the background and then lock, or just lock. The app crashes as soon as it resumes either thorugh unlocking the screen (when the app was not paused before) or resuming the app. As you can see in my litte node-apn server, the payload should be okay. Nothing special about it :/ It's really strange that I get this error on all devices and you don't... Thank you very much for checking it!
Hello [~VanCoding], I was able to recreate your crash with your node script and our ACS push notifications. It looks like a problem when using
in Tiapp.xml. The problem disappears entirely if it is removed (possible temporary solution for you). And the error only occurs for x ≥ 3 messages while the app is backgrounded. I'll get some additional eyes on this issue.
Hi Seth I'm so glad that you cloud reproduce the bug and are now looking forward to fix it. Sadly, removing the UIBackgroundModes flag also means not receiving push notifications when the app is in background anymore. So that's not really a workaraound :( The only option I have is to wait until this bug gets fixed, which I hope will be the case as soon as possible. Thanks for your work, Seth :)
[~VanCoding], Might be worth exploring http://docs.appcelerator.com/titanium/latest/#!/guide/iOS_Background_Services to see if it still errors with that.
My customer forces me to ask you for the deadline until when this issue will be fixed. Can you give me an expected fix date? Thank you very much!
[~VanCoding], some of our team members are still working on the test cases so it might be several weeks at this point.
Dear Seth Toda, thank you for your reply. We do have a deadline from our customer to let the app work by end of January. It would be really great if you can help us with this matter so that we will not get in trouble with our customer. Thank you very much in advance.
If I'm not mistaken, removing the UIBackgroundModes 'remote-notifications' should not affect the app receiving push notifications in background. It will continue to work. See http://docs.appcelerator.com/titanium/latest/#!/guide/Subscribing_to_push_notifications-section-37551717_Subscribingtopushnotifications-ObtainingadevicetokenoniOS for how to receive push notifications on iOS 7 and > iOS8. Once push notifications are received in background or foreground, by pressing on the notification, it will bring the app to the foreground and proceed to the callback 'receivePush'. Unless you want to do something in the background when the notification is received, you will want to explore notification actions that will allow this in > iOS8. Example here: http://docs.appcelerator.com/titanium/latest/#!/guide/iOS_Interactive_Notifications
Closing ticket as invalid with reference to the above comments.