Setting item ubiquitous strange behaviour

708 views Asked by At

The thing is, i have a UIManagedDocument in some local directory. Im setting it ubiquitous. Here is the code :

-(void)queryGatheredInfo:(NSNotification*)notification{
    NSLog(@"Query gathered info!");
    [[NSNotificationCenter defaultCenter]removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:self.documentQuery];
    NSLog(@"Removed AppDelegate as an observer for NSMetadataQueryDidFinishGatheringNotification.");
    [self.documentQuery disableUpdates];
    NSMetadataQuery* tempQuery=[notification object];
    if(tempQuery.resultCount){
        NSLog(@"Query Found Items:");
        for (int i=0;i<tempQuery.resultCount;i++){
            NSMetadataItem* item=[tempQuery resultAtIndex:i];
            NSURL* itemURL=[item valueForAttribute:NSMetadataItemURLKey];
            NSString* itemFSName=[[self filePackageURLForCloudURL:itemURL]lastPathComponent];
            NSLog(@"Item %d: %@",i,itemFSName);
            if([itemFSName isEqualToString:kUSER_DOCUMENT_NAME]){
                NSLog(@"FOUND A SAVED DOCUMENT IN iCLOUD!");
                [self loadDocumentFromiCloudAtURL:[itemURL URLByDeletingLastPathComponent]withPersistentStoreOptions:[self getPersistentOptionsFromDocumentMetadataAtURL:itemURL]];
                break;
            }
        }
    }else{
        NSLog(@"Query did not found a document in iCloud!");
        if([[NSFileManager defaultManager]fileExistsAtPath:[[self localDocumentURL]path]]){
            NSLog(@"Document was found in local documents directory.");
            [self transferFileFromLocalDirectory:[self localDocumentURL] ToiCloudDirectory:[[self iCloudDocumentsURL]URLByAppendingPathComponent:kUSER_DOCUMENT_NAME]];
        }else{
            NSLog(@"Creating new document in iCloud!");
            [self createNewDocumentIniCloud];
        }
    }
    [self.documentQuery stopQuery];
}
-(void)transferFileFromLocalDirectory:(NSURL*)localURL ToiCloudDirectory:(NSURL*)iCloudURL{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSError* error=nil;
        BOOL flag=[[NSFileManager defaultManager]setUbiquitous:YES itemAtURL:localURL destinationURL:iCloudURL error:&error];
        if(flag){
            NSLog(@"Successfully set document ubiquitous");
            UIManagedDocument* doc=[[UIManagedDocument alloc]initWithFileURL:iCloudURL];
            doc.persistentStoreOptions=[self getPersistentOptionsFromDocumentMetadataAtURL:[iCloudURL URLByAppendingPathComponent:@"DocumentMetadata.plist"]];
            [self openDocument:doc];
        }else{
            NSLog(@"There was an error setting document Ubiquitous.\n%@",error);
        }
    });
}

And after this, it starts to download copies of itself for 2 times. So at the end i get the 3 same items in my core data. But if i delete the app, and run it again, it finds document in icloud, loads it, and it looks alright, no duplicate items. My question is: what's happening when i set my document ubiquitous? why does it load duplicates?

Here is output when the item is set ubiquitous:

2013-12-01 22:02:56.452 iGymPRO[5517:60b] iCloud is available
2013-12-01 22:02:56.456 iGymPRO[5517:60b] Added AppDelegate as an observer for NSMetadataQueryDidFinishGatheringNotification.
2013-12-01 22:02:56.458 iGymPRO[5517:60b] Query started!
2013-12-01 22:02:56.500 iGymPRO[5517:60b] Query gathered info!
2013-12-01 22:02:56.502 iGymPRO[5517:60b] Removed AppDelegate as an observer for NSMetadataQueryDidFinishGatheringNotification.
2013-12-01 22:02:56.503 iGymPRO[5517:60b] Query did not found a document in iCloud!
2013-12-01 22:02:56.569 iGymPRO[5517:60b] Document was found in local documents directory.
2013-12-01 22:02:56.609 iGymPRO[5517:1803] Successfully set document ubiquitous
2013-12-01 22:02:56.983 iGymPRO[5517:3e03] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5815F60F-67BF-4FD1-8376-B509672B469D:UserDataDocumentContent
Using local storage: 1
2013-12-01 22:02:57.055 iGymPRO[5517:60b] Opened document
2013-12-01 22:02:57.057 iGymPRO[5517:60b] Removing delegate as an observer for UIDocumentStateChangedNotification
2013-12-01 22:02:57.059 iGymPRO[5517:60b] Listening to UIDocumentStateChangedNotification
2013-12-01 22:02:57.060 iGymPRO[5517:60b] Managed Object Context is ready to use! Dismissing loading screen
2013-12-01 22:02:57.925 iGymPRO[5517:4707] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5815F60F-67BF-4FD1-8376-B509672B469D:UserDataDocumentContent
Using local storage: 0
2013-12-01 22:03:02.650 iGymPRO[5517:4707] -[PFUbiquitySetupAssistant finishSetupWithRetry:](811): CoreData: Ubiquity:  <PFUbiquitySetupAssistant: 0x1463c2f0>: Retrying after delay: 60
2013-12-01 22:04:09.390 iGymPRO[5517:470b] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5815F60F-67BF-4FD1-8376-B509672B469D:UserDataDocumentContent
Using local storage: 0
2013-12-01 22:04:13.875 iGymPRO[5517:470b] -[PFUbiquitySetupAssistant finishSetupWithRetry:](811): CoreData: Ubiquity:  <PFUbiquitySetupAssistant: 0x1463c2f0>: Retrying after delay: 120
2013-12-01 22:06:59.170 iGymPRO[5517:4717] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5815F60F-67BF-4FD1-8376-B509672B469D:UserDataDocumentContent
Using local storage: 0
2013-12-01 22:13:34.370 iGymPRO[5517:4227] __45-[PFUbiquityFilePresenter processPendingURLs]_block_invoke(305): CoreData: Ubiquity:  Librian returned a serious error for starting downloads Error Domain=LibrarianErrorDomain Code=1 "The operation couldn’t be completed. (LibrarianErrorDomain error 1 - Unable to initiate download.)" UserInfo=0x1467b370 {Item Errors={
    "file:///private/var/mobile/Library/Mobile%20Documents/476DPCGZ25~trenbolone~SP~iGym/CoreData/UserDataDocumentContent/mobile~5815F60F-67BF-4FD1-8376-B509672B469D/UserDataDocumentContent/GxrbFeXHGcfBNM0uvaCzuqHE4XmcYCiCKbgWv7OTybM=/receipt.0.cdt" = "Error Domain=UBErrorDomain Code=10 \"The operation couldn\U2019t be completed. (UBErrorDomain error 10 - Error Domain=UBErrorDomain Code=10 \"The operation couldn\U2019t be completed. (UBErrorDomain error 10 - The item can't be found on disk, is not yet scanned or was deleted)\" UserInfo=0x14570a30 {NSDescription=The item can't be found on disk, is not yet scanned or was deleted})\" UserInfo=0x1463c6a0 {NSDescription=Error Domain=UBErrorDomain Code=10 \"The operation couldn\U2019t be completed. (UBErrorDomain error 10 - The item can't be found on disk, is not yet scanned or was deleted)\" UserInfo=0x14570a30 {NSDescription=The item can't be found on disk, is not yet scanned or was deleted}}";
}, NSUnderlyingError=0x1470d510 "The operation couldn’t be completed. (UBErrorDomain error 10 - The item can't be found on disk, is not yet scanned or was deleted)", NSDescription=Unable to initiate download.} with userInfo {
    "Item Errors" =     {
        "file:///private/var/mobile/Library/Mobile%20Documents/476DPCGZ25~trenbolone~SP~iGym/CoreData/UserDataDocumentContent/mobile~5815F60F-67BF-4FD1-8376-B509672B469D/UserDataDocumentContent/GxrbFeXHGcfBNM0uvaCzuqHE4XmcYCiCKbgWv7OTybM=/receipt.0.cdt" = "Error Domain=UBErrorDomain Code=10 \"The operation couldn\U2019t be completed. (UBErrorDomain error 10 - Error Domain=UBErrorDomain Code=10 \"The operation couldn\U2019t be completed. (UBErrorDomain error 10 - The item can't be found on disk, is not yet scanned or was deleted)\" UserInfo=0x14570a30 {NSDescription=The item can't be found on disk, is not yet scanned or was deleted})\" UserInfo=0x1463c6a0 {NSDescription=Error Domain=UBErrorDomain Code=10 \"The operation couldn\U2019t be completed. (UBErrorDomain error 10 - The item can't be found on disk, is not yet scanned or was deleted)\" UserInfo=0x14570a30 {NSDescription=The item can't be found on disk, is not yet scanned or was deleted}}";
    };
    NSDescription = "Unable to initiate download.";
    NSUnderlyingError = "Error Domain=UBErrorDomain Code=10 \"The operation couldn\U2019t be completed. (UBErrorDomain error 10 - The item can't be found on disk, is not yet scanned or was deleted)\" UserInfo=0x145d6340 {NSDescription=The item can't be found on disk, is not yet scanned or was deleted}";
}

and this is output when i delete and run my app ( when everything loads fine)

2013-12-01 22:32:49.748 iGymPRO[5525:60b] iCloud is available
2013-12-01 22:32:49.754 iGymPRO[5525:60b] Added AppDelegate as an observer for NSMetadataQueryDidFinishGatheringNotification.
2013-12-01 22:32:49.756 iGymPRO[5525:60b] Query started!
2013-12-01 22:32:49.897 iGymPRO[5525:60b] Query gathered info!
2013-12-01 22:32:49.898 iGymPRO[5525:60b] Removed AppDelegate as an observer for NSMetadataQueryDidFinishGatheringNotification.
2013-12-01 22:32:49.899 iGymPRO[5525:60b] Query Found Items:
2013-12-01 22:32:49.959 iGymPRO[5525:60b] Item 0: Data Document
2013-12-01 22:32:49.960 iGymPRO[5525:60b] FOUND A SAVED DOCUMENT IN iCLOUD!
2013-12-01 22:32:50.031 iGymPRO[5525:60b] Opening document from iCloud
2013-12-01 22:32:54.203 iGymPRO[5525:5003] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5815F60F-67BF-4FD1-8376-B509672B469D:UserDataDocumentContent
Using local storage: 1
2013-12-01 22:32:54.259 iGymPRO[5525:60b] Opened document
2013-12-01 22:32:54.260 iGymPRO[5525:60b] Removing delegate as an observer for UIDocumentStateChangedNotification
2013-12-01 22:32:54.261 iGymPRO[5525:60b] Listening to UIDocumentStateChangedNotification
2013-12-01 22:32:54.262 iGymPRO[5525:60b] Managed Object Context is ready to use! Dismissing loading screen
2013-12-01 22:33:57.635 iGymPRO[5525:1803] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5815F60F-67BF-4FD1-8376-B509672B469D:UserDataDocumentContent
Using local storage: 0
1

There are 1 answers

2
Duncan Groenewald On BEST ANSWER

Happy to be corrected on this but I don't think this is the correct way to set a UIManagedDocument up to synch via iCloud. If you have a UIManagedDocument in a local directory you need to migrate the store itself to iCloud using the persistentStoreCoordinators migratePersistentStore method in order to recreate the log files in iCloud.

I am quite surprised it works at all when you delete and reinstall the app.