drewmccormack / ensembles

A synchronization framework for Core Data.
MIT License
1.63k stars 131 forks source link

mergeWithCompletion on second device always completes with error: Error Domain=NSCocoaErrorDomain Code=3072 "The operation couldn’t be completed. (Cocoa error 3072.)" #77

Closed kunalsood closed 10 years ago

kunalsood commented 10 years ago

Before I begin explaining this, I must say, I have a strong feeling that this is something I'm doing wrong.

The issue I have run into is, I'm having trouble getting a second device to do a mergeWithCompletion: successfully.

Here are the steps I've followed, several times..

    CDEPersistentStoreEnsemble *ensemble;
    CDEICloudFileSystem *cloudFileSystem;
    // Setup Ensemble
    cloudFileSystem = [[CDEICloudFileSystem alloc]
                       initWithUbiquityContainerIdentifier:my ubiquity container identifier];
    ensemble = [[CDEPersistentStoreEnsemble alloc] initWithEnsembleIdentifier:my ensemble identifier
                                                          persistentStorePath:path to my persistent store file
                                                        managedObjectModelURL:path to my managed object model (momd) file
                                                              cloudFileSystem:cloudFileSystem];
    ensemble.delegate = self;

    if (!ensemble.isLeeched)
    {
        [ensemble leechPersistentStoreWithCompletion:^(NSError *error) {
            if (error)
            {
                NSLog(@"Could not leech to ensemble: %@", error);
            }
            else
            {
                NSLog(@"Leeching succeeded");
            }
        }];
    }
    else
    {
        NSLog(@"isLeeched");
    }

Replacing my ensemble identifier, path to my persistent store file and path to my managed object model (momd) file with appropriate strings.

     - (void)persistentStoreEnsemble:(CDEPersistentStoreEnsemble *)ensemble didSaveMergeChangesWithNotification:(NSNotification *)notification
{
    [self.managedObjectContext performBlock:^{
        [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
    }];
}
     NSLog(@"Attempting to merge");
    [ensemble mergeWithCompletion:^(NSError *error) {
        if (error)
        {
            NSLog(@"Error merging: %@", error);
        }
        else
        {
            NSLog(@"Merge succeeded");
        }
    }];
Leeching succeeded

and, then I add some information to manipulate the data in my core data store, and tap the button that calls mergeWithCompletion:, the console logs..

Attempting to merge
Merge succeeded

followed by the iCloud gauge showing upload activity.

Leeching succeeded
Error merging: Error Domain=NSCocoaErrorDomain Code=3072 "The operation couldn’t be completed. (Cocoa error 3072.)"
Leeching succeeded

Call mergeWithCompletion:

Error merging: Error Domain=NSCocoaErrorDomain Code=3072 "The operation couldn’t be completed. (Cocoa error 3072.)"

Now, this is what <Foundation/FoundationErrors.h> says about 3072..

NSUserCancelledError = 3072,                                            // User cancelled operation (this one often doesn't deserve a panel and might be a good one to special case)

As cough nice cough an explanation as that is, I'm hoping someone might be able to tell me what I could be doing wrong here.

drewmccormack commented 10 years ago

I am pretty sure that the error you are seeing is just that the iCloud files have not been downloaded yet. Ensembles will request the files when it sees the metadata, and then it is up to iCloud to download. This part can take some time, and ensembles can't influence it. It is up to iCloud.

When the metadata for an iCloud file arrives, that file will seem to be in the file system, even if it hadn't been downloaded yet.

So what is happening is that ensembles is looking at the new files, trying to import them, and failing because one or more are not downloaded yet. In general, this is not a serious failure, and you should just retry a bit later.

I am surprised you can't get the sync to work at all. What if you are really patient, wait 15 minutes, and then try again?

Have you tested with the Idiomatic test app to see if that works?

Drew

drewmccormack commented 10 years ago

By the way, the cancelled error arises because ensembles uses a timeout to cancel file operations that take too long due to the file not yet being downloaded. We thought it was better just to fail the merge quickly and try later, rather than waiting for the download, which could take minutes or longer.

Drew

kunalsood commented 10 years ago

Confirmed, this was indeed the issue. Thanks for taking the time to explain this, and the improved error!!