简体   繁体   中英

Cache View Controller

While working in iOS I see a difference between my app and Apples default app in iPhone. My app name is MyApp which i built on objective C and I compared the behavior with Apple's default apps ie Notes .

I used both apps without suspending. When the device gets rebooted, I see both MyApp and Notes are shown in the recent list but when I open MyApp from the recent list it restarts from the splash screen unlike the system app (Notes) which still stays in the old screen (the screen it was showing before device reboot). Anyone knows what is the reason of different behavior? Do I need to implement any extra step to get the similar behavior like Apples default apps?

This behavior doesn't come automatically. You have to save and restore the UI state in your app. Apple has lots of documentation on this topic; I recommend to start here: https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches

View Controller State Restoration

State Restoration in iOS was introduced back in 2012 and major improvements happened in 2013. iOS handles a lot when it comes to State Restoration. When State Restoration is enabled in the application, iOS takes care of the following:

  • Maintaining the navigation controller and thereby the navigation hierarchies.
  • Maintaining the state of tab bar controllers like selected tabs, etc.
  • Building up and restoring view controllers which have opted for state restoration.
  • Provides an encrypted archive space to encode the data to and decode the data from.
  • If controllers are built from storyboard with restoration opted in the storyboard itself, UIKit helps in saving the controllers and providing controller references and restoring.

Doesn't that seem easy !! iOS doing almost all the tricky things.

Integration

Integration in your code can be broken down into the following parts:

AppDelegate

In AppDelegate, we have to enable state restoration for our application by implementing two delegate methods:

func application(application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
  return true
}

func application(application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
  return true
}

ViewControllers

ViewControllers are the ones that are to be saved and restored. They are the components which handle the user state in the app. So logically, controllers are the ones which are responsible to save and restore the state of the controllers. So how to do that?

Restoration ids:

In order to have restoration enabled for a controller, we have to provide a restoration identifier to the class as:

self.restorationId = “Your Restoration Id”

We could directly set this in storyboard in the attributes inspector as below在此处输入图片说明

Note: If you are not providing Restoration ID for any controller it will be excluded from the restoration process, including all controllers in the navigation hierarchy after this controller.

Restoration Class

A restoration class is a class which knows how to create a specific view controller. This class should conform to UIViewControllerRestoration protocol. UIStateRestoring protocol Each class by default confirms to UIStateRestoring protocol. This protocol has delegate methods and properties to help controller save relevant information to build up the UI.

//Encoding and Decoding the Object
func encodeRestorableState(with: NSCoder)
//Encodes state-related information for the object.
func decodeRestorableState(with: NSCoder)
//Decodes and restores state-related information for the object.
func applicationFinishedRestoringState()
//Called after all objects have had a chance to decode their state.

UIViewControllerRestoration Protocol

The methods that objects adopt so that they can act as a “restoration class” for view controllers during state restoration. Any class that adopts to this protocol provides a reference of the controller at the time of restoration. View controller should assign this class as its restoration class.

//Creating the View Controller
static func viewController(withRestorationIdentifierPath: [String], coder: NSCoder) -> UIViewController?
//Asks the receiver to provide the view controller that corresponds to the specified identifier information.
Required.

Note: Conformance to UIViewControllerRestoration protocol is generally not needed if we are building your controllers from storyboard as the reference of the view controllers is taken from the storyboard by UIKit at time of restoration. But if we are building your controller programmatically, you have to implement the protocol by yourself.

Save Data

We have been familiar with UIStateRestoring Protocol above. For saving data UIKit provides us with the following delegate method:

func encodeRestorableState(with coder: NSCoder)

We encode the data that we need to restore the controller via the coder corresponding to a key.

Note: Apple recommends to save minimal data ie actually necessary for recreating a view controller. Eg. You want to restore the User Details page. So the data that you need to save is the user id and then make a database query to fetch the details and recreate the view controller. This is because the encrypted archive that Apple uses to store the data can be cleaned anytime if the OS deems necessary. So any relevant data will be lost.

Restore Data

For restoring data, we have to implement the following delegate method:

func decodeRestorableState(with: NSCoder)

This method is called when UIKit needs to restore the view controller. Here we ask the coder to fetch us the data that we saved and then our normal set up methods should set the UI. The coder has additional information such as versions

For Orignal Article Click Here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM