implementing state restoration in iOS 14

1.8k views Asked by At

I am trying to implement state restoration in my app, I've read through numerous articles and documentation but so far I have not been able to get it working. I have given all view controller a restoration ID, and (I think) have all the necessary functions to get it to work.

in AppDelegate

func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        return true
    }
    
    func application(_ application: UIApplication, shouldRestoreSecureApplicationState coder: NSCoder) -> Bool {
        return true
    }
    func application(_ application: UIApplication, shouldSaveSecureApplicationState coder: NSCoder) -> Bool {
        return true
    }
    
    func application(_ application: UIApplication, viewControllerWithRestorationIdentifierPath identifierComponents: [String], coder: NSCoder) -> UIViewController? {
        return coder.decodeObject(forKey: "Restoration ID") as? UIViewController
        
    }
    func application(_ application: UIApplication, didDecodeRestorableStateWith coder: NSCoder) {
        UIApplication.shared.extendStateRestoration()
        DispatchQueue.main.async {
            UIApplication.shared.completeStateRestoration()
        }
    }

in my view controller:

override func encodeRestorableState(with coder: NSCoder) {
        super.encodeRestorableState(with: coder)
        
        getSetDataFromTable()
        coder.encode(currentSession, forKey: "CurrentSession")
    
    }
    
    override func decodeRestorableState(with coder: NSCoder) {
        super.decodeRestorableState(with: coder)
        
        
        self.currentSession = coder.decodeObject(forKey: "CurrentSession") as! [CurrentSessionElement]
    }
    
    
    override func applicationFinishedRestoringState() {
        
        tableView.reloadData()
    }
    static func viewController(withRestorationIdentifierPath identifierComponents: [String], coder: NSCoder) -> UIViewController? {
            
        guard let restoredSession = coder.decodeObject(forKey: "CurrentSession") as? [CurrentSessionElement] else {
            print("decoding user detail")
            return nil
        }
        
        let vc = CurrentSessionVC()
        vc.currentSession = restoredSession
        return vc
    }

I set breakpoints in all the functions and when I try to test the functionality the breakpoints that hit are

when loading: shouldRestoreSecureApplicationState didDecodeRestorableStateWith

when clearing the app: shouldSaveSecureApplicationState

Nothing is restoring when tested, and none of the view controller functions are being triggered, am I missing something?

3

There are 3 answers

2
alobaili On

I just started learning about this yesterday. There are two types of state restoration; The old view-controller-based restoration, and the new scene-based restoration introduced in iOS 13 and later, the link in @Phantom59 answer is excellent in explaining it and there are a few sessions from WWDC 2019.

What you are doing in your question is the old way and only works if you opt-out of the scene based app life cycle.

1
Олексій Безродний On

I had the same issue. I removed SceneDelegate and all started to work fine. As I understand, restoration for SwiftUI works in another way, not compatible with classic UI flow

0
Programmer On

iOS 13 and later requires scene based state restoration I had issue figuring out from the official demo. Check the following sample app created to demonstrate state restoration.

Official Sample for 13 and later

Scene based state restoration sample