35

Before iOS4.0 clicking the home button on iPhone exits the application, and Apple had in their guide that programmatically exiting the application was not accepted.

now everything changed in iOS4.0, clicking the home button puts your app in a suspended mode (multitasking).. and I think there should be a clear way for the user to exit the app, like an exit button.

is it now OK with apple? and how can it be done?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Tamer
  • 537
  • 1
  • 7
  • 15
  • 2
    Note that clicking the home button only suspends apps compiled with SDK 4.0. Apps compiled with earlier SDK's (and 4.0 apps that [opt out](http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/CoreApplication/CoreApplication.html#//apple_ref/doc/uid/TP40007072-CH3-SW24)) do not suspend, they terminate. – progrmr Jun 23 '10 at 03:10
  • Here's a good article on the changes Apple made and where to change your methods: http://www.drobnik.com/touch/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/ – fearmint Jul 05 '10 at 04:07

11 Answers11

50

You can set the Info.plist key UIApplicationExitsOnSuspend to make sure the app is completely terminated.

Joost Schuur
  • 4,417
  • 2
  • 24
  • 39
  • 7
    +1 Yes you can opt out of background execution and have your app terminate instead of suspending, [read the docs here](http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/CoreApplication/CoreApplication.html#//apple_ref/doc/uid/TP40007072-CH3-SW24) – progrmr Jun 23 '10 at 03:08
  • 1
    The "correct" answer in this thread does not answer the question asked, pretty bad form. (Even though it has merit) In my case I have an app with sensitive information and I would prefer to "log out" every time and the easiest way to do this is to quit. – Marius Aug 19 '11 at 17:11
  • It's not a complete answer, since part of it was asking whether it is acceptable. It is ok with Apple, but not in place of suspending the app. An exit button is the conscious intent of the user, so is perfectly acceptable, though they want you to try and get by without one. – iND Jan 02 '12 at 17:27
  • 1
    Why would anyone do this though? iOS will suspend your app when it background = 0 CPU cycles and 0 battery drain. If the OS needs the memory it will eventually terminate your app, and free the memory. The upside of suspension is that your app "launches" a lot quicker when coming back from a suspended state instead of relaunching. – Maciej Swic Jun 10 '13 at 12:50
24

No still shouldn't do this.

You have handlers for the different stages, so this is how you should do it. There's no point in exiting manually. If you restart the app, ideally it would start where you left off, so this is either by resuming or by starting and loading the old state.

No reason for exit.

Edit

As this keeps popping up again: iOS Human Interface Guidelines says "Don't Quit Programmatically". And we have seen many reports of apps that had calls to exit() in them in the past.

Exiting instead of suspending by setting the appropriate key in the Info.plist file is perfectly fine, of course - but that's not a dedicated UI Button, just application-specific implementation of program exit by the home button.

Eiko
  • 25,601
  • 15
  • 56
  • 71
  • 2
    I can't see why it is not acceptable to put an exit button for the user. every time I double click the home button I have dozen of suspended apps, and they keep growing, which really annoys me, and I think all iPhone users will feel the same. – Tamer Jun 22 '10 at 21:33
  • 14
    You're thinking of it the wrong way. Those apps aren't your suspended apps. Those apps are just the apps that the user's used recently. The fact that some of them are in different stages of freeze is irrelevant on the iPhone. – Steven Fisher Jun 22 '10 at 23:08
  • @tewha, these are active apps (from user point of view), frozen or suspended, but not user just last used apps. I still think there should be a way to close the app, rather than stack them in the task list. – Tamer Jun 22 '10 at 23:17
  • What is the difference to the user? Why should he want to exit, if he doesn't notice a difference? It's not about ressources, as the apps will be killed if ressources get low. – Eiko Jun 22 '10 at 23:20
  • mmmmmmmmm... this way the task bar (switcher) is useless, imagine every app the user opens stays there, and if he wants to switch to another app he has to scroll among 30 apps or so. Anyway, I look all around and I think it is how Apple wants it :) . – Tamer Jun 23 '10 at 00:30
  • Even though this No answer was accepted, there is a way to make your app exit instead of suspending. See [Joost's answer](http://stackoverflow.com/questions/3097244/exit-application-in-ios-4-0/3098252#3098252) below. – progrmr Jun 23 '10 at 03:06
  • @progrmr: Sure, you can disable going to background, but you cannot give the user the choice (doing this in some of our apps). I thought question was how to programmatically *end* the program (and this is still dicouraged). How is preventing from going to suspend mode within the plist a "clear way for the user to exit the app, like an exit button"? – Eiko Jun 23 '10 at 09:06
  • I interpreted the question as how to get the pre-4.0 home button behavior, with his idea of an answer being an exit button. I agree with you that an exit button is not the solution, but there is a way to get the pre-4.0 behavior so no need for an exit button (in <4.0 the Home button was the exit button). – progrmr Jun 23 '10 at 13:47
  • 10
    I actually appreciated this answer. Sometimes when you're starting to develop, you don't stop to think through if what you want to do is the best thing for the user. Every once in a while it's refreshing for an answer on SO to be: "You shouldn't do that." I changed what I was trying to do to what I should be doing, and my app is far better for it. Thanks. – Joshua May 05 '11 at 19:07
  • What about the case when your app is doing things in the background (like transmitting location) and you want a clear way to stop your app? – rburhum Oct 10 '11 at 20:58
  • The answer is: it is ok with Apple, but not in place of suspending the app. An exit button is the conscious intent of the user, so is perfectly acceptable. For how it can be done, see the correct answer (the one with the most votes, not the one checked as correct). – iND Jan 02 '12 at 17:15
  • @iND Sorry, you missed the point here. Of course setting the Info.plist is ok (and totally acceptable by any means). But providing a dedicated button in your UI and make that close the app (be it background or real exit) IS NOT, and it is definitely against the rules that Apple provides. I wander how you can say that this would be acceptable/accepted. – Eiko Jan 03 '12 at 20:47
  • I have not read any documentation restricting "close button" functionality, but it is discouraged. Since I cannot prove that there is an absence, and you can prove that the restriction exists, let's see a link or a citation, please. – iND Jan 04 '12 at 00:23
  • Does "Don't Quit Programmatically" suffice? http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices.html#//apple_ref/doc/uid/TP40006556-CH20-SW27 Apps have been and will get rejected for calling exit(). I don't think that down voting (an old an accepted) answer is ok, just because you fail to know the details. – Eiko Jan 04 '12 at 10:10
8

There's a reason for programmatically invoked exit().

Suppose you have a voip app that is always started at boot and restarted when killed by the system e.g. when memory warning happens. Normally it's preferred behavior because you need to run in background in order to maintain your voip TCP sockets.

However, if the app supports multiple modes of operation — like a) run in background using TCP, and b) do not run in background but start only after accepting PUSH notification —, if the user uses the app in b) mode he doesn't fancy that the app is consuming memory that can be used for other apps.

So it would be nice if the app could check upon the start if it was started to the background and user wanted the app to run in b) mode and gracefully exit(0) so it's no longer automatically restarted.

ЯegDwight
  • 24,821
  • 10
  • 45
  • 52
6

Also see iOS Debugging Magic (Technical Note TN2239):

Be mindful that the iOS application lifecycle is under user control, meaning that iOS applications should not just quit. Your release build should only call abort in circumstances where it would have crashed anyway, and the abort call prevents damage to user data or allows you to more easily diagnose the problem.

While on the topic of determining the cause for premature exit, Understanding and Analyzing iPhone OS Application Crash Reports (Technical Note TN2151) might be of interest.

Sorry for going off topic a bit, but it relates to early exits and diagnosis.

Jeff

jww
  • 97,681
  • 90
  • 411
  • 885
3

Here are the steps for @Joost Schuur;s answer:

  1. Open your info.plist file

  2. Add The Key UIApplicationExitsOnSuspend or Select Application does not run in background

  3. Set the new key to YES or Fill in the tick box

Breakpoints in applicationWillResignActive and applicationWillTerminate will show it works.

jww
  • 97,681
  • 90
  • 411
  • 885
iMeMyself
  • 1,649
  • 13
  • 28
3

I had a real problem with this. There is a big point in exiting manually or prgramatically.

With previous iPhone OS, my app was writing out its state (first use or second time onwards, etc.) in a plist when it terminated. When the user came back, it wanted to show different things by reading the plist. Also, it wanted to show the first screen every time when the user came back after exiting.

With app becoming suspended in the background with iPhone OS4, the app comes back where it left off (i.e. showing the same screen wherever the user was on) and never changes the state of it, because applicationWillTerminate is now never called.

Becasue this is the behaviour desired most of the time (to be able to continue when you step out of the app temporary), there has to be a way to be able to choose, i.e. suspend it or quit.

Since setting the UIApplicationExitsOnSuspend=YES gives only one way (i.e. it always terminates when the HOME is pressed), this is not a solution I am looking for.

I want the app to know once the whole chain of steps are completed, opposed to just the sequence was suspended, and to quit itself at the right time.

To do this, I have to be able to terminate the app and write out the state once the use completed the entire sequence. Other times, I just want the app to be suspended.

If you tap the HOME button twice you can see the suspended apps. I can delete (quit) my app by touching it longer and touch the (-) symbol that comes up, but this is not so intuitive for the users and too many steps.

Another option is to have a Quit button as one of the Nav Tabs in my app, but that is ugly. For now, my only option seems to be opting to set the UIApplicationExitsOnSuspend=YES.

Yoichi
  • 12,233
  • 2
  • 18
  • 11
3

You can always use exit(1). This is a raw/forced exit with an integer for a code/reason. You can used this during development, like in simulation mode when you just want to terminate; as in NOW.

Cosmin
  • 21,216
  • 5
  • 45
  • 60
Frederick C. Lee
  • 9,019
  • 17
  • 64
  • 105
1

You're not supposed to do this. When the user wants to quit your app, he will press the HOME button.

When the user pushes the home button, you get a UIApplicationWillResignActiveNotification notification. Use that notification to tear down all your resources.

Basically your app should "hide in a corner" (consume as little memory as possible) when the user pushes the home button. However, there is a tradeoff as the more you tear down, the longer it takes for the app to be shown again when the user switches back (need to reload all your resources).

bobobobo
  • 64,917
  • 62
  • 258
  • 363
1

Just use below method to gracefully exit with animation

   @IBAction func MinimizeOrKillApp(){            
        UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)
        //Comment if you want to minimise app
        Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { (timer) in
            exit(0)
        }
    }

Output

Download sample code

It is not recommended and your app will be rejected. We all are the developers and We know to how to approve it from reviewer team

Apple developer question

Hitesh Surani
  • 12,733
  • 6
  • 54
  • 65
0

You can do this:

@IBAction func yourButtonAcation(_ sender: Any) {

    UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)

}
Patrick
  • 1,717
  • 7
  • 21
  • 28
-4

You can put an app programatically in background with this private command :

(but your app will get rejected if you use it)

[[UIApplication sharedApplication] suspend];
Philippe97
  • 380
  • 4
  • 9