App State Restoration in iOS

G. Abhisek
Swift India
Published in
7 min readOct 4, 2018

Imagine, you are reading a news app. You have browsed hundreds of articles and got an interesting one and started reading. Suddenly, you got a guest and he happened to be your old school buddy. You guys had a great time and spent hours in chit-chat. You came back and thought of continuing your blog. But you found your blog to be lost and the app started from the beginning. Oh….so frustrating !!

It's so frustrating 😤

So what happened here. Your application was suspended or terminated by the OS when it was inactive in the background for quite a long time. The app never saved your state and it was lost when you returned back.

If you are an app developer, you would never want your user to share this frustration. In order to help you restore user state iOS provides App State Restoration.

What is App State Restoration?

App State Restoration refers to the process of saving and restoring applications semantic state. Semantic state of an application refers to the user's state in the application and the computational state of the application i.e any computations or business logic at the time when application suspends.

How does State Restoration help us?

State Restoration is a small feature which can greatly enhance the capabilities of your application. It can help you in the following aspects:

  • User Experience.
  • The user feels as if the app has never quit.
  • The app stands out in the crowd.

What does iOS have for App 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

Setting Restoration ID in Storyboard. You could keep it similar to Storyboard ID or provide a unique one

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.

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.

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.

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.

Okay, so now comes the million dollar question: “How to save and restore data? After all, that is what we aim for.”

  • 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 i.e 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 and

These are the basic delegates and properties that help us in state restoration. In WWDC 2013, Apple announced that Objects can also be saved in the restoration process by using UIObjectRestoration Protocol. Keeping a reference to table view or collection view data source can be kept by UIDataSourceModelAssociation Protocol which we would discuss in detail in the second part of this blog series.

Control Flow

Control Flow of State Restoration

Be Careful !!

There are some facts that needed to be taken care of when we are working with State Restoration and the encrypted archive base.

  • It is not user defaults nor core data.
  • Saved state can be lost.
  • If data is a preference, don’t store it in state restoration archive.
  • Don’t convert to data and encode.

Demo

Let us put to use our newly learned feature to use. Please download the sample code base from the Git Repo. And open up the AppStateRestoration1 code base for the demo.

The sample app consists of a tab controller embedding two controllers, the first one shows the two very popular comic worlds i.e DC and Marvel. The second one gives the user an option to switch between two popular comic characters i.e Batman and Ironman. Don’t expect much from this app, it is just a demo to demonstrate State Restoration 😉

The first tab is ComicWorldController and the second tab is PhotosViewController. You won't find any logic in ComicWorldController as its a static page with static images.

  • Open the Main.Storyboard, and check the attribute inspector, you would find we have provided each controller with a restorationID. This ensures that our controllers are identified by UIKit to be restored.
  • Open the AppDelegate.swift of our application. You would find that we have enabled restoration by returning true to two of the methods i.e shouldSaveApplicationState and shouldRestoreApplicationState.
  • Now let us visit PhotosViewController. This controller has two best comic characters from DC and Marvel i.e Iron Man and Bat Man. You can switch between these characters and admire their grandeur.
  • Each hero has its id coming from enum SuperHeroType. The selected superhero id is saved in the property selectedSuperheroId. Now, this id is our point of interest and this is what we are gonna save.
  • We have implemented the UIStateRestoring protocol methods and have saved the selectedSuperheroId corresponding to key “imageId”. This encoding method gets called when UIKit starts saving the state. When it comes to decoding, we call upon the coder to fetch us the saved id and then we continue configuring the UI.

Testing

  • Run the app on the simulator.
  • Switch to Super Hero Mode tab. The initial superhero we see is Iron Man. Switch to the next hero, Batman using the switch button.
  • Press Cmd + Shift + H and then pause the app from Xcode.
  • Relaunch the app by tapping the app icon on your simulator screen.
  • We find our app shows up the Super Hero Mode tab and Batman selected.

Voilla !!! We did it …. 😂

What did we learn?

  • What is App State Restoration?
  • What iOS has for State Restoration?
  • The control flow.
  • Sample implementation.

I would love to hear from you

You can reach me for any query, feedback, or just want to have a discussion by the following channels:

Twitter — @gabhisek_dev

LinkedIn

Gmail: abhisekbunty94@gmail.com

Please feel free to share with your fellow developers.

--

--