iCloud Core Data "no document at URL"

638 views Asked by At

I have an app with core data and icloud to allow the user to use the same database on several devices. The sync works most of the time perfect, but sometimes it doesn't, i.e. some transactions are simply skipped.

When I check the console, I get the error message:

__45-[PFUbiquityFilePresenter processPendingURLs]_block_invoke(439): CoreData: Ubiquity:  Librarian returned a serious error for starting downloads Error Domain=BRCloudDocsErrorDomain Code=5 "The operation couldn’t be completed. (BRCloudDocsErrorDomain error 5 - No document at URL)"  

Funny enough this message appears even when the sync works.  

The code fits to Apple latest version of " iCloud Programming Guide for Core Data". The storeURL is coded as follows:

 NSURL *documentsDirectory = [[[NSFileManager defaultManager]  URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
 NSURL *storeURL = [documentsDirectory  URLByAppendingPathComponent:@"iCloudSample.sqlite"];

The code for the options:

  storeOptions =          @{NSPersistentStoreUbiquitousContentNameKey: @"iCloudSampleStore" ,
                            NSPersistentStoreUbiquitousContentURLKey: @"iCloudSampleURL"};

The code for the store:

NSPersistentStore *store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                     configuration:nil
                                                               URL:storeURL
                                                           options:storeOptions
                                                             error:&error];

The merge policy (MOC is on the main qeue)

  _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];

_managedObjectContext.mergePolicy = [[NSMergePolicy alloc]
                                    initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType];

As I understand the docs, there is not really much more to do(?). But I guess I'm missing something, does anyone has an idea what to check, change, try? Anyone who had the same problem? Any ideas are appreciated!

2

There are 2 answers

1
viktronics On

I have the same problem and solved it by removing the persistentStore and adding it again while the app is running. It is always the same problem when doing several changes in the first device, the second device doesn't get all the changes. I use the following code when applicationDidBecomeActive to remove the persistent store first:

var storeCoordinator:NSPersistentStoreCoordinator = persistentStoreCoordinator!
        var store:NSPersistentStore = storeCoordinator.persistentStores[0] as! NSPersistentStore
        var storeURL:NSURL = store.URL!
        storeCoordinator.removePersistentStore(store, error: nil)
        NSFileManager.defaultManager().removeItemAtPath(storeURL.path!, error: nil)

Following this I proceed to add the persistentStore again. Then I received all the notifications as it was the first run after installation but with the full data synched. it always works but I don't know if it is the proper way to handle the problem.

I believe that all the changes made in the first device always reach the second device but for some weird reason they don't merge completely with the local core data. I have made some weird observations about the iCloud-CoreData issue in:

https://stackoverflow.com/questions/32084952/core-data-to-icloud-doesnt-sync-all-changes

I hope it helps.

0
One In a Million Apps On

I found that when my store URL had .s in the path

(e.g. ---/com.companyName.project/---)

let applicationSupportDirectory = applicationSupportDirectoryURL.URLByAppendingPathComponent("com.companyName.project")
let iCloudStoreFileName = "iCloud.sqlite"
lazy var iCloudStoreURL: NSURL = {
    return self.applicationSupportDirectory.URLByAppendingPathComponent(self.iCloudStoreFileName)
}()

When I enabled logging, by going to Edit Scheme... in Xcode for my project and adding:

-com.apple.CoreData.SyntaxColoredLogging 1

the log file in the debug window showed the path it was searching was

---/com~companyName~project/---

Core data had changed the .s to ~s. I eliminated the entire com.companyName.project from the URL and synchronizing seems to work better. But with core data and iCloud you never know - there's soooo much magic going on behind the scenes.