1

I'm trying to realise sync Core Data with iCloud.

and when I try to [self fetchedResultsControllerICloud] performFetch:&error] in

-(id)init

    [self managedObjectModelICloud];
    [self managedObjectContextICloud];

    if (![[self fetchedResultsControllerICloud] performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }

I've got an Error

 2012-11-12 23:50:34.917 My English words[1072:907] iCloud access at file://localhost/private/var/mobile/Library/Mobile%20Documents/LUB2V2L4R3~ru~________~My-English-words/
 2012-11-12 23:50:34.920 My English words[1072:907] count: 0
 2012-11-12 23:50:34.935 My English words[1072:110b] iCloudData: /private/var/mobile/Library/Mobile Documents/LUB2V2L4R3~ru~________~My-English-words/Documents/My_English_words.sqlite
 2012-11-12 23:50:34.938 My English words[1072:110b] -[__NSCFConstantString path]: unrecognized selector sent to instance 0x8ca28
 2012-11-12 23:50:34.940 My English words[1072:110b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString path]: unrecognized selector sent to instance 0x8ca28'
 *** First throw call stack:
 (0x331012a3 0x33fbf97f 0x33104e07 0x33103531 0x3305af68 0x344b840b 0x343805cf 0x3437e73d 0x7fe33 0x356f111f 0x356ff259 0x356ff3b9 0x3572fa11 0x3572f8a4)
 libc++abi.dylib: terminate called throwing an exception
 (lldb)

linked with [_persistentStoreCoordinatorICloud addPersistentStoreWithType:NSSQLiteStoreType string in - (NSPersistentStoreCoordinator *)persistentStoreCoordinatorICloud method

#define sqlLiteDataBaseName @"My_English_words.sqlite"
#define sqlLiteDataBasePath @"Documents"
#define iCloudEnabledAppID @"LUB2V2L4R3.ru.________.My-English-words"

//************************************************

- (NSManagedObjectContext *)managedObjectContextICloud
{
    if (_managedObjectContextICloud != nil) {
        return _managedObjectContextICloud;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinatorICloud];
    if (coordinator != nil) {
        _managedObjectContextICloud = [[NSManagedObjectContext alloc] init];
        [_managedObjectContextICloud setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContextICloud;
}
//************************************************

- (NSManagedObjectModel *)managedObjectModelICloud
{
    if (_managedObjectModelICloud != nil) {
        return _managedObjectModelICloud;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"My_English_words" withExtension:@"momd"];
    _managedObjectModelICloud = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModelICloud;
}
//************************************************
    - (NSPersistentStoreCoordinator *)persistentStoreCoordinatorICloud
    {
        NSURL *iCloud = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
        NSLog(@"iCloud access at %@", iCloud);
        NSString *pathString=[[iCloud path] stringByAppendingPathComponent:sqlLiteDataBasePath];
        _persistentStoreCoordinatorICloud = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModelICloud]];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        if([[NSFileManager defaultManager] fileExistsAtPath:pathString] == NO)
        {
            NSLog(@"!Exist");
            NSError *fileSystemError;
            [[NSFileManager defaultManager] createDirectoryAtPath:pathString
                                      withIntermediateDirectories:YES
                                                       attributes:nil
                                                            error:&fileSystemError];
            if(fileSystemError != nil) {
                NSLog(@"Error creating database directory %@", fileSystemError);
            }

        }

        NSString *iCloudData = [[[iCloud path] stringByAppendingPathComponent:sqlLiteDataBasePath] stringByAppendingPathComponent:sqlLiteDataBaseName];
        NSLog(@"iCloudData: %@",iCloudData);
        NSMutableDictionary *options = [NSMutableDictionary dictionary];
        [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
        [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
        [options setObject:iCloudEnabledAppID            forKey:NSPersistentStoreUbiquitousContentNameKey];
        [options setObject:sqlLiteDataBasePath           forKey:NSPersistentStoreUbiquitousContentURLKey];


        [_persistentStoreCoordinatorICloud lock];

        [_persistentStoreCoordinatorICloud addPersistentStoreWithType:NSSQLiteStoreType
                                                        configuration:nil
                                                                  URL:[NSURL fileURLWithPath:iCloudData]
                                                              options:options
                                                                error:nil];

        [_persistentStoreCoordinatorICloud unlock];

        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"asynchronously added persistent store!");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"RefetchAllDatabaseData" object:self userInfo:nil];
        });
    });    
    return _persistentStoreCoordinatorICloud;
}
//************************************************
    - (NSFetchedResultsController *)fetchedResultsControllerICloud{

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"OriginalWords" inManagedObjectContext:_managedObjectContextICloud];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    [fetchRequest setFetchBatchSize:1000];

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                                                  managedObjectContext:_managedObjectContextICloud
                                                                                                    sectionNameKeyPath:nil
                                                                                                             cacheName:nil];

    self.fetchedResultsControllerICloud  = theFetchedResultsController;
    _fetchedResultsControllerICloud.delegate = self;

    return _fetchedResultsControllerICloud;


}
  • 1
    Somewhere you got an NSString where there probably should be an NSURL. If you look at the exception traceback it will tell you where. – Hot Licks Nov 12 '12 at 18:18
  • 1
    I suspect that the `iCloud` variable is not being brought into the block context correctly. What if you call `URLForUbiquityContainerIdentifier:` method inside your block instead of using `iCloud`? (If it gets rid of the error message, it narrows the problem.) – Phillip Mills Nov 12 '12 at 18:27
  • thanks for suggestions, Really interesting thing, despite this error, after running this script the sqlite file was created in iCloud. – Alexander Sharunov Nov 14 '12 at 05:28
  • the error has been resolved. Problem was in [options setObject:sqlLiteDataBasePath forKey:NSPersistentStoreUbiquitousContentURLKey]; #define sqlLiteDataBasePath @"Documents" very stupid error, but now i've got another one error: 'This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation'. I think it happen due to [_managedObjectContextICloud save:&error] – Alexander Sharunov Nov 15 '12 at 03:30

1 Answers1

0

the error has been resolved. Problem was in

[options setObject:sqlLiteDataBasePath forKey:NSPersistentStoreUbiquitousContentURLKey];

where sqlLiteDataBasePath path should be full

[[iCloud URLByAppendingPathComponent:sqlLiteDataBasePath] URLByAppendingPathComponent:sqlLiteDataBaseName]

very stupid error, but now i've got another one error:

'This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation'. 

I think it happen due to

[_managedObjectContextICloud save:&error]
  • Solved! The answer is: you may also be doing wrong is to modify the context (for example adding new managed objects to it) and then trying to save it, before the store has been initialized. – Alexander Sharunov Nov 15 '12 at 14:29