iOS UImanaged document on multiple tabs

43 Views Asked by At

I'm trying to use a UIManagedDocument context for multiple tabs to retrieve and store data from my database. However, it can only retrieve info when I'm on my first tab. The second and third tabs show no data and I cannot insert data into Core Data with them. I use the context retrieved to set up a generic NSFetchController, but as I said this only works correctly for the first tab. What am I doing wrong?

- (NSManagedObjectContext *)managedObjectContext {
if (_document.managedObjectContext) {
    return _document.managedObjectContext;
}

NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject]; // Default location to store the document
NSString *documentName = @"ModelDocument";
NSURL *url = [documentsDirectory URLByAppendingPathComponent:documentName];
self.document = [[UIManagedDocument alloc] initWithFileURL:url];

if ([fileManager fileExistsAtPath:[url path]]) { // If already exists, open the document
    [self.document openWithCompletionHandler:^(BOOL success) {
        if (success) {
            [self announceContextReady];
        } else {
            NSLog(@"Problem with database!");
        }
    }];
} else {
    [self.document saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { // Document doesnt exist, create it
        if (success) {
            [self announceContextReady];
        } else {
            NSLog(@"Problem with saving!");
        }
    }];
}
return _document.managedObjectContext;

}

Fetch controller (Doesnt work on second or third tab):

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
switch (type) {
    case NSFetchedResultsChangeInsert: {
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
    }

    case NSFetchedResultsChangeDelete: {
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
    }

    case NSFetchedResultsChangeUpdate: {
        [self configureCell:(UITableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;
    }

    case NSFetchedResultsChangeMove: {
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
    }
}

}

1

There are 1 best solutions below

0
theMikeSwan On

The second and third tabs likely don't have a reference to the managed object context (or at least not the same one) and as such can't do anything with the persistent store. The same is true of the fetched results controller.

In order to have all three tabs show information from the same persistent store they all need to have a reference to the same managed object context. One way to do this would be to make a custom tab bar controller that has a managed object context that you set as needed. Each of the three tab view controllers could then observe the tab bar controller's context and update their own context when the tab bar controller's context changes. This would allow all three tabs to point to the same context and therefore work with a common pool of data.

If each tab shows a different entity from your model they will each need their own fetched results controller configured to pull the correct entity.