Wednesday, May 23, 2012

Sync Data Changes Between Views

Sometimes you may want to sync data source between two views. For example, one view is for displaying data and another for editing. If these two views are associated with tab bar controller, any changes in the edit view should be reflected on the display view. Right?

Here is the tip: make sure the data source context in both views are the same one. The data source context behaviors like a cache for holding all the source source objects. Any changes in the context will be magically refreshed in both views. To do that, simply create one class with singleton object of UIManagedDocument.

// in .h file
@interface MyAppDBManager : NSObject

+ (UIManagedDocument*) database;
@end

// .m file
@implementation MyAppDBManager

+ (UIManagedDocument* ) database {
 static UIManagedDocument* db = nil;

 if (!db) {
   NSURL *url = [[[[NSFileManager defaultManager]
     URLsForDirectory:NSDocumentDirectory
            inDomains:NSUserDomainMask]
            lastObject]
            URLByAppendingPathComponent:@"My database"];
   NSURL*
   db = [[UIManagedDocument alloc] initWithFileURL:url];
 }

 return db;
}

@end

The following is an example to use the database in a table view:

#implementation
@synthesize myDatabase;
@synthesize fetchResultController;
...

- (void)setup {
  NSFetchRequest* fecchRequest = ...

  self.fetchResultController = [
    [NSFetchRequest alloc]
    initWithFetchRequest:fetchRequest
           managedObject:self.myDatabaese.managedObjectContext
      sectionNameKeyPath:...
               cachename:...];
  ...
}

- (void) viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
 ...
  self.myDatabase = [MyAppDBeManager database];
 ...
}

Since the instance of myDatabase is singleton object, its managedObjectConext is only one as well. So that any other views will share the same context as long as the database is from MyDBManager class.

One thing the data source you need to reload is the case of tab bar view controller. Tab bar view controller provides a way to switch among several views. When they are loaded, I found that there is no magical to refresh changes. What I did is to add the reload in a view controller's will appear event:


- (void) viewWillAppear:(BOOL)animated {
 [supper viewWillApear:animated];
 ...
 [self.tableView reloadData];
 ...
}

0 comments: