save state when phone turned off - ios

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.

Related

assertUnfrozen on iOS

I use a Firebase realtime database in an iOS app and I get a crash report through Firebase's crash reporting at [FIRDatabase assertUnfrozen] called from [FIRDatabase setPersistenceEnabled:]. (There's also a variation of these reports where the source is FIRDatabaseConfig rather than FIRDatabase)
In my app delegate's application:didFinishLaunchingWithOptions: method, I load the Firebase config from a file and then set persistence to enabled. For about 1 out of every 200 users this causes the crash with assertUnfrozen. Am I initializing Firebase in an incorrect way, or is there anyone with an idea about what's going wrong?
Calls to setPersistenceEnabled must be made before any other usage of FIRDatabase instance.This is reason for the crash, so check whether you are using FIRDatabase instance before calling setPersistenceEnabled.
In my case, I was using FIRDatabase instance in applicationDidEnterBackground and I had used setPersistenceEnabled in launchController.As soon as we open the app, before launchController is called, make the app go into background.Then, applicationDidEnterBackground gets called and FIRDatabase instance is used before calling setPersistenceEnabled.So, I removed firebase code from applicationDidEnterBackground and wrote it after setPersistenceEnabled is called.

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.

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

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")
}

Where do I put logic for when an iOS application hard closes and comes back?

I have an iOS application where I need to persist a set of data after the application HARD CLOSES (when the user double clicks the Home button and slides the application upwards). Then, when the application comes back to the foreground, I need to fetch that data and do something with it. I'm just not sure where I need to put that logic for Application Hard Close and Resuming the Application.
In your AppDelegate
When your app is going to be closed, but still in Multitasking menu the following method is getting called
-(void)applicationWillResignActive:(UIApplication*)application
If after 3 minutes user doesn re-open your app this method is going to be called
-(void)applicationDidEnterBackground:(UIApplication*)application
If user re-opens your app from multitasking menu the following method is getting called
-(void)applicationWillEnterForeground:(UIApplication*)application
If user is going to close your app from multitasking menu this method is getting called(you will have limited time to perform some logic here)
-(void)applicationWillTerminate:(UIApplication*)application
When user presses home twice applicationWillResignActive and applicationDidEnterBackground is called. You can save data here.
When user opens app, applicationWillEnterForeground is called, you get data which you save and process.
When a user hard-closes the application, the UIViewController's Delegate's method called applicationWillTerminate. Here I can catch and save the model data before it's all destroyed.
Then when a user launches the application again, there are many choices like didFinishLaunchingWithOptions where I can grab the data stored to disk.
Your app no longer gets an applicationWillTerminate call ever. You are simply silently killed while in the background. You have to write your app to save state in the applicationDidEnterBackground handler, as nmh describes. That's your only option.

Definitive Way to Save Data Between Launches.

For a project I'm working on, I would like to save a few bytes of data to the users iPhone between launches of the application. I would like to do this so I can save some state and a few important numbers when the user terminates the app. I have thought about it, and the best place to do this seems like the AppDelegate.
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate.
// Save data if appropriate. See also applicationDidEnterBackground:.
/* this is where I want to begin the process of saving application data */
}
I have heard of writing objects (only a select few allowed such as NSString, NSDictionary, NSArray) to file, but can this be kept around between launches of the app, or does the data go away when the user terminates the app?
Question:
Is there a definitive way to write data to the users iPhone that will stick around after the application quits?
The most common approach is to persist whatever data or state you need when your app enters the background. Then the data will be there if the app is killed while in the background and the app is restarted.
How you store the data really depends on what the data is. Writing the data to a file in the app's sandbox is quite common. Small bits of data can also be stored in NSUserDefaults.

Resources