SWIFT: how to run a function even when user kills the app - ios

I am using swift 2 and Xcode7 for iOS9. I want to know if I can maintain a function (that checks for something to delete) running "forever" even if the user kills the app?
I am deleting contacts from the contact list according to some rules and time. It is running ok, but just with the app opened or in second plan. I want to make this app capable to delete those contacts even when the user kills it.

You can use background thread when user opens the app. But if the app will be terminated, there is no option to run functions.
Look for the app lifecycle here and redesign your architecture: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html

If the user kills the app it is no longer running, therefore your code is no longer running. There is no such state that your code/app can be in where this is possible.
By "kill", I don't mean "background". Backgrounding an app is different. Check Apple's docs on the different app states (see m.albin's answer) as well as various strategies for handling those app states.

func applicationWillTerminate(_ application: UIApplication) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
print("Application Will Terminate")
}

Related

save state when phone turned off

I created a saveState() method that uses UserDefaults to save certain settings at certain parts of my App. It works fine when I exit the App and return, but if I actually turn my (iOS) phone off, when I start the App again, the settings are not saved. In addition to those places where I call the saveState() method in the code, I also call saveState() in three AppDelegate functions: applicationWillResignActive, applicationDidEnterBackground and applicationWillTerminate. I have a loadState() function in viewDidLoad so any saved information will load at that time. Does anyone know what I am not doing re: saving/restoring settings when phone powered off?
When iphone off, AppDelegate's applicationWillTerminate
function Called when the application is about to terminate
how about use synchronize() after your saveState() called
In apple API https://developer.apple.com/reference/foundation/userdefaults/1414005-synchronize
Writes any modifications to the persistent domains to disk and updates all unmodified persistent domains to what is on disk.

iOS - How to guarantee that applicationWillTerminate will be executed

Is there A way to guarantee that the applicationWillTerminate method in the AppDelegate delegate will be hit? Something like a key in the info.plist file, etc..?
My goal: I'm working in a beacon app, the piece of code is in this article. My problem is that the message from the didEnterRegion keeps poping even when i'm beside the beacon. To solve that I'm setting a flag to control the message. My code below:
if(!UserDefaults.standard.bool(forKey: Constants.EnterZoneMsgShowName)){
let notification = UILocalNotification()
notification.alertBody = "Hi, you are about to arrive at CIDMA's office. Please open de demo app and turn on the bluetooth on your device to enrich your experience. "
UIApplication.shared.presentLocalNotificationNow(notification)
UserDefaults.standard.set(true, forKey: Constants.EnterZoneMsgShowName)
}
I want to set this flag to false when I close the app. I tried to put it at the applicationWillTerminate but this method is not hit every time.
I would like to know how to guarantee that this code will be hit or if there is a better place to put the code: UserDefaults.standard.set(false, forKey: Constants.EnterZoneMsgShowName)
applicationWillTerminate(_:) - Tells the delegate when the app is about
to terminate.
For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app.
For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason.
What you want to call is applicationDidEnterBackground if your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

iPhone App transiting from active to inactive state

Assume that I am build an iPhone application which accepts user name and password in one of the screens. While I am entering my username, I get an high priority event like a phone call.
My app will transit from being active to an inactive state at this point.
My question here is: What are the steps that I need to do in my app so that I can save the current application state (and entered info) so that I can restore the same when my app becomes active later on?
This question was asked in one of iOS interviews.
My answer was that handle the active to inactive state transition in the applicationWillResignActive delegate method to save the partially entered user info details and restore it in applicationDidBecomeActive method. The App UI state, we don't have to handle as the OS will take care of it.
It looked like the interviewer was not convinced with my answer. He kept asking me as to how would you handle (steps that you would take in your app) the transition from an active state to inactive state and then to active state in your app so that app state is restored/intact?
Your answer is correct, the interviewer was probably looking for you to name each of these methods and you most likely only named the two you stated. There are a few other delegate methods for certain App UI states, such as applicationDidEnterBackground and applicationWillEnterForeground
If you read the default description of these methods in the comments you will get a better understanding of what each is used for. For example, applicationWillResignActive specifically refers to incoming phone calls or SMS messages:
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
And applicationDidEnterBackground is for saving user data when a user closes your app:
// 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.
Check out your AppDelegate.m file of a new project and the comments really are very, very useful for understanding exactly which ones will handle what states and when you should use each.
Also, be sure to read up on Apple's documentation on handling application states: The App Life Cycle
Apple has already provided decent documentation on your question:
link.
And for interruptions:
link for apple developer site on handling interruptions
I think you are talking much more about restore state.
First of all, implement App delegate protocol:
func application(application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
return true
}
func application(application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
return true
}
Then in your ViewController, implement UIStateRestoring protocol. Here you should notice that if you want archive your own complicated object, don't forget to implement NSCoder.
Please go deep into "State Restoration".
Besides, when your app go to background, you need to do some work such as stop timer, pause ongoing task.
When go to foreground, you need to do something like start the paused task, and prepare to refresh page.

terminating an app from didFinishLaunchingWithOptions

So, I have an app that monitors significant location changes. I want to only record changes at most every 2 hours. The other times, I really don't want my app to startup at all. Does anyone know if I can terminate my app from within
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Will returning "False" cause my app not to be loaded (from the docs it seems that is only if it is trying to handle a URL).
You should not terminate the app as it lead to rejection by apple.As docs say
There is no API provided for gracefully terminating an iOS application.
You can show pop up to user for appropriate message.During development or testing you can call abort().But you should not ship your app with any of terminate api as apple strongly discourage this.
you can try exit(0); but Let me warn you apple may reject your app if you terminate your app willingly, what would be better is to show a dialogue box containing the reason and asking the user to close the app on thier own.
You really should not terminate your application, but should prompt the user that there's nothing to show at the moment and have them go to the home screen.
However, if you really want to, you can use abort().
From Apple's Developer Library (emphasis added):
In iOS, the user presses the Home button to close applications. Should your application have conditions in which it cannot provide its intended function, the recommended approach is to display an alert for the user that indicates the nature of the problem and possible actions the user could take — turning on WiFi, enabling Location Services, etc. Allow the user to terminate the application at their own discretion.
[...]
If during development or testing it is necessary to terminate your application, the abort function, or assert macro is recommended.

applicationWillTerminate: not being called

I'm using applicationWillTerminate: to save some last-minute stuff. But the problem is that it never gets called. If I do something like this at the top of the method: NSLog(#"Something"); it doesn't get called and doesn't get outputted to the console.
Does anyone know why this is happening?
From Apple docs:
For applications that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the application. 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.
If your app has background enabled use:
- (void)applicationDidEnterBackground:(UIApplication *)application
Use applicationDidEnterBackground: instead. Applications aren't terminated when you press the home button in a multitasking system.
From the iOS Application Programming Guide on Core Application Design and Application life time:
The applicationWillTerminate: method is not called if your application is currently suspended.
If you are linking against iOS 4.0, you should also save data in applicationDidEnterBackground:.
step 1: command + shift + h (double click(tab))
step 2: move app top side (kill)
step 3: applicationWillTerminate Work

Resources