G'day iOS Guru's,
I have searched extensively for an answer, but can't find one (I bet the first response to my question will be to another similar question, but I cant find it).
Anyway, my problem is that I am running a simple map app that the user can drop pins on the map with a customised circle overlay around the dropped pin.
When the app goes into the background (iphone locked or home button pressed), if I re-enter the app within ~ 5 mins, the pins are still there and the app reopens to the last screen.
All good.
However, if I leave the app in the background for longer than 5 mins, the app restarts and all the pins are lost.
I have "Application does not run in background = NO" in the plist, and also enabled "App registers for location updates" under Required background modes.
How can I prevent the app from restarting after it enters the background and load the last opened view?
iOS can, and will, terminate your app while it's in the background if it needs additional resources to carry out whatever's going on in the foreground.
You need to ensure that your data is saved/archived when your app is terminated, and unpacked when re-launched so as to go back to where the user last was. The traditional way to do this is to use the applicationDidEnterBackground method, which is called when your app is suspended. You can then save all the data you need in order to resume cleanly in case your app is later terminated.
However, if you're targeting iOS 6 and upwards you can take advantage of a new feature - State Presumption & Restoration (link to documentation). State restoration off-loads some (but not all) of the heavy lifting onto iOS, and it can automatically snapshot your UI and provides easier ways to preserve and restore data.
in your AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
// Save your data
}
Related
If I send my app to background by clicking the home button and wait a certain time (perhaps 1 or 2 hours).
What will happen if i tap on the app icon now?
Will the app relaunch or simply be brought from background to foreground?
Quick "prologue":
Welcome to the wonderful world of stack overflow (SO), I myself am rather new here, but found it much friendlier to use welcome you anyway!
Just in case you haven't: Before you ask a question please look around a bit on SO in case someone else has asked the same thing, but if you can't get your question answered from that, then you should of course ask your own question.
Answer:
This question has no definite answer, because it depends. When you tap the home button your app enters, as you've said, the background and is still running to a certain degree. However after done so, the apps life cycle is up to iOS (the devices operating system) to determine. iOS controls and checks memory and CPU usage (etc..) of the device, and if you start another activity while your app is in the background that makes the available memory and CPU etc of the device not sufficient, iOS will terminate any apps in the background to not waste those resources (or battery etc). If so your app will relaunch next time you tap on it.
Although if you don't do anything performance heavy it is more likely that iOS keeps your device running in the background.
I'm not sure about the exact conditions and such the iOS works on, but i would say its very likely your app will have gotten terminated and is relaunched after 1 or 2 hours "in the background". Additional conditions apply if the device is locked during that period.
For proper documentation of this i would recommend reading Apples documentation for handling App State Transitions and/or the api for UIApplicationDelegate on apples developer website. Where you can see what the different methods in the AppDelegate does and how they interact.
Edit (answer to comment):
A way to relaunch the app everytime it goes into background?
Hm, yes, but also no. I'm not 100% sure about this (never encountered that "wish" before), but you can do this in your AppDelegate: (It will basically crash your app, but beware that apple does not encourage you to crash your own app anywhere). Doing this might stop the app from passing through apple store review process (i.e. your app might not be accepted to the App Store).
func applicationDidEnterBackground(_ application: UIApplication) {
exit(0)
}
Check out the answer to these post for a bit more information: call exit(0) in iphone app , objc - Proper way to exit iPhone application?.
Personally I would recommend you to work around it and don't do this. Also remember that when your app will enter the background applicationWillResignActive will be called and when the user opens it again, applicationDidBecomeActive gets called so you can do a reload or something from there if you want to refresh any data.
Whenever we press the home button in our device, the application releases the currently being used memory and moves to background stage. However, when we press this application app icon again it brings the app on top of the iPhone screen and occupies memory again. This is definitely not the relaunch because relaunch depends upon the UIApplicationDelegate method
didFinishLaunchingWithOptions. When we are switching app from background to foreground then applicationWillEnterForeground method fires.
For better understanding, the following link might be useful
iOS Application Life Cycle
I am new to IOS development. I am still confused about data lifecycle inside the UIViewController. If I had a property called "userData" and I identified it as following
let userData : UserData! {
didSet {
// do something
}
}
and I used this data to handle click events later. What could happen if the app went to background then -say after 1 hour- the user reopened the app and found the page still displaying the content, then he clicked a button inside page. I am not sure if userData will be kept or the page lost it when it went to background!?
My app crashes when I come later and open it, but I am not sure if that's because of identifying variables like this or not
The term background is confusing. Apple generally uses it to mean a state where your app is still getting processor time but another app is front-most. You have to ask if you want more than a few seconds of background time when the user hits the home button.
If the user presses the home button and then swaps to another app your app gets a few seconds of background time to save it's state, and then it moves to the "suspended" state, where it is still in memory, but no longer gets processor time.
Once you've been suspended, if the user switches back to your app while it's still in memory you get a resume message and then you continue running, with everything that was in memory still in memory.
However, once you've been suspended your app can be terminated at any time after that without any warning. That's why you have to save your app state when you get suspended.
If you do get terminated then the next time the user selects your app you get re-launched. You are usually expected to restore state and make it look like the app simply picked up where it left off, but it is a cold launch.
If you are crashing after your app is resumed (not terminated) then you might need help debugging that crash.
My app needs the device location with an accuracy of about 10 meters. If the app is launched, it usually takes e.g. 10 sec to get the required accuracy. This delay is OK. However when the app is „in use“ (see below), the delay should be less, e.g. 1 sec.
The problem is the following:
When the user switches off the display, the app transits from the active state to the background state (and the delegate methods applicationWillResignActive and applicationDidEnterBackground are called).
Normally, location updates are not done in background. So, next time the app transits from background to active state (delegate methods applicationWillEnterForeground and applicationDidBecomeActive are called), the location manager needs again e.g. 10 sec to reach the required accuracy. This delay in unfortunately not OK.
To avoid it, the app could do location updates in the background. This works fine.
The disadvantage is that these background location updates continue, even if the app is no longer used, because the user pressed the home button and switched to another app. This is disturbing at least for 2 reasons: The GPS hardware is unnecessarily active and uses power, and the user is notified that my app is using the device location although this is no longer required.
My question thus is:
Is it possible to determine if another app becomes active?
If so, background location updates could be switched off.
Is it possible to determine if another app becomes active?
No, your app only knows if it's in background or in foreground handling delegate events. Know if user opened another app or is in the home screen is not possible.
These background location updates continue, even if the app is no longer used, because the user pressed the home button and switched to another app.
I think you're right. You could start a timer when application goes in background and update localization only for an estabilished period (one minute?). Then, at the end of timer count save last localization coordinates. Timer is used to avoid unnecessary updates, then if user doesn't open again your app after a reasonable time, maybe it's because he's using other apps or he locked the device.
When the app comes to the foreground again, if timer is still active you're good. Otherwise show last localization saved and show a small "banner" to advise user that localization could not be accurated for the first 10 seconds (until when required accuracy has been reached)
Can someone tell me a scenario when an iOS application directly enters the background state?.
Here I have quoted the lines from iOS Application Programming Document in multitasking section.
If your app is launched into the background instead—usually to handle
some type of background event—the launch cycle changes slightly to the
one shown in Figure 3-3. The main difference is that instead of your
app being made active, it enters the background state to handle the
event and then is suspended shortly afterward.
Added ...
In the iOS Application Programming Document if you see the figure 3.3 titled Launching an app into the background, the flow is like this User taps app icon -> main() -> UIApplicationMain() -> Enter background. Is there any chance when the app directly enters background when an user taps app icon. I interpreted the image like this. Is it correct?
Thanks.
One scenario for a background launch (App X)
X registered for location background mode in its Info.plist
X is run by the user, and registers for significant location changes while running
The user switches to another app Y, so X goes to background and is then suspended (it will be returned to background mode whenever there is a significant location change to handle, and then be suspended again)
The app Y eats lots of memory, so suspended applications (including X) get kicked out of memory
a significant location change comes in. Now X is launched into background.
Scenario
Lets say you had registered your application for Local/Push notification. Then your application will launch in background run some code which have written inside your applicationDidEnterBackgroud: delegate method and then it terminates immediately.
Check listing 2
Apple documentation
EDIT:
Applications might also find local notifications useful when they run
in the background and some message, data, or other item arrives that
might be of interest to the user. In this case, they should present
the notification immediately using the UIApplication method
presentLocalNotificationNow: (iOS gives an application a limited time
to run in the background). Listing 2-2 illustrates how you might do
this.
What delegate is called in this situation if I have an app running.
Over time, if iPad is set to lock after 2 mins, what is its state? Does the app still run? or does it suspend?
I'd like to know thanks
If the iOS device automatically locks after a period of inactivity, the same thing happens as when it's locked by pressing the lock button: the app briefly goes into the background before being suspended. (Unless of course it is an audio-playing app or other app that requests extra execution time, in which case it may stay in the background longer, or indefinitely, without being suspended).
In terms of UIApplicationDelegate methods, applicationWillResignActive: will be called first, followed by applicationDidEnterBackground:.