core data - How to best handle CoreData + iOS State Restoration? -


i'm trying add ios 6 state restoration app i'm finished with. it's app model comes coredata.

as recommended, i'm using "pass baton" approach moving managed object contexts between view controllers - create moc in app delegate, pass first view controller, passes second in prepareforsegue:, passes third in prepareforsegue:, etc.

this doesn't seem jive state restoration. thing can think of retrieve moc app delegate directly in implementation of viewcontrollerwithrestorationidentifierpath:coder:. in fact, appears apple developers did similar when watching wwdc session.

is best/only way? state restoration break pass-the-baton, @ least view controllers restored?

to become familiar state restoration highly recommend wwdc 2013 session what's new in state restoration. while state restoration introduced year earlier in ios 6, ios 7 brought notable changes.

passing forward

using "pass baton" approach, @ point root nsmanagedobjectcontext created , nspersistentstorecoordinator attached. context passed view controller , subsequent child view controllers in turn passed root context or child context.

for example, when user launches application root nsmanagedobjectcontext created , passed in root view controller, manages nsfetchedresultscontroller. when user selects item in view controller new detail view controller created , nsmanagedobjectcontext instance passed in.

passing managed object context baton

saving , restoring state

state restoration changes in ways significant applications using core data in view controllers. if user on detail view controller , sends application background system creates restoration archive information useful reconstructing state visible when left. information entire chain of view controllers written out, , when application relaunched used reconstruct state.

state restoration

when happens not use custom initializers, segues, etc. uistaterestoring protocol defines methods used encoding , decoding state allow degree of customization. objects conform nscoding can stored in restoration archives , in ios 7 state restoration extended model objects , data sources.

state restoration intended store information required reconstruct visible state of application. core data application means storing information needed locate object in correct persistent store.

on surface, seems simple. in case of view controller managing nsfetchedresultscontroller may mean storing predicate , sort descriptors. detail view controller displays or edits single managed object uri representation of managed object added state restoration archive:

- (void) encoderestorablestatewithcoder:(nscoder *)coder {     nsmanagedobjectid   *objectid   = [[self managedobject] objectid];      [coder encodeobject:[objectid urirepresentation] forkey:kmanagedobjectkeypath];     [super encoderestorablestatewithcoder:coder]; } 

when state restored uistaterestoring method -decoderestorablestatewithcoder: called restore object archived information:

  1. decode uri restoration archive.
  2. get managed object id uri persistent store coordinator
  3. get managed object instance managed object context managed object id

for example:

- (void) decoderestorablestatewithcoder:(nscoder *)coder {     nsurl               *objecturi  = nil;     nsmanagedobjectid   *objectid   = nil;     nspersistentstorecoordinator    *coordinator    = [[self managedobjectcontext] persistentstorecoordinator];      objecturi = [coder decodeobjectforkey:kmanagedobjectkeypath];     objectid = [coordinator managedobjectidforurirepresentation:objecturi];     [[self managedobjectcontext] performblock:^{         nsmanagedobject *object = [self managedobjectcontext] objectwithid:objectid];         [nsoperationqueue mainqueue] addoperationwithblock:^{             [self setmanagedobject:object];         }];     }];  } 

and things become more complicated. @ point in application life cycle -decoderestorablestatewithcoder: called view controller need correct nsmanagedobjectcontext.

pass baton vs. state restoration: fight!

with "pass baton" approach view controller instantiated result of user interaction, , managed object context passed in. managed object context connected parent context or persistent store coordinator.

during state restoration not happen. if @ illustrations of happens during "pass baton" vs. state restoration may similar - , are. during state restoration data is passed along - nscoder instance represents interface restoration archive.

unfortunately nsmanagedobjectcontext information require can't stored part of restoration archive. nsmanagedobjectcontext does conform nscoding, important parts not. nspersistentstorecoordinator not, not persisted. curiously, parentcontext property of nsmanagedobjectcontext not (i suggest filing radar on this). storing urls of specific nspersistentstore instances , recreating nspersistentstorecoordinator in each view controller may seem attractive option result different coordinator each view controller - can lead disaster.

so while state restoration can provide information needed locate entities in nsmanagedobjectcontext, can't directly provide needed recreate context itself.

so next?

ultimately needed in view controller's -decoderestorablestatewithcoder: instance of nsmanagedobjectcontext has same parentage did when state encoded. should have same structure of ancestor contexts , persistent stores.

state restoration begins in uiapplicationdelegate, several delegate methods invoked part of restoration process (-application:willfinishlaunchingwithoptions:, -application:shouldrestoreapplicationstate:, -diddecoderestorablestatewithcoder:, -application:viewcontrollerwithrestorationidentifierpath:coder:). each 1 of these opportunity customize restoration process beginning , pass information along - such attaching nsmanagedobjectcontext instance associated object reference nscoder used restoration.

if application delegate object responsible creating root context object pushed down throughout view controller chain once launch process complete (with or without state restoration). each view controller pass appropriate nsmanagedobjectcontext instance it's child view controllers:

@implementation uiviewcontroller (coredata)  - (void) setmanagedobjectcontext:(nsmanagedobjectcontext *)context {     [[self childviewcontrollers] makeobjectsperformselector:_cmd withobject:context]; }  @end 

and each view controller provided it's own implementation create child context of it's own. has other advantages - approach has users of managed object context react changing makes easier create context asynchronously. creating context fast , lightweight, adding persistent stores root context potentially expensive , should not allowed run on main queue. many applications on main queue in application delegate method , end being killed os when opening files of store takes long or migration required. adding persistent store on thread , sending context objects use when it's ready can prevent these kinds of problems.

another approach may leverage responder chain in view controller. during state restoration view controller walk responder chain find next nsmanagedobjectcontext chain, create child context, , use that. implementing using informal protocol simple, , results in solution flexible , adaptable.

the default implementation of informal protocol walk further responder chain:

@implementation uiresponder (coredata)  - (nsmanagedobjectcontext *) managedobjectcontext {     nsmanagedobjectcontext    *result = nil;      if ([self nextresponder] != nil){         if ([[self nextresponder] respondstoselector:@selector(managedobjectcontext)]){             result = [[self nextresponder] managedobjectcontext];         }     }     return result; }  @end 

and object in responder chain can implement -managedobjectcontext provide alternate implementation. includes application delegate, participate in responder chain. using informal protocol above, if view or view controller calls -managedobjectcontext default implementation go way application delegate return result unless other object along way provided non-nil result.

you have option of using restoration class factories state restoration reconstruct chain of managed object contexts during restoration.

these solutions not appropriate every application or situation, can decide work you.


Comments

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

css - Firefox for ubuntu renders wrong colors -