Reputation: 11081
We've encountered a very odd problem with regards to local notifications firing while our app is not running. By not running, I mean it is completely terminated (does not appear in the task list when you double-tab the home button).
Under normal running conditions, while the app is backgrounded, if the device is motionless for more than X number of seconds, the app will generate a local notification with warning a sound. 15 seconds after that, if no action has been taken, another local notification is generated with an emergency message.
Seemingly at random, hours or days after the app was terminated, the device will suddenly report a warning notification, followed by the emergency notification approximately 15 seconds later, just as though the app was running normally in the background. As stated, we have verified that the app is not listed in the running tasks lists, and appears to be completely terminated.
The app is registered for long-term background processing modes for location, audio, and VOIP.
When the app terminates (in applicationWillTerminate), we perform cleanup, which includes shutting down and nullifying timers, cancelling local notifications, etc.
I have two theories:
I wonder if anybody has encountered this odd issue, and if so, how we resolve the issue?
P.S - We are quite new to iOS development, so apologies in advance if we've overlooked something completely obvious
Update #1 Using log messages through xCode, I have observed applicationWillTerminate being consistently called when the application is shut down via task bar closure. There does seem to be a lot of debate about whether this behaviour can be relied upon, though, so I won't say conclusively whether I believe my observation to be consistent, but I am leaning in that direction. Any further insight on this, however, would be appreciated!
Update #2
I tried a new approach last night; until now we were scheduling a notification to fire "now" by using the [application scheduleLocalNotifications]
method, and setting the the date to the current time. Instead, I used the [application presentLocalNotificationNow]
method, and supplied no date/time. The app still functions properly, however it did not resolve the problem, as the 'ghost' notifications triggered randomly last night while the app was not running. I am wondering now if the issue is less of an 'old notification'-related problem, and more to do with the application being "woken up" due to some trigger as a result of our long-term background execution registration.
Upvotes: 1
Views: 2297
Reputation: 10129
Once your app has scheduled a UILocalNotification, they are handled by the operating system, not your app. So even if your app killed, they still go off.
So no, your app isn't still secretly running in the deep background, those are just notifications that you already scheduled that are going off. Are you possibly setting a repeatInterval on the notifications?
You can clear all the notifications by using:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
It's possible that your applicationWillTerminate is not getting called before your app gets killed as onnoweb stated. I'm not sure if that always gets called when the user closes the app in the task bar or not.
Edited to respond to comment:
My first thought is that you seem to be scheduling UILocalNotifications with incorrect fire dates. I suggest that you check the way that you're scheduling them. The only way that they could be going off a day after your app has been killed is if you scheduled them while your app was still running.
Edited to respond to further comment:
Teeg - I think that it's possible that applicationWillTerminate sometimes gets called when you kill the app, but is not guaranteed to be called. From what I've read, if your app is in a suspended state, the method does not get called. I don't know exactly how apps with long running background tasks work, but perhaps it switches between background and suspended states. I'm not sure. But the thing is, calling
[[UIApplication sharedApplication] cancelAllLocalNotifications];
will cancel all your notifications. So if one goes off after that, that is evidence that the method wasn't called. I guess another possibility could be that the method was called, but the app didn't have enough time to cancel all the notifications before it was killed. I'm not too sure about how much time you get to do stuff there. I would suggest again though that your best bet is to find out why those notifications are being scheduled in the first place.
Upvotes: 5