Painted painted levels: fostered fostered fostered

Tags: “iOS” “UIStateRestoration” author: Mu Lingluo Review: QiShare team


Introduction: In iOS development, we all know that when an App clicks the home button or switches to another App, it will enter the background. Over time, apps run in the background, hang in the background, and die. Consider a scenario like this:

Scenario 1: When a user is using our App to edit personal information, he suddenly receives a call, which causes the App to enter the background and the call duration exceeds the duration of the App background. When the user finishes the call, he returns to continue filling in, only to find that the App has been restarted, and the data he filled in before has not been saved, so he needs to re-enter it? The user experience will be terrible.

To this question, we might say just keep the App background active. Yes, it’s a good solution. But in addition to this scheme, do we have other ways to achieve the UI interface and data save and restore. The answer is yes. Next, we will introduce a solution called UIStateRestoration.

I. About UIStateRestoration

UIStateRestoration appears in apis of iOS 6.0 and later. It mainly helps us to achieve UI save and restore in specific scenarios. UIStateRestoration is a protocol class. In Apple’s system, UIApplication, UIViewController and UIView under the UIKit framework all implement the UIStateRestoration protocol.

The sequence of UI state calls from application startup to recovery and UI state saving apis can be better understood by using the diagrams on the official website.

UI state recovery, only when the AppDelegate implementation application: shouldRestoreApplicationState: and will only take effect when the method returns true. UI state save, only when the AppDelegate implementation application: shouldSaveApplicationState: and will only take effect when the method returns true.

Ii. Introduction of UIStateRestoration

  1. When the system saves and restores UI status, it automatically uses the following constant strings to archive related data.
#pragma mark -- State Restoration Coder Keys -- // UIStoryBoard that originally created the ViewController that saved state, Nil if no UIStoryboard / / to save and create a story using the key UIKIT_EXTERN nsstrings * const UIStateRestorationViewControllerStoryboardKey NS_AVAILABLE_IOS(6_0); // NSString with value of info.plist's Bundle Version (app version) when state was last saved for the app / / application info. The last time preserved plist application version UIKIT_EXTERN nsstrings * const UIApplicationStateRestorationBundleVersionKey NS_AVAILABLE_IOS(6_0); // NSNumber containing the UIUserInterfaceIdiom enum value of the app that saved state / / state preservation application ` UIUserInterfaceIdiom ` enumeration values UIKIT_EXTERN nsstrings * const UIApplicationStateRestorationUserInterfaceIdiomKey NS_AVAILABLE_IOS(6_0); // NSDate specifying the date/time the state restoration archive was saved. This is in UTC. UIKIT_EXTERN NSString *const UIApplicationStateRestorationTimestampKey NS_AVAILABLE_IOS(7_0); // NSString with value of the system version (iOS version) when state was last saved for the app / / the last application version save the state of the system (iOS version) UIKIT_EXTERN nsstrings * const UIApplicationStateRestorationSystemVersionKey NS_AVAILABLE_IOS(7_0);Copy the code
  1. UIViewControllerRestoration protocol: when UI state recovery do we generate a controller.
#pragma mark -- State Restoration protocols for UIView and UIViewController -- // A class must implement this protocol If it is specified as the restoration class of a UIViewController, this protocol must be implemented. @protocol UIViewControllerRestoration + (nullable UIViewController *) viewControllerWithRestorationIdentifierPath:(NSArray<NSString *> *)identifierComponents coder:(NSCoder *)coder; @endCopy the code
  1. UIDataSourceModelAssociation agreement: currently, only the UITableView and UICollectionView implements this protocol.

Website description: UIDataSourceModelAssociation.

@protocol UIDataSourceModelAssociation
- (nullable NSString *) modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view;
- (nullable NSIndexPath *) indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view;
@end
Copy the code
  1. UIStateRestoring Protocol: Implements the UIStateRestoring protocol that allows our custom views (non-UIView and UIViewController subclasses) to participate in state recovery. The prerequisite must be UIApplication+ (void)registerObjectForStateRestoration:(id<UIStateRestoring>)object restorationIdentifier:(NSString *)restorationIdentifierMethod registration.
+ (void)registerObjectForStateRestoration:(id<UIStateRestoring>)object restorationIdentifier:(NSString *)restorationIdentifier
Copy the code
@protocol UIObjectRestoration; // Conform to this protocol if you want your objects to participate in state restoration. // To participate in state Restoration of the function registerObjectForStateRestoration must / / be called for the object. The object / * if you want to participate in the back, please comply with this agreement. To participate in the back, registerObjectForStateRestoration function must be called for this object. */ @protocol UIStateRestoring <NSObject> @optional // The parent property is used to scope the restoration identifier path for an object, to // disambiguate it from other objects that might be using the same identifier. The parent // must be a restorable The object or a view controller, else it will be ignored. /* Parent property is used to define the recovery flag recovery path for one object to disambiguate other objects that may use the same recovery flag. The parent property must be either a recoverable object 'ID <UIStateRestoring>' or a view controller, otherwise it will be ignored. Personal understanding: Similar to inheritance system mode, convenient to consolidate clear recovery path, help us to carry out a certain sequence and level of recovery. */ @property (nonatomic, readonly, nullable) id<UIStateRestoring> restorationParent; // The restoration class specifies a class which is consulted during restoration to find/create // the object, Rather than trying to look it up /* objectRestorationClass specifies the classes used to locate and create objects that need to be restored during recovery. */ @property (NonAtomic, ReadOnly, Nullable) Class<UIObjectRestoration> objectRestorationClass; // Methods to save and restore state for the object. If these aren't implemented, the object // can still be referenced by other objects in state restoration archives, But it won't // save/restore any state of its own. If these methods are not implemented, the object can still be referenced by other objects in the state recovery archive, but it will not save and restore any of its state. */ - (void) encodeRestorableStateWithCoder:(NSCoder *)coder; - (void) decodeRestorableStateWithCoder:(NSCoder *)coder; // applicationFinishedRestoringState is called on all restored objects that implement the method *after* all other object // decoding has been done (including the application delegate). This allows an object to complete setup after State // Restoration, Knowing that all objects from the restoration archive have decoded their state. Decoding completed (including ` AppDelegate ` decoding) and restored after all can restore object will invoke applicationFinishedRestoringState. This allows the objects in the recovery from the state of complete set, can know to restore files by this method is clear in all objects have been decoding its state * / - (void) applicationFinishedRestoringState; @end // Protocol for classes that act as a factory to find a restorable object during state restoration // A class must Implement this protocol if it is specified as the restoration class of a UIRestorableObject. Used to find recoverable objects during state recovery. If you specify a class as' objectRestorationClass 'of' id<UIStateRestoring> ', that class must implement this protocol. @protocol UIObjectRestoration + (nullable id<UIStateRestoring>) objectWithRestorationIdentifierPath:(NSArray<NSString *>  *)identifierComponents coder:(NSCoder *)coder; @endCopy the code
UIStateRestoration scenario

This applies to the scenario where the App enters the background and is killed by the system after the background stays longer than the background active time. Because when the user forcibly exits the application, the system automatically deletes the reserved state of the application. Removing retained status information when an application is terminated is a security precaution. If the application crashes at startup, the system also removes the reserved state as a similar security precaution.

UIStateRestoration debugging

According to the scenario description, if you are testing an application’s ability to restore its state, you should not use the multitasking bar to force termination of the application during debugging. You can set the Application does not run in background to YES in the project plist file.

UIApplication implements the UI collaboration protocol
#pragma mark -- State Restoration protocol adopted by UIApplication delegate --
- (nullable UIViewController *) application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray<NSString *> *)identifierComponents coder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
- (BOOL) application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
- (BOOL) application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
- (void) application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
- (void) application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
Copy the code
UIViewController implements the UIStateRestoration protocol
@interface UIViewController (UIStateRestoration) <UIStateRestoring>
@property (nullable, nonatomic, copy) NSString *restorationIdentifier NS_AVAILABLE_IOS(6_0);
@property (nullable, nonatomic, readwrite, assign) Class<UIViewControllerRestoration> restorationClass NS_AVAILABLE_IOS(6_0);
- (void) encodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
- (void) decodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
- (void) applicationFinishedRestoringState NS_AVAILABLE_IOS(7_0);
@end
Copy the code
UIView Implements the UI Collaboration protocol
@interface UIView (UIStateRestoration)
@property (nullable, nonatomic, copy) NSString *restorationIdentifier NS_AVAILABLE_IOS(6_0);
- (void) encodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
- (void) decodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
@end
Copy the code

This article introduces the process of UI state saving and recovery, the method of UIStateRestoration protocol class, and application scenarios. The debug policy and the interface methods provided by UIApplication, UIViewController, and UIView on the 1UIStateRestoration1 protocol. The next article will show you how to implement UI state saving and recovery.


Recommended articles:

Swift operator iOS accurate timing common method Sign In With Apple (one) algorithm small column: dynamic planning (one) Dart foundation (one) Dart foundation (two) Dart foundation (three) Dart foundation (four) iOS SMS verification code countdown button strange dance weekly