0

My iPhone app will download several content to Documents folder while running the application. I want to delete the downloaded files when app is going to terminate. My app runs on target 4.3 or more and ARC enabled. What is the best place to delete content from documents folder ?

- (void)applicationWillTerminate:(UIApplication *)application

is not being called when the app is terminated.

Srivathsa
  • 606
  • 10
  • 34
  • "applicationWillTerminate is not called when the app is terminated" - well, it **is** called, at least your app is not terminating, just suspends. –  Dec 24 '12 at 09:48
  • From the [documentation](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40006786), _For applications that support background execution, this method is generally not called when the user quits the application because the application simply moves to the background in that case. However, this method **may be called in situations** where the application is running in the background (not suspended) and the system needs to terminate it for some reason._ – iDev Dec 24 '12 at 09:51
  • Note that they used **"may be"**. So there is no guarantee that it will be called. – iDev Dec 24 '12 at 09:54

2 Answers2

2

Look for – applicationDidEnterBackground: instead of applicationWillTerminate.

In iOS 4.0 and later, this method is called instead of the applicationWillTerminate: method when the user quits an application that supports background execution.

applicationWillTerminate represents what "quitting" an app used to mean in pre-iOS4 world.

In modern (i.e., iOS4+) apps, when the user quits the app, the app goes to background and is suspended (so the user can reenter it quickly). So, the app is not actually terminated, still iOS can terminate it anytime if it needs to recover memory. This happens quite often, meaning that if you suspend your app and go back to it the day after, you will find that the app was terminated. The bad thing is that a suspended app will not receive a applicationWillTerminate message when it is terminated, so applicationDidEnterBackground: is the last "guaranteed" chance you have to clean up after yourself when the user quits the app.

Anyway, you can still get applicationWillTerminate to be called when the user quits your app (and your app terminated accordingly) if you set UIApplicationExitsOnSuspend in your app plist file.

For the sake of completeness, I will also add that applicationWillTerminate:

may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.

but this is a specific use case for an app which is actually running in the background (which is the case for a counted number of app types out there).

Summing it all up, the correct place to clean up the docs is:

  1. applicationDidEnterBackground if you are running iOS4+ and do not set UIApplicationExitsOnSuspend in your app plist file;

  2. applicationWillTerminate if you are running on iOS3 and set UIApplicationExitsOnSuspend in your app plist file.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • `applicationDidEnterBackground:` will be called whenever the app goes to background mode, not when the application is terminated unless `UIApplicationExitsOnSuspend` is set to `YES` in info.plist file. So it is not an alternative to `applicationWillTerminate`. – iDev Dec 24 '12 at 09:55
  • @ACB: thanks for your comment. I was referring to what Apple UIApplicationDelegate Protocol reference states about `applicationDidEnterBackground`. In many cases (practically always, except for background-running apps) entering the background is very close to being terminated, since your app can be terminated any time while suspended without receiving any notification. In any case, I expanded my answer for completeness. – sergio Dec 24 '12 at 10:01
  • Hi All, Thanks for so many responses. I am using iOS 4 plus and its not a background process. I want to clean my app downloaded content only at application termination. So you all mean to applicationWillTerminate: is the correct place ? – Srivathsa Dec 24 '12 at 10:07
  • @sergio, Yes, I have seen that statement in docs, and I feel that is a misleading one. Normally apps wont get terminated just by putting in background mode. It's just that there is a possibility of OS terminating it but it wont do it unless it is very much needed. So most of the times, when `applicationDidEnterBackground:` is called, it just represents a temporary suspension of the app and it doesn't represent the termination of app. User can still bring it back to foreground. The edited answer looks much better than the previous one. – iDev Dec 24 '12 at 10:08
  • 1
    @Sivannarayana, It is upto you to decide where to keep that. If you want to clean it whenever user minimizes the app(puts in background mode), you can do it in `applicationDidEnterBackground` method. But this will clean it whenever user just switches the app. But if you do this in `applicationWillTerminate`, there is no guarantee that `applicationWillTerminate` will get called on termination. – iDev Dec 24 '12 at 10:14
  • @Sivannarayana: `applicationDidEnterBackground:` is the last "guaranteed" chance you have to clean up after your app when the user quits; if an app goes to background, it is just a matter of time before it will be terminated. – sergio Dec 24 '12 at 10:19
  • 1
    @sergio, _if an app goes to background, it is just a matter of time before it will be terminated._ I am not sure what exactly you meant there, but I have a lot of apps kept in background mode for months now and I dont see them terminated at all. It just starts from where I left. So I would like to disagree to that comment. I feel there is a clear difference between terminating an app and suspending it. – iDev Dec 24 '12 at 10:35
  • @ACB: I agree on the fact that terminating is not suspending; as to your apps, you know that all depends on memory usage. E.g., open a heavy game and suspended apps will be wiped out from memory (at least on my devices :-)). And what about if the user reboots the device? What I see is that the lack of real multitasking on iOS makes this point a bit more complex than it could be, because a suspended app, though not yet terminated, is in a "unclear" status (due to the possibility of it being terminated without notice). – sergio Dec 24 '12 at 10:50
  • 1
    @sergio, Yes, I agree to that. But there is always an "if" there. 90% of the scenarios, it wont get terminated just by putting in background mode. Your comment makes us feels like the app will get terminated immediately after putting in background mode, which is not true. There is just a chance that it might get terminated that too only if the criterias you mentioned above are satisfied. Otherwise in normal cases it should work fine if you try to bring it in foreground. – iDev Dec 24 '12 at 10:54
  • Apple could have give us a delegate method when App is terminated like a cleanup call. My app contains confidential data which must be deleted after its usage. Use cases (1) App forcibly terminated by user (2) Due to memory OS may be terminating your app (3) When you restart your app etc.. In these scenarios only i want to cleanup documents folder because deleting every time app goes to background and download again when app invoked again is annoying user experience (specially when download takes considerable amount of time.) – Srivathsa Dec 26 '12 at 07:11
0

as you will not get an applicationWillTerminate: if you are running on iOS 4+ (and app does not quit forcefully on entering background) if you really looking for cleanup the stuff only if the application gets terminated, you should do it in applicaitonDidFinishedLaunching:

Saurabh Passolia
  • 8,099
  • 1
  • 26
  • 41
  • Your answer is misleading. `applicaitonDidFinishedLaunching` is called on app launch, not on terminate. – iDev Dec 24 '12 at 09:59