How to detect app force quit event in iOS - ios

I am working on an iOS app for which I need to show a local notification when users force quit the application.
I tried to use the "applicationWillTerminate" iOS callback but it doesn't work when the app is killed from the multi-tasking window.
From the official Apple documentation, it appears that there is no way to detect the force quit app event (from the multi-tasking window) but I found that Alarmy app can show a notification when we force quit the application.
Questions:
How this "Alarmy" app can show the force-quit app notification? What possible approach is used by the application?
Are there any workaround solutions for this problem?
I would appreciate any suggestions and thoughts on this topic. Thank you.

When app terminates, the following delegate will be called:
- (void)applicationWillTerminate:(UIApplication *)app
{
}
To receiving the terminate event, you need to add the UIApplicationExitsOnSuspend key to your info.plist.

Related

Is there any delegate which fires while app is killed from background only?

Is there any delegate which fires while app is killed from background in iPhone X?
No. Your app is suspended. It can't get any events because it isn't running. If the app is running in the background, you might get applicationWillTerminate: if the user terminates the app, but I wouldn't count on it. Basically you should assume when the app goes into the background that it might be terminated.
Yes there is please refer to Pushkit framework, I have done that same task using this library, Here]1 is the link all you need to set up, if you want to try in kill mode, you need to do this on Xcode => go to edit scheme in your Xcode.
After setting all this you will be able to do all you need

Which method is called when app which has been killed from background in iphone is opened again?

After our app has been removed/Killed from the background either by iOS or by the user himself, which method is called when the same is opened again?
Well i believe, 'applicationDidFinishLaunchingWithOptions' is called because since app has been killed, its is relaunched again. Is that so?
You are right ! As it describe in the Apple Documentation:
You can also read the full version here

iOS: Handling interactive notifications when app is not running in background

I am trying to implement interactive local notifications for my app, and in particular via implementing this method:
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
The method works fine except if the user kills the app and then receives an interactive local notification. In that case there is no indication that the local notification action (button click) was received.
I am looking for help/advice on 2 fronts
(1) Is anyone able to confirm/deny that handleActionWithIdentifier is not called when the app is not running at all (i.e. not even in background mode). I went through the relevant programming guide and I noticed that much of the language talked about foreground and background mode without addressing the third possibility. However, I'm looking for something more solid than 'it doesn't work for me' to put this to rest. Is there anything in the docs that says these should or should not work after the app is killed?
(2) How can I log in the Xcode console after I have killed my app? Every time I try this, I notice that when I relaunch the app I no longer have logging. This is important because I need to prove one way or another whether I receive interactive notification messages from user clicks after the user has killed the app.
I would appreciate any and all advice on this matter. Thank you.
If the app is terminated then when it gets launched via the notification then didFinishLaunchingWithOptions gets called with a key of UIApplicationLaunchOptionsLocalNotificationKey. The value of this key is an NSDictionary containing the payload of the local notification
You can't log in the Xcode console from the app if the app isn't running of course. But if you run the app not via Xcode you can watch the output by going to Window|Devices then selecting your attached device.
If you are relaunching the app via Xcode and logging isn't there this is probably a bug in Xcode, I've noticed recent versions of Xcode is having problems displaying logging. If this happens try the Devices output.

Prevent UILocalNotifications when the app is killed

I have developed IBeacon App. When the app is in background mode and I enter the beacon region the UILocalNotification is triggered. But the thing is that if I kill the app the notification still triggers. I use locationMgr.RequestAlwaysAuthorization (); to catch the location change when the app is in background. I have written background-safe task to enlarge my background time on iPhone.
I have tried to use UIApplication.SharedApplication.ApplicationState but it returns true when the app is in background only, not terminated.
I use locationMgr.RequestAlwaysAuthorization (); since DidEnterRegion is called only with location set to ALWAYS.
In a word I am searching for the solution how to monitor EnterRegion&ExitRegion only in background and active mode. NOT WHEN THE APP IS KILLED
Before iOS 7.1 this was the default behavior of iOS, and everybody complained about it. Since iOS 7.1, beacon monitoring will launch apps even if they are killed.
What you need is a way to detect if an app has previously been killed when it is launched again so you can suppress notifications. Unfortunately, I am unaware of any way to do this.
There are several reasons why an app would be terminated (not running):
because the user actively terminated it (double-tap on home button, swipe app up)
because the OS needed the memory, and terminated it
because the OS updated the app, and terminated it
because the device was rebooted, and the app was not launched yet
Do you want to avoid notifications in all cases, or only in the first one?
If you want to avoid notifications in all cases, you can try removing the local notification in your AppDelegate's applicationWillTerminate: method (or an observer for the UIApplicationWillTerminateNotification notification):
- (void)applicationWillTerminate:(UIApplication *)application
{
[application cancelLocalNotification:<insert here the notification you saved>];
}
(you may alternatively use cancelAllLocalNotifications, or search for the notification using scheduledLocalNotifications).
If you only want to avoid those notifications in the first case, I'm afraid I'm not aware of any way to detect the user having actively terminated the app.

Will iOS launch my app into the background if it was force-quit by the user?

I am triggering a background fetch by using the content-available flag on a push notification. I have the fetch and remote-notification UIBackgroundModes enabled.
Here is the implementation I am using in my AppDelegate.m:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(#"Remote Notification Recieved");
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"Looks like i got a notification - fetch thingy";
[application presentLocalNotificationNow:notification];
completionHandler(UIBackgroundFetchResultNewData);
}
When the app is running in the background, it works fine. (The notification is received and the app triggered the "looks like i got a notification" local notification, as the code above should do).
However, when the app is not running and a push notification is received with the content-available flag, the app is not launched and the didRecieveRemoteNotification delegate method is never called.
The WWDC Video Whats New With Multitasking (#204 from WWDC 2013) shows this:
It says that the application is "launched into background" when a push notification is received with the content-available flag.
Why is my app not launching into the background?
So the real question is:
Will iOS perform background tasks after the user has force-quit the app?
UPDATE2:
You can achieve this using the new PushKit framework, introduced in iOS 8. Though PushKit is used for VoIP. So your usage should be for VoIP related otherwise there is risk of app rejection. (See this answer).
UDPDATE1:
The documentation has been clarified for iOS8. The documentation can be read here. Here is a relevant excerpt:
Use this method to process incoming remote notifications for your app.
Unlike the application:didReceiveRemoteNotification: method, which is
called only when your app is running in the foreground, the system
calls this method when your app is running in the foreground or
background. In addition, if you enabled the remote notifications
background mode, the system launches your app (or wakes it from the
suspended state) and puts it in the background state when a push
notification arrives. However, the system does not automatically
launch your app if the user has force-quit it. In that situation, the
user must relaunch your app or restart the device before the system
attempts to launch your app automatically again.
Although this was not made clear by the WWDC video, a quick search on the developer forums turned this up:
https://devforums.apple.com/message/873265#873265 (login required)
Also keep in mind that if you kill your app from the app switcher
(i.e. swiping up to kill the app) then the OS will never relaunch the
app regardless of push notification or background fetch. In this case
the user has to manually relaunch the app once and then from that
point forward the background activities will be invoked. -pmarcos
That post was by an Apple employee so I think i can trust that this information is correct.
So it looks like when the app is killed from the app switcher (by swiping up), the app will never be launched, even for scheduled background fetches.
You can change your target's launch settings in "Manage Scheme" to Wait for <app>.app to be launched manually, which allows you debug by setting a breakpoint in application: didReceiveRemoteNotification: fetchCompletionHandler: and sending the push notification to trigger the background launch.
I'm not sure it'll solve the issue, but it may assist you with debugging for now.
The answer is YES, but shouldn't use 'Background Fetch' or 'Remote notification'. PushKit is the answer you desire.
In summary, PushKit, the new framework in ios 8, is the new push notification mechanism which can silently launch your app into the background with no visual alert prompt even your app was killed by swiping out from app switcher, amazingly you even cannot see it from app switcher.
PushKit reference from Apple:
The PushKit framework provides the classes for your iOS apps to
receive pushes from remote servers. Pushes can be of one of two types:
standard and VoIP. Standard pushes can deliver notifications just as
in previous versions of iOS. VoIP pushes provide additional
functionality on top of the standard push that is needed to VoIP apps
to perform on-demand processing of the push before displaying a
notification to the user.
To deploy this new feature, please refer to this tutorial: https://zeropush.com/guide/guide-to-pushkit-and-voip - I've tested it on my device and it works as expected.
Actually if you need to test background fetch you need to enable one option in scheme:
Another way how you can test it:
Here is full information about this new feature:
http://www.objc.io/issue-5/multitasking.html
I've been trying different variants of this for days, and I thought for a day I had it re-launching the app in the background, even when the user swiped to kill, but no I can't replicate that behavior.
It's unfortunate that the behavior is quite different than before. On iOS 6, if you killed the app from the jiggling icons, it would still get re-awoken on SLC triggers. Now, if you kill by swiping, that doesn't happen.
It's a different behavior, and the user, who would continue to get useful information from our app if they had killed it on iOS 6, now will not.
We need to nudge our users to re-open the app now if they have swiped to kill it and are still expecting some of the notification behavior that we used to give them. I'm worried this won't be obvious to users when they swipe an app away. They may, after all, be basically cleaning up or wanting to rearrange the apps that are shown minimized.
This might help you
In most cases, the system does not relaunch apps after they are force
quit by the user. One exception is location apps, which in iOS 8 and
later are relaunched after being force quit by the user. In other
cases, though, the user must launch the app explicitly or reboot the
device before the app can be launched automatically into the
background by the system. When password protection is enabled on the
device, the system does not launch an app in the background before the
user first unlocks the device.
Source:
https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
For iOS13
For background pushes in iOS13, you must set below parameters:
apns-priority = 5
apns-push-type = background
//Required for WatchOS
//Highly recommended for Other platforms
The video link: https://developer.apple.com/videos/play/wwdc2019/707/

Resources