Coming back from suspended state - iOS - iphone

When my app comes back from a suspended state is behaving in a very strange way, so I would like to restart it from scratch in this situation.
But I don't want to restart it every time it enters the background and comes back to the foreground.
Is it possible to know if the app comes back from a suspended state or if it was just a background state?
Thanx in advance!

I believe that the short answer to this is No.
Apple's state documentation isn't explicit, but I would argue that the documentation implies that didEnterBackground is called in this situation, as it states that there are methods associated with each transition, but it isn't explicit, so I tested.
I wrote a short test program that uses region monitoring to force an app to transition from suspended to background. This isn't definitive, as it is also difficult to know if an app has transitioned from background to suspended, but after a couple of minutes, apps should be in suspended unless they're using background modes or tasks.
Firing the region change ( through the debugger), I got didExtRegion callback, but no didEnterBackground.

Related

Execute code upon app termination in swift

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.

background operation

Is it possible to put your app in the background, and have a counter that once expires, wakes up the app and have the app does some action? I know it's basic, but I just cant seem to have it work. Where do I put this counter + action? Under app did enter background?
Thanks for the help.
I don't think that this works in general:
You are allowed only to run in the background for specific tasks:
Apple doc tells which tasks that are:
One of that tasks is receiving GPS messages.
As long as you have GPS enabled and your app configured that it uses GPS for background, your app stays alive in the background.
If you disable GPS some time later it will suspend, and not wake up till the user activates it.
So to realize your problem you have to stay active in the background (e.g by reading GPS).
You can start the timer in AppDelegate:applicationDidEnterBackground or similar
If you need more time to shutdown, you explicitly can request for more time, there is one method for that. I dont know what happens if you request more at regulary intervals

iPhone force kill while in background using CLLocationManager

Does anyone know how to detect if the user has force killed my app while the app is in the background? In the Apple documentation for the applicationWillTerminate: method it says this:
"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."
From my testing, when I force kill the app, my app still looks like it is tracking my location (the arrow is still at the top). But the cllocationmanager delegate method is not getting called until the app is relaunched, and the manager is stopped then started again. What is the best way, if any, to handle this situation?
Thanks!
UPDATE:
After looking into this post: Behaviour for significant change location API when terminated/suspended?
I'm still left with a problem. Because I'm using the method startUpdatingLocation, rather than the startMonitoringSignificantLocationChanges method. It looks like the application is only relaunched if you are logging significant changes. It seems to me that's it's kinda a hack to log significant changes just so I don't lose the app. Any ideas?

Running apps in background?

Is it possible to keep a socket connection alive in background, to be able to push new data and alert users at all times?
The answer to this question is a definitive yes. If you are in the background state, then you can keep a connection open and process messages from a server.
Unfortunately the complexity here is that you don't have a lot of control over the state your application is in:
foreground - The user has tapped your icon and the app is running with the UI visible.
suspended - The user was previously running your app in the foreground, but suspended it by hitting the home button or receiving a call. Basically your app is 'freeze dried' and will remain inactive until it is resumed by the user (starting where it left off) or it is terminated by the OS (see below).
background - The app was previously running in the foreground but has moved to the background state as a result of something the user has done. Normally your app will move to the suspended state in this case, but there are things you can do as the developer to prevent the instant 'freeze dry' and go into the background instead (see below). Your app will also be in the background state if it is woken up for a significant change event.
terminated - Your app has been unloaded from memory and the next time it starts will be from scratch. This is what happens when you double click the home button and then tap the x next to your app icon. It moves the app from the suspended state into the terminated state. This will also happen if the OS decides it needs room for more recently running apps and your app has been suspended for a long time.
So obviously the trick here is how do I stay in the background state as a long as possible. There are a couple of ways to do this:
Beg for more time - You can get up to 10 minutes of additional background processing when your app is closed if you ask for it.
Use UIBackgroundMode - You can declare youself a voip, audio or location app by adding the corresponding UIBackgroundMode value to the pList. There are special requirements for these types of apps which you can check out here.
So these approaches are not without their own problems (getting approved on the store being one of them) and as such I tend to agree with the other answers that using push notifications is probably your best approach for notifying your users. With the notification improvements in iOS5 this is going to be the best user experience going forward.
You can keep a socket connection alive (or do whatever else you want) in the background for about 15 minutes after your app closes. There are also more specialized background processing modes (specifically, audio, voip, and location) which Apple supports if your app fits into one of their supported categories. See here.
If you want to keep sending the user notifications indefinitely, you want to use the Apple Push Notification Service. This allows your app to continue to receive notifications when it's not running, and it conserves resources since there's only one connection to the APN service at a time.
You can definitely alert users with local and push notifications.
And as far as I know, you can keep a connection open only for limited time.
Look here for more details.

NSTimer callbacks while iPhone application is inactive

This question seems to be the essence of several others on this forum. I believe that it is possible for the active iPhone application to continue running, and specifically, to continue receiving timer call-backs, after it has entered the inactive state (either through the idle timer kicking in the screen lock, or through the user pressing the hardware lock button).
The documentation specifically says that while an application is inactive, it is executing, but not dispatching incoming events (I'm not giving a link because I'm jumpy about NDA - should I relax about that? Is this whole post a breach? sigh).
Also, two answers by user "Ambr Str" directly state that it is possible to continue receiving timer call-backs, and he supplies a snip of code to achieve it (I can't link to this because I'm a new user, sorry - search for the question: "What happens to an iPhone app when iPhone goes into stand-by mode?" to find his answer).
I've tried to create my call-backs as he suggests, but once my application becomes inactive, the call-backs cease firing.
I've just noticed that while the iPhone is plugged in, if the application becomes inactive (due to idle time out or me pressing the sleep button), call-backs do continue to occur - perhaps I should get my users to carry a battery pack with them ;-)
There is a good answer to this question on Apple's forums. Search for "Timer" and "Eskimo" (the helpful chap who provides the answers).
In brief, shortly after the application becomes inactive, the phone really does go to sleep. The only way to prevent this is to be playing some audio (or for some audio to be playing in a background application). While audio is playing the phone will not sleep, and your application continues to be run.
It is suggested that playing stay awake audio is a hack, and that you shouldn't do it if at all possible. I think in my application (which performs audio playback interspersed with silent periods), the approach is valid, if not ideal!
I have an app. which includes an embedded webserver. I'm planning to offer an option of disabling auto-sleep IFF the server is turned on, AND the device is on power. So you might consider checking the batteryState property of UIDevice. So if batteryState != UIDeviceBatteryStateUnplugged, go ahead and disable idle timer. (note: the docs say that UIDeviceBatteryStateUnknown will be returned when in simulator.)
You'll also want to listen for UIDeviceBatteryStateUnplugged notifications and set batteryMonitoringEnabled appropriately.