Can anyone help me here. I am really stuck.
In my code if no file exists in the Documents location; I create the store, put the data in it and read back from it. This works fine.
However, if a file already exists in that location I am unable to read back from it. I have tried a lot, but am really unsure why it is not working. Some times (very few actually), the very same code will work but the other times it wouldn’t.
Here is the code. When it doesn’t work, the debug message ‘End of useDocument’ in useDocument method is never logged. This is the method where openWithCompletionHandler is called on the UIManagedDocument. The code enters the method but never makes it to the end of that method!
- (void)setupFetchedResultsController
{ NSLog(@"In setupFetchedResultsController");
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"WorkOutTypes"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"workoutName" ascending:YES]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.workoutDatabase.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
NSLog(@"End of setupFetchedResultsController");
}
- (void)pushWorkoutDataIntoDocument:(UIManagedDocument *)document
{ NSLog(@"In pushWorkoutDataIntoDocument");
dispatch_queue_t pushQ = dispatch_queue_create("Push data", NULL);
dispatch_async(pushQ, ^{
NSArray *workOuts = [NSArray arrayWithObjects:@"Squats", @"Bench Press", @"Overhead Press", @"Bent Over Rows", nil];
[document.managedObjectContext performBlock:^{
for (NSString *workout in workOuts) {
[WorkOutTypes workoutName:workout inManagedObjectContext:document.managedObjectContext];
}
}];
});
dispatch_release(pushQ);
}
- (void)useDocument
{ NSLog(@"In useDocument");
NSLog(@"File path - %@", [self.workoutDatabase.fileURL path]);
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.workoutDatabase.fileURL path]]) {
NSLog(@"1");
[self.workoutDatabase saveToURL:self.workoutDatabase.fileURL
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success){
[self setupFetchedResultsController];
[self pushWorkoutDataIntoDocument:self.workoutDatabase];
}];
}
else
if (self.workoutDatabase.documentState == UIDocumentStateClosed) {
NSLog(@"2");
[self.workoutDatabase openWithCompletionHandler:^(BOOL success){
NSLog(@"handler called");[self setupFetchedResultsController];}];
}
else
if (self.workoutDatabase.documentState == UIDocumentStateNormal) {
NSLog(@"3");
[self setupFetchedResultsController];
}
NSLog(@"End of useDocument");
}
- (void)setWorkoutDatabase:(UIManagedDocument *)workoutDatabase
{ NSLog(@"In setWorkoutDatabase");
if (_workoutDatabase != workoutDatabase) {
_workoutDatabase = workoutDatabase;
[self useDocument];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
if (!self.workoutDatabase) {
NSLog(@"Came in");
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Default Workouts Database"];
self.workoutDatabase = [[UIManagedDocument alloc] initWithFileURL:url];
NSLog(@"URL - %@", [url path]);
}
if (self.workoutDatabase) {
NSLog(@"workoutDatabase created");
}
else
NSLog(@"workoutDatabase not created");
}
Closing the question for now. I reverted to using a traditional Core Data stack instead of a UIManagedDocument. It was quite unreliable.