In iOS, we all know that there is AppDelegate method applicationWillTerminate, and it is called when my app is closed by user when it is currently running(i.e. not in background). But I want to do something(save data, for example) when my app is terminated(closed by user or killed by OS) when it runs in background.
PS: my app can run in background.
Do you have any solutions? thanks.
Sorry but you should use applicationWillTerminate:
This method lets your app know that it is about to be terminated and
purged from memory entirely. You should use this method to perform any
final clean-up tasks for your app, such as freeing shared resources,
saving user data, and invalidating timers. Your implementation of this
method has approximately five seconds to perform any tasks and return.
If the method does not return before time expires, the system may kill
the process altogether.
For apps that do not support background execution or are linked
against iOS 3.x or earlier, this method is always called when the user
quits the app. For apps that support background execution, this method
is generally not called when the user quits the app because the app
simply moves to the background in that case. However, this method may
be called in situations where the app is running in the background
(not suspended) and the system needs to terminate it for some reason.
So if you need to save data ALSO when user manually kill the app use applicationDidEnterBackground that it's called if your app support background mode.
If you need to execute code when your app isn’t running, there are
several options open to you depending on what you’re trying to do.
Background fetch will let your app run in the background for about 30 seconds at scheduled intervals. The goal of this is to fetch data
and prepare your UI for when the app runs next.
Push notifications let your app fetch fresh data from your server. You can make a message appear on the device if you want, but it’s not
required – silent push notifications let you skip that part.
Local notifications let you display an alert to the user, along with any media attachments you want and some options for the user to
select from. If they choose those options then your app can be
launched in the foreground or background to handle them.
From:
https://www.hackingwithswift.com/example-code/system/how-to-run-code-when-your-app-is-terminated
You can also use Silent Push Notification
as I mentioned in a similar question: https://stackoverflow.com/a/57245980/6157415
Related
Is this possible to download data when the application is terminated? I want to download data at a particular time to get new updates in my API. And if data download in the background after that if user run application again, the user has no need to wait for download new data.
If the application [server] that is serving the content has been terminated the answer is no. (There is nothing to continue writing data out to the buffer/stream)
You will need to provide more details regarding your applications concerns to determine if there is some sort of caching layer that could be implemented which would allow your downloads to be resumable in some cases.
No, you can't continue download when your app get terminated by user! Your app must require to remains in background state!!! Because if user force close app that means, he doesn't want to run it anymore. If your app is suspended by system then it can be wake up but not if it's terminated by user!
See there are two types of termination, one if user do from app switcher and another one is if iOS do. If user terminates its not possible to do any thing in background. But in case of iOS terminates your app it can continue download or background task. Check about NSURLsession background download for more info.
https://developer.apple.com/documentation/foundation/url_loading_system/downloading_files_in_the_background?language=objc
https://www.raywenderlich.com/567-urlsession-tutorial-getting-started
I agreed with other answer. You can't continue download when your app get terminated by user!
But I'm not agree with you about Background app refresh.
Background app refresh
Here is Apple's definition :
After you switch to a different app, some apps run for a short period of time before they're set to a suspended state. Apps that are in a suspended state aren’t actively in use, open, or taking up system resources. With Background App Refresh, suspended apps can check for updates and new content.
And here some parts from another doc
Apps that need to check for new content periodically can ask the system to wake them up so that they can initiate a fetch operation for that content.
...
Enabling this mode is not a guarantee that the system will give your app any time to perform background fetches.
iOS try to predict when user will launch app on next time. iOS launches the app in background to update content right before the momnent when user launch the app.
Another approach to update content is use the Push Notifications
Here is from Apple's doc
If your server sends push notifications to a user’s device when new content is available for your app, you can ask the system to run your app in the background so that it can begin downloading the new content right away.
Notification’s payload must include the content-available key with its value set to 1. This key lets iOS to know that the notification is silent.
Pushing Updates to Your App Silently.
I was wondering which event in my AppDelegate is called when I swipe out my running app from within the app switcher? My target iOS is >= 7.0 (i.e. with multitasking support).
Maybe I just don't understand the multitasking paradigm itself... When I swipe out my app from within the app switcher, the app is going to be terminated, right? Or does it continue running in the background?
EDIT-1: Why I am asking: During startup of the app, I connect to my Linux game server by plain sockets. I want to disconnect the socket when the app terminates.
EDIT-2: I am not sure if I am using background execution. I register my network socket within a run-loop object to asynchronously receive inputs from the server socket. Moreover I have a kind of network service installed that periodically tests for network connectivity. This service is using SCNetworkReachabilityScheduleWithRunLoop.
There are situations where applicationWillTerminate: will be called and sometimes not.
More can be read up from the Apple documentation here
Excerpt:
For apps that do not support background execution or are linked
against iOS 3.x or earlier, this method is always called when the user
quits the app. For apps that support background execution, this method
is generally not called when the user quits the app because the app
simply moves to the background in that case. However, this method may
be called in situations where the app is running in the background
(not suspended) and the system needs to terminate it for some reason.
What's interesting to note is that
After calling this method, the app also posts a
UIApplicationWillTerminateNotification notification to give interested
objects a chance to respond to the transition.
It is - (void)applicationWillTerminate:(UIApplication *)application
I have tried various samples from the web (the last one being this one) in order to get a better understanding of NSUrlSession.
What I was hoping to see: file downloads will continue even if the app that triggered them gets killed (for instance by the user through the task manager). However this does not seem to happen.
Is this a configuration issue or does background file transfer not work if the app gets terminated?
I thought the whole idea was that iOS will restart the app.
If the system kills your app and your background session has active downloads, your downloads will continue and the system will launch your app when the downloads complete. However, if a user force quits your app, all tasks get cancelled.
Documentation for backgroundSessionConfigurationWithIdentifier:
If an iOS app is terminated by the system and relaunched, the app can
use the same identifier to create a new configuration object and
session and retrieve the status of transfers that were in progress at
the time of termination. This behavior applies only for normal
termination of the app by the system. If the user terminates the app
from the multitasking screen, the system cancels all of the session’s
background transfers. In addition, the system does not automatically
relaunch apps that were force quit by the user. The user must
explicitly relaunch the app before transfers can begin again.
No - the app is not relaunched for background downloads when the user has force quit.
The iOS8 documentation for application:didReceiveRemoteNotification:fetchCompletionHandler: says:
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.
I have created background nsurlsession to perform download task. It worked well when the app was in background. However, download task seems to be canceled and failed when I closed the app (double click "Home" button and swipe up), and it made me to download from the beginning again when I relaunched the app. According to Apple document, background transfer works even the app is no longer running. Am I doing anything wrong?
From the NSURLSessionConfiguration Class Reference:
If an iOS app is terminated by the system and relaunched, the app can use the same identifier to create a new configuration object and session and retrieve the status of transfers that were in progress at the time of termination. This behavior applies only for normal termination of the app by the system. If the user terminates the app from the multitasking screen, the system cancels all of the session’s background transfers.
So, while background transfers will continue if iOS itself closes your app during the normal course of things, if you force the quit from the multitasking screen, it will kill all your transfers.
The app is not relaunched for background downloads when the user has force quit.
The iOS8 documentation for application:didReceiveRemoteNotification:fetchCompletionHandler: says:
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.
In the first paragraph of NSURLSession documentation, we can observe:
This API provides a rich set of delegate methods for supporting
authentication and gives your app the ability to perform background
downloads when your app is not running or, in iOS, while your app is
suspended.
Now notice where it states:
or, in iOS, while your app is suspended.
It looks like only OS X applications have the ability to finish background tasks while your app isn't running.
I've built a small ios app which perform periodic updates.
I'm registering my app for background fetches with a callback handler.
When app goes background I'm continue to receive callbacks over the time (every 20-30 minutes, event days later).
Once my app is terminated - the callback handler will be not executed any more.
Is it excepted behavior? I failed to find any mentions about activation from terminated state in Apple documentation on this.
ps: activation from the terminated state is crucial for my app. The approach of the activation could be any, except of user interaction.
It seems that if an app is terminated it will be awaken neither by background fetch nor push notification. No official documentation on this though.
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.
Source here