I'm new to swift and programming so I'm not sure if or how this is possible, but could anyone tell me if I can designate code to be executed when the user terminates the app from the multitasking menu? I just have a line of code that I would like to execute at that time, but I'm not sure where to put it in my project.
Thanks!
If the user terminates the app from the multitasking menu, your app is killed dead. It is not terminated "in good order". You do not get an event at that time. It's just like the scene in 2001: A Space Odyssey where the scientists are already in suspended animation and HAL pulls the plug on them.
The art of Cocoa / iOS 8 programming is the art of the possible. Adjust your desires to fit the reality of the events you do get. You get an event when the user leaves your app, so if there is something you need to be sure to do, do it then, as you may never get another chance.
As matt said, when the app is terminated from the multitasking menu, none of your code is run, it's just killed.
Try putting your code into the application delegate's applicationWillResignActive(_:) method. This will run any time your app becomes inactive, though. In other words, more often (all the time) than being terminated in the multitasking menu. It'll run when there's an incoming phone call or text, I believe it will run if there is a notification with an alert, it will run when the user presses the home button.
Related
When I restart the device my app is on it won't preserve the state it had once I open up the app again, it will be as if it's the first time I open, losing the session and having to re-login, how can I make my app preserve its state even through a device reboot? Like Twitter does, for example.
I'll try a bit more formal answer based on the comments you added above. I'll start by saying that the link Tim posted is something you should familiarize yourself with.
When your app is running, it's in the Foreground state. When you "exit" an app with the Home button, you're not really quitting it; you're just pushing it to the Background state. after a few seconds in background state, the OS automatically moves the app to the Suspended state. If you come back within a few minutes, your app is still in memory, so the OS just puts it back on the screen the way it was.
However, if you leave the app alone for a while and use other apps, the OS can--at any time and without warning--purge your app from memory. This is known as the "Not Running" state. Now, when the open the app again, it has to start from scratch. Obviously, the same thing happens when the device restarts--all apps are purged from memory.
The trick, then, is to save essential information about the app state whenever it enters the background state. You can use the app delegate's didEnterBackground method, or register for the UIApplicationDidEnterBackgroundNotification and invoke a method in your active view controller (or any other class, for that matter). Either way, you should save whatever state information you can.
How do you save this information? There are several strategies. For a simple app, perhaps you can register a few setting as NSUserDefaults. Or maybe you can write out a file containing whatever data the user was working on. It's really up to you.
Then, whenever the app launches, check for the presence of that saved data (however you chose to write it out), and set up the UI accordingly. To the user, it will appear as though the app never quit, which is exactly what Apple wants them to think.
So here is the issue I am facing. Certain portions of the application I am building open some c network sockets that allow connections to various servers/services. However, if the application goes to sleep, these socket connections are lost, and error out when trying to reload them. So what I want to do is basically notify the user when the app launches again, that the application needs to be restarted. The main question is, can I present them with a button that will kill the app by using exit(0) without my app getting rejected?
Apple says that the user should be in control of when the app is killed, and in this case I see that they are, but I am not sure of Apple's opinion on this. Has anyone else used this? Have you been rejected for this? Thanks in advance for any advice!
EDIT:
Thank you everyone for your advice. I am trying to take everything into consideration, but because the app needs to be submitted ASAP, I just need to know, if we can not get another solution, if the above proposed solution, will get rejected or not.
Your application delegate receives notifications when significant events affect the life of the application. Rather than ask your user to recreate a session, you should attempt to discontinue network operations and then resume them at the appropriate times in the application's lifecycle automatically.
You can gracefully kill network sockets (amongst other things) in any number of places as the application prepares to exit or enter the background via callbacks in your application delegate:
applicationWillResignActive:
applicationWillEnterBackground:
applicationWillTerminate:
Potentially reconstruct sockets in:
applicationDidBecomeActive
applicationWillEnterForeground
Have you tried not allowing the app to run in the background? Then it will be killed whenever the user exits to the home screen. This might be a bit aggressive, but would solve the problem. From Apple's opting out of background execution:
"If you do not want your application to remain in the background when
it is quit, you can explicitly opt out of the background execution
model by adding the UIApplicationExitsOnSuspend key to your
application’s Info.plist file and setting its value to YES.
When an application opts out, it cycles between the not running,
inactive, and active states and never enters the background or
suspended states.
When the user taps the Home button to quit the application, the
applicationWillTerminate: method of the application delegate is called
and the application has approximately five seconds to clean up and
exit before it is terminated and moved back to the not running state."
See also: How to prevent my app from running in the background on the iPhone
The documentation is pretty explicit about this, "There is no API provided for gracefully terminating an iOS application." See Technical Q&A QA1561
How do I programmatically quit my iOS application?.
To be blunt, terminating an app to cleanup a socket is just like dealing with memory management by forcing an app to exit instead of calling release.
What about bringing up a modal view controller telling the user to quit the application? You could make this view controller without any dismiss button, so the user is obligated to kill the app.
I'm setting "Application does not run in background" to NO
which means, it can go background and resumed later.
I'm putting some code in "applicationDidEnterBackground",
and I would like to force quit the app when desirable. (when there's nothing to do in background.)
I read 'exit' is not recommended.
Can I post a message which will result in something like applicationWillTerminate maybe?
Edit
Let me clarify why I would want that,
I want my app to run background when it's downloading something.. via beginBackgroundTaskWithExpirationHandler
But if user isn't downloading anything, I can safely quit the application.
Thank you
The general Apple approach on iOS is that applications should never terminate themselves, for any reason.
It's important to understand that when your application is 'running' in the background, it's not really running: the 'Application does not run in background' key is basically there to ensure backwards compatibility with applications built for iOS 3 and lower, which tend to make certain assumptions about how the user will enter the app. There are very few reasons why a new app wouldn't support it.
Basically, don't bother: I suppose you could technically call exit(), but Apple will hate you for it, and it's bad style for the platform.
You don't need to worry about this.
If you have work to do in the background and you set up a background task then it'll run for as long as it needs and execute its handler when done.
What you don't seem to be aware of is that if you have nothing to do in the background, your app is simply suspended and in fact does not run.
As this is the case, there's nothing you need to do, quitting the app won't gain you anything that you don't already get with suspension.
I am running my iPod touch application and then go in background and change the device language from Settings application and try to bring that application on foreground. My application gets restarted and I do not land on the screen where I left the application when I went into the background.
Is this because a KILL signal is sent by settings application when language was changed? Is it the desired behavior?
I wasn't aware the switching the language would cause apps to be terminated, but that's not shocking. It's a very straightforward way to get what the user wants. Your problem isn't the language change, though. The problem is that you're not responding correctly to a notification of termination. You can be terminated at any time when you're in the background, and it's your job to deal with it.
Your application delegate should implement applicationWillTerminate: (or you can observe UIApplicationWillTerminateNotification wherever it is convenient). When you receive this, you should save off sufficient information to get yourself back to where you were when you restart. As much as possible, you should make it look to the user that you did not terminate. The easiest place to save state is usually in NSUserDefaults, but you can use any mechanism you like.
Handling application restart is one of those things that separates excellent iOS applications from "good enough."
What is the proper way of ending an application on the iPhone when you are finished with it?
thanks,
anton
Jaanus is referring to this paragraph in the Apple iPhone Human Interface Guidelines
Stopping
People quit an iPhone application by opening a different application. In particular, note that people don’t tap an application close button or choose Quit from a menu. In iOS 4.0 and later, and on certain devices, the quitting application moves to a suspended state in the background. All iPhone applications should:
Be prepared to quit at any time. Therefore, save user data as soon as possible and as often as reasonable.
Save the current state when stopping, at the finest level of detail possible. For example, if your application displays scrolling data, save the current scroll position.
iPhone applications should never quit programmatically because doing so looks like a crash to the user. There may be times, however, when external circumstances prevent your application from functioning as intended. The best way to handle this is to display an attractive screen that describes the problem and suggests how users can correct it. This helps users in two ways:
It provides feedback that reassures users that there’s nothing wrong with your application
It puts users in control, letting them decide whether they want to take corrective action and continue using your application or press the Home button and open a different application
If certain circumstances prevent only some of your application's features from working, you can display either a screen or an alert when users activate the feature. Although an alert doesn't allow much flexibility in design, it can be a good choice if you can:
Describe the situation very succinctly
Supply a button that performs a corrective action
Display the alert only when users try to access the feature that isn’t functioning
As with all alerts, the less users see them, the more effective they are. For more information about creating alerts, see “Using Alerts.”
There is no way for an iPhone application to quit/terminate itself. Apple actively advises against it in their Human Interface and/or programming guides (can't remember which exactly) because it would look like a crash to the user.
An app should not terminate by itself.
Also, avoid showing an "exit screen" that prompts the user to quit the app manually as in iOS4, the app might stay open in the background and your user would be stuck in that exit state.