ios state preservation and restoration

Post on 29-Nov-2014

5.041 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Covers iOS app state preservation and restoration with extra emphasis on NSCoding. WWCD 2012 session 208 glosses over some of the fine details of how NSCoding works. Understanding this foundation better helps in understanding state preservation and restoration.

TRANSCRIPT

iOS State Preservation and RestorationRobert BrownTwitter: @robby_brownapp.net: @robert_brown

What is State Restoration?

Restores your app where the user left it

Makes your apps appear as if they never terminated

Lets users seamlessly get back to what they want

NSCoding

Similar to writing to a plist

Any object that conforms to NSCoding can be encoded

plist NSCodingNSNumber Y YNSString Y Y

NSDictionary Y YNSArray Y YNSData Y YNSDate Y YNSSet N YBlocks N N

Anything Else N Y

NSCoding

-initWithCoder:

-decodeObjectForKey:

-encodeWithCoder:

-encodeObject:forKey:

NSSecureCoding

Irrelevant to state restoration, but nice to know

Securely persists data

Many Cocoa classes conform to NSSecureCoding

Restoration Identifiers

Each view controller you want to restore must define a restoration identifier

Restoration identifiers make up a restoration ID path

Restoration paths must be unique

Example: /TabBarController/AboutViewController

Restoration Identifiers/A

/A/C/A/B/A/B

/A/C/B

Preservation Flow

-application:shouldSaveApplicationState:

-application:willEncodeRestorableStateWithCoder:

Each window on main screen Save view controller Save view

1

2

3 4

5

Preservation Flow

- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {

[super encodeRestorableStateWithCoder:coder];

// Assumes Person is NSCoding-compliant

[coder encodeObject:self.person forKey:@“person”];

}

Restoration Flow-application:willFinishLaunchingWithOptions:

-application:shouldRestoreApplicationState:

-application:didFinishLaunchingWithOptions:

State Restoration

Yes

No

-application:didDecodeRestorableState:withCoder:

Restoration Flow

Each view controller +viewControllerWithRestorationIdentifierPath:coder:

Found view controllers

-decodeRestorableStateWithCoder:

Restore view controller state Restore view

1

3

4

5

2

Restoration Flow

+viewControllerWithRestorationIdentifierPath:(NSArray *) components coder:(NSCoder *)coder {

// Restore only what you absolutely need

// You may not be able to restore other view controllers

return [self new];

}

Restoration Flow

- (void)decodeRestorableStateWithCoder:(NSCoder *)coder {

[super decodeRestorableStateWithCoder:coder];

self.person = [coder decodeObjectForKey:@“person”];

}

UIDataSourceModelAssociation

Many views will automatically restore their state

UITableView and UICollectionView need some extra help to restore your visible and selected cells

UIDataSourceModel association provides a mapping of cells to model objects

This is NOT intended to be used to persist data

UIDataSourceModelAssociation

-modelIdentifierForElementAtIndexPath:inView:

Converts from model object to ID

-indexPathForElementWithModelIdentifier:inView:

Converts from ID to model object

UIDataSourceModelAssociation

- (NSString*)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view {

// Uses Core Data

Person * person = self.persons[idx.row];

return person.objectID.URIRepresentation.absoluteString;

}

UIDataSourceModelAssociation

- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view {

NSURL * uri = [NSURL urlWithString:identifier];

NSPersistentStoreCoordinator * coordinator = // Your coordinator

NSManagedObjectContext * context = // Your context

NSManagedObjectID * objectID = [coordinator managedObjectIDForURIRepresentation:uri];

Person * person = [context existingObjectWithID:objectID error:NULL];

NSInteger index = [self.persons indexOfObject:person];

return [NSIndexPath indexPathForRow:index inSection:0];

}

Demo

Must use proper UIViewController containment

Restoration identifier paths must be unique

For a view controller to be restored, it must have a path to the root view controller

Manually terminating the app will delete the state

Gotchas

Gotchas

Restore only minimal state in +viewControllerWithRestorationIdentifierPath:

If a view controller that was persisted is not restored, the app delegate is given a chance to restore it

Testing state restoration isn’t straightforward

Press home button, then have Xcode kill the app

Gotchas

Restoration classes must conform to the UIViewControllerRestoration protocol

Restoration classes aren’t necessary when using UIStoryboard

Gotchas

If you change your view controller hierarchy, make sure you don’t restore from an older state

If your app crashes during restoration, the state data is thrown out

Want to Learn More?

WWDC Session 208

Archives and Serializations Programming Guide

iOS App Programming Guide

Questions?

top related