state restoration in iOS - ios

I am storing my application screen, so that when the application gets opened it will show the screen that was stored. The application is navigation based.
I have assigned the Restoration Ids to my two view controllers in main story board. The first controller is the root view controller of the navigation controller. I have also assigned Restoration Id to the navigation controller.
Now the problem is when I run the application I am getting the following warning:
Unable to create restoration in progress marker file.
Not sure what else need to be done.

I had the same warning before and fixed it by doing the followings.
I was using storyboard. My storyboard only included a navigation view controller and a view controller (which was the root view controller of that navigation view controller). In my case, it was caused by either of the two reasons:
The application was not set up correctly for state preservation
The followings need to be set:
In app delegate, override application:willFinishLaunching. One can simply return YES in that method.
For every view controllers and views (including the navigation view controllers and tab view controllers), set a restore ID
In app delegate, opt-in by overriding shouldSaveApplicationState and shouldRestoreApplicationState
If this warning still occurred, you could check how you run your app in Xcode. I ran my app in Xcode simulator and had to follow a specific sequence to trigger state preservation.
launch the app in Xcode simulator
In Xcode simulator, click the "Home" button to put the app into the background. The encodeRestorableStateWithCoder method of the view controller should be called
go back to Xcode, click the "stop" button to terminate the simulation
In Xcode simulator, double click the "Home" button and then remove the app from the app switcher and
go back to Xcode, run the app again.
That warning should not appear. When I used other sequences, I saw that warning appearing. When I debugged my app on my device using Xcode, I followed the same sequence and did not see the warning.
I think that warning indicated that because Xcode could not terminate the app correctly, the state restoration file was not correctly saved onto the disk.

Try to give your View a restoration ID. You can do so to open your xib or storyboard and assign the id to your View Controller.
more details: http://useyourloaf.com/blog/2013/05/21/state-preservation-and-restoration.html

Simulator:
This happens for the first time on the simulator when the app encodes. (not sure why)
Subsequent times this warning wouldn't be shown.
Device:
Try running on the device.
Run on device
Go to home screen.
Stop running on Xcode
Remove app from app switcher
Run on device again

Related

Launch Screen only showing once

I have used the LaunchScreen.storyboard file in my swift file to create a launch screen, however I only see the launch screen when I load the app onto my phone. After that, even when I kill the app I don't see the launchscreen again. I want it so that it shows every time the app is booted, so after it's been removed from the background like most other apps that exist. I there a setting that i need to toggle, or am I doing something wrong?
What you want can be achieved from the initial ViewController instead of Launch Screen.
Reason: Launch Screen timing is not fixed and can have a very short appearance if the app has recently been in the memory.
I would recommend you to use the welcome graphic/animation on the initial View Controller and move to the intended View Controller after a set timer by using a segue.
Edit: Additionally, in case of a graphic, you can put that on the Launch screen as well, then on the initial View Controller. That will get you continuity.
Hope this helps.

iOS app Killed and relaunched Showing my last VC

Killing and relaunching iOS app, If I have View Controller A,B,C last visible View Controller was C. So now when I relaunch app i see View Controller C for 10 sec and then shows up Splash Screen. How can I avoid this.
Because of this first 10 sec User cant perform any event on app.
I think this is an operation system bug. But if you want to avoid this, you can try to add a splash screen image view before your app will go to background. You need to add your custom overlay view as subview to current window. Use this method to implement this feature: applicationDidEnterBackground. You can find more information about this feature here:
Display a view or splash screen before applicationDidEnterBackground (to avoid active view screenshot)
To force iOS to launch an app with its default viewcontroller or launch image, you need to call
UIApplication.shared.ignoreSnapshotOnNextApplicationLaunch()
where you implement state preservation.
Form the documentation : Documentation
Prevents the app from using the recent snapshot image during the next launch cycle.

Quit the application on a specific view

I have a doubt:
I have an app with 10 views. I want that, if the user is on View1 and sends the app to the background, it terminates the application (exit (0)). But I wanted this to happen only on View1, on the other screens, if the app goes to the background and then returns, it will continue where it left off.
What can I do?
Apple's guidelines seem to be strictly against terminating your app programmatically (for example, with exit()); it would go against what iOS users expect of how apps work.
Instead, I recommend the following approach:
When the app is sent to the background (applicationWillResignActive(_:) is called), check which view controller is currently being displayed.
If it's such that you wish to start over next time the app is brought to the foreground, just reset the app window's root view controller to whatever the initial view controller of your app is (typically, it involves reloading the inital view controller from Main.stroyboard, but your setup could be different).
You can not choose at runtime whether your app goes to the background or is terminated when the user presses the home button ("multitasking"); that is set in stone in your Info.plist file at build time.
Also, remember that even if you are in the screen that you wish to preserve when the user resumes, your app might be terminated by the system while it is in the background (to reclaim scarce system resources), so in that case it will still start from the initial screen. To prevent this, you might want to check out the APIs for state preservation and restoration.
Here is another SO question asking how to find the identity of the current view controller. Why not query the current view when you receive applicationWillResignActive indicating that your app is going to move to the background and then choose the action you want?
As far as I understand your description Preserving and Restoring State is what you are looking for.
Excerpt from Documentation:
The preservation and restoration process is mostly automatic, but you need to tell iOS which parts of your app to preserve. The steps for preserving your app’s view controllers are as follows:
Required
Assign restoration identifiers to the view controllers whose
configuration you want to preserve; see Tagging View Controllers for
Preservation.
Tell iOS how to create or locate new view controller objects at
launch time; see Restoring View Controllers at Launch Time.
Optional
For each view controller, store any specific configuration data needed to return that view controller to its original configuration; see Encoding and Decoding Your View Controller’s State.
Here is a link to Preserving Your App’s Visual Appearance Across Launches

Loading the last View Controller Active after app goes into background, swift

I have "Tinder" like swipping view that is located in a CardViewController. The card View Controller is accessed by moving through two other view controllers. i.e. Load App -> FirstViewController -> SecondViewController - > CardViewController.
When I am in the Card ViewController and I go into background mode, the app launches on the FirstViewController and on going to the cards, they are loaded from the first card in a stack of about 10?
Is there anyway to load the app from the last Card I had swipped and in the CardViewController without having to navigate from the FirstView Controller again?
I would really appreciate the help as it's horribly affecting some of my users.
An example of a Tinder like card view is shown!
The problem, from the sound of it, is not what happens when the app goes into the background — that would leave it in exactly the same state when it reactivates. The problem is what happens when the app goes into the background and quits. Your app is then relaunched from scratch, which is why you find yourself in the first view controller. What's upsetting you is the difference between the app's behavior in these two situations.
Apple provides a solution to this situation: UIViewController, along with the App Delegate, has methods permitting you to save and restore state. When the app goes into the background, the current configuration (what view controller's view is showing) is saved. That way, even when the app quits, when it relaunches it can get back to that configuration before it appears to the user. Thus, coming back from background-and-quit looks just like coming back from mere backgrounding.
For full details, see Apple's documentation. This is a good place to start:
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html

Reset View hierarchy iOS

I'd like to add some code to the app delegate that resets the view hierarchy back to the beginning.
My app is basically a demonstration mockup, and I'd like EVERYTIME the app opens that it resets to the first view in the storyboard, and doesn't remember what page the user was on when they closed or 'minimized' the app.
I'm using iOS sdk 8.1, and Xcode 6.
Putting aside that it's actually quite bad user experience - it's very easy to do. You just need to specify that your app doesn't run in the background, and each time user closes app, next time - brand new copy will be launched.
Here is what you need to set in your project properties in Xcode:
If your'r info.plist Show raw keys/values option are enabled, the property is named UIApplicationExitsOnSuspend which you can get by right clicking on the empty space of info.plist properties table and selecting Add Row option as follows
and right after that you will be presented with following option,
where you can select second options which is Application does not run in the background.
Selecting the mentioned property and setting it to YES, the app opt out of background mode and it cycles between the not-running, inactive, and active states and never enters the background or suspended states and moved back to the not-running state. In other words, iOS will not preserved any states which allows the app to run as fresh on next launch.

Resources