3

I have some NSLogs set up to ensure that my app syncs changes with iCloud, but I've waited half an hour and changes aren't being sync'd. Here's the code I have for core data. The Core Data Store is stored inside the documents directory because I want it to continue working if it loses access to iCloud, and don't want it to lose the database to be lost in that instance.

Core data sets up and makes changes to data as normal, but just doesn't seem to sync with iCloud.

- (void)mergeChangesFromiCloud:(NSNotification *)notification {
    NSLog(@"changes from iCloud");
    NSManagedObjectContext* moc = [self managedObjectContext];

    [moc performBlock:^{

        [moc mergeChangesFromContextDidSaveNotification:notification];

        NSNotification* refreshNotification = [NSNotification notificationWithName:@"SomethingChanged"
                                                                            object:self
                                                                          userInfo:[notification userInfo]];

        [[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
    }];
}

#pragma mark - Core Data Objects

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {

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

        [_managedObjectContext performBlockAndWait:^{
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
        [[NSNotificationCenter defaultCenter]addObserver:self
                                                selector:@selector(mergeChangesFromiCloud:)
                                                    name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
                                                  object:coordinator];
        }];

    }
    return _managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel {

    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }

    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:DATABASE_MODEL_URL];

    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURL = [NSURL fileURLWithPath:STORE_PATH];

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSMutableDictionary *options = [NSMutableDictionary dictionary];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
    NSLog(@"icloud: %@", iCloud);
    if (iCloud) {

        NSString *iCloudLogsDirectoryName = @"Logs";
        NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];

        //Create logs directory, in case it doesn't exist
        if([fileManager fileExistsAtPath:[iCloudLogsPath path]] == NO) {
            NSLog(@"logs directory doesn't exist");
            NSError *fileSystemError;
            [fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]
                   withIntermediateDirectories:YES
                                    attributes:nil
                                         error:&fileSystemError];
            if(fileSystemError != nil) {
                NSLog(@"Error creating database directory %@", fileSystemError);
            }

        NSString *iCloudEnabledAppID = @"ID REMOVED FROM STACK OVERFLOW";

        [options setObject:iCloudEnabledAppID            forKey:NSPersistentStoreUbiquitousContentNameKey];
        [options setObject:iCloudLogsPath                forKey:NSPersistentStoreUbiquitousContentURLKey];

        [_persistentStoreCoordinator lock];

        [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                          configuration:nil
                                    URL:storeURL
                                options:options
                                  error:nil];

        [_persistentStoreCoordinator unlock];

        }

        else {

            [_persistentStoreCoordinator lock];

            [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                              configuration:nil
                                        URL:storeURL
                                    options:options
                                      error:nil];

            [_persistentStoreCoordinator unlock];
        }

    }

    [[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" object:self userInfo:nil];


    return _persistentStoreCoordinator;
}

Edit: The problem was that the addPersistantStore code was in the wrong place, in terms of brackets. It should have been a bracket lower.

Andrew
  • 15,935
  • 28
  • 121
  • 203

0 Answers0