Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS CoreData: How to setup the core data "connection"? Stanford UIDocument vs. Apple template?

I've worked through the Stanford course and setup my first app and core data as in the lecture. Approximately like this (I will shift the code into the app delegate now):

- (void)setupFetchedResultsController
{
    NSError *error = nil;
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MainCategory"];
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"position" ascending:YES]];
    [self.budgetDatabase.managedObjectContext executeFetchRequest:request error:&error];

    self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request
                                                                       managedObjectContext:self.budgetDatabase.managedObjectContext
                                                                         sectionNameKeyPath:nil
                                                                                  cacheName:nil];
}

-(void)useDocument
{
    if(![[NSFileManager defaultManager]fileExistsAtPath:[self.budgetDatabase.fileURL path]]){
        [self.budgetDatabase saveToURL:self.budgetDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
            [self setupFetchedResultsController];
        }];
    } else if (self.budgetDatabase.documentState == UIDocumentStateClosed){
        [self.budgetDatabase openWithCompletionHandler:^(BOOL success){
            [self setupFetchedResultsController];
        }];
    } else if (self.budgetDatabase.documentState == UIDocumentStateNormal){
        [self setupFetchedResultsController];
    }
}

- (void)viewWillAppear:(BOOL)animated
{
    //Initialize database
    [super viewWillAppear:animated];
    if(!self.budgetDatabase){
        NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentationDirectory inDomains:NSUserDomainMask] lastObject];
        [url URLByAppendingPathComponent:@"BudgetDatabase"];
        self.budgetDatabase = [[UIManagedDocument alloc]initWithFileURL:url];
    }
}

The code in the Apple template (if you check "CoreData" when creating a Xcode project) looks very different and more complex. What's the difference to this UIManagedDocument? Is there a better or worse?

like image 510
MichiZH Avatar asked Oct 03 '22 00:10

MichiZH


1 Answers

The UIManagedDocument is designed for applications that have documents, hence the name. The Stanford class is using it to skip over the construction of Core Data to make it "easier" for the student. Unfortunately they are making life harder for you in the long run.

Do not use UIManagedDocument. Start with the Apple templates, learn how to stand up the Core Data stack. You will gain more knowledge that way, have a better understanding of what the code is doing (less magic) and will progress as a developer.

UIManagedDocument has a lot of sharp edges and it is difficult to work with when things start getting complex. Skip it.

Update

UIManagedDocument is not designed to be the single Core Data stack for an application, it is meant for document based applications.

The fact that you cannot guarantee a save (without hacking at it) is a big risk. It is also an opaque construct and you are not supposed to dive down into its private context.

The fact that it will save on its own with no way to stop it makes it dangerous in my book. It is very easy for you to be wanting the context not saved (heavy UI, playing a video, etc.) and it decides to save. Bad UX.

Add on top of that, it is intended to be used with external file structures that are complicated to work with and it gets even more risky.

What does it save you? Nothing. It is not a code savings because the 6 lines of code to stand up a normal Core Data stack are replaced by a lot of asynchronous code to stand up and deploy a UIManagedDocument.

How do you handle a migration? What happens when the migration requires extra effort beyond a lightweight migration?

Lots of things to consider.

Number one in my book is the random and async saving. I just don't like the idea of giving up that control.

like image 76
Marcus S. Zarra Avatar answered Oct 13 '22 10:10

Marcus S. Zarra