Ios 在应用程序运行时启用/禁用核心数据的iCloud同步

Ios 在应用程序运行时启用/禁用核心数据的iCloud同步,ios,objective-c,core-data,ios7,icloud,Ios,Objective C,Core Data,Ios7,Icloud,如何添加启用和禁用iCloud核心数据同步(iOS7)的选项 以下是我的想法/尝试: 要禁用iCloud同步,请执行以下操作: NSDictionary *options = @{NSPersistentStoreUbiquitousContentNameKey: @"MYStore"}; [NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeUrl options:options er

如何添加启用和禁用iCloud核心数据同步(iOS7)的选项

以下是我的想法/尝试:

要禁用iCloud同步,请执行以下操作:

NSDictionary *options = @{NSPersistentStoreUbiquitousContentNameKey: @"MYStore"};
[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeUrl options:options error:&error];
NSDictionary *options = @{NSPersistentStoreUbiquitousContentNameKey: @"MYStore"};
[__persistentStoreCoordinator lock];
result = [__persistentStoreCoordinator migratePersistentStore:result toURL:storeUrl options:options withType:NSSQLiteStoreType error:&error];
[__persistentStoreCoordinator unlock];
但是,我认为这可能会删除iCloud中的所有数据?我不想那样

要启用iCloud同步,请执行以下操作:

NSDictionary *options = @{NSPersistentStoreUbiquitousContentNameKey: @"MYStore"};
[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeUrl options:options error:&error];
NSDictionary *options = @{NSPersistentStoreUbiquitousContentNameKey: @"MYStore"};
[__persistentStoreCoordinator lock];
result = [__persistentStoreCoordinator migratePersistentStore:result toURL:storeUrl options:options withType:NSSQLiteStoreType error:&error];
[__persistentStoreCoordinator unlock];
在这段代码中,我尝试使用
NSPersistentStoreUbiquitousContentNameKey
键添加
选项
,以便它开始与iCloud同步。但是,我不想把商店搬到一个新的地方。这个代码正确吗


如何在应用程序运行时启用/禁用iCloud?

以下是我用于启用或禁用iCloud sync(OS X)的方法,基本上每次都会重建存储,这与在应用程序运行时启用和禁用iCloud sync不同。所以你不想用它来“暂停”同步

据我所知,您需要以下内容:

如果您在应用程序运行时关闭了iCloud sync,然后执行了一些更新,则您不希望同步这些更改,但稍后重新打开iCloud sync时,您希望同步后续更改

我可能错了,但我认为您可能会因为使用标准的Core Data/iCloud集成而运气不佳

根据您的要求,您可能只需观察导入通知并放弃任何更改,但我看不出您将如何避免出现各种可能导致后续导入失败的数据不一致

    // Removes the current Document from iCloud and deletes the local copy.
    // There does not appear to be any way of only removing ubiquitous content
    // and turning off iCloud sync.
    // So before we remove it we make a local copy by appending "_Backup" to the filename
    // (we should check this filename does not already exist and add a counter or something)
    //
    - (void)removeMeFromICloud {
        //LOG(@"removeMeFromICloud called");
        NSError *error;

        NSURL *currentURL = self.fileURL;
        NSString *fileType = self.fileType;
        NSString *extension = [currentURL pathExtension];
        NSString *path = [[currentURL URLByDeletingPathExtension] path];
        NSString *backupFilename = [NSString stringWithFormat:@"%@_Backup", path];
        NSURL *backupFileURL = [[[NSURL alloc] initFileURLWithPath:backupFilename] URLByAppendingPathExtension:extension];

        // We only have one store
        NSPersistentStore *currentStore = [self.managedObjectContext.persistentStoreCoordinator.persistentStores objectAtIndex:0];
        NSDictionary *currentOptions = currentStore.options;

        if ([self buildNewStoreAtURL:backupFileURL type:fileType error:&error]) {

            //FLOG(@" reset the moc...");
            [self.managedObjectContext reset];
            [self.managedObjectContext save:&error];

            //Set the document title
            //FLOG(@" current displayName is %@", self.displayName);
            self.fileURL = backupFileURL;

            //set the file extension hidden attribute to YES
            NSDictionary* fileAttrs = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
                                                                  forKey:NSFileExtensionHidden];
            if(![[NSFileManager defaultManager] setAttributes:fileAttrs
                                                 ofItemAtPath:[backupFileURL path]
                                                        error:&error])
                FLOG(@" unable to set file attributes to hide extension");

            // Now remove the old one
            bool success = [NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:currentURL options:currentOptions error:&error];

            if (success) {
                FLOG(@" removed document from iCloud");
                FLOG(@" using backup copy");
            }
            else  {
                FLOG(@" error removing document from iCloud");
                FLOG(@" error is %@, %@", error, error.userInfo);
            }
        } else {
            FLOG(@" error creating backup before removing from iCloud");
            FLOG(@" error is %@, %@", error, error.userInfo);
        }
    }

    // in order to migrate to the cloud we have to build the database from scratch,
    // we can't just open it with iCloud parameters because we have to ensure that
    // log files get generated in iCloud that will allow the store to be rebuilt from
    // scratch by peer devices.
    //
    - (void)migrateMeToICloud {
        //LOG(@"migrateMeToICloud called");

        NSPersistentStoreCoordinator *psc = self.managedObjectContext.persistentStoreCoordinator;

        NSArray *stores = psc.persistentStores;
        NSError *error;

        // Now get current URL and add_iCloud to the document name, use this for the new store name
        NSURL *currentURL = self.fileURL;
        NSString *extension = [self.fileURL pathExtension];
        NSString *currentFilePathName = [[currentURL URLByDeletingPathExtension] path];
        NSString *uuidString = [[NSUUID UUID] UUIDString];
        NSString *newFilePathName = [NSString stringWithFormat:@"%@_UUID_%@",currentFilePathName, uuidString];

        // We must make it NSSQLite so get the right extension...
        NSURL *newURL = [[[NSURL alloc] initFileURLWithPath:newFilePathName] URLByAppendingPathExtension:extension];

        NSDictionary *options = [self storeOptionsForICloud:self.fileURL];
        NSString *ubiquityName = [options valueForKey:NSPersistentStoreUbiquitousContentNameKey];


        if ([stores count]) {
            NSPersistentStore *store = [stores objectAtIndex:0];

            if (store) {
                //FLOG(@" starting migration...");

                NSPersistentStore *newStore = [psc migratePersistentStore:store toURL:newURL options:options withType:NSSQLiteStoreType error:&error];
                //FLOG(@"  psc is %@", psc);

                //FLOG(@" done migrating...");
                if (newStore != nil) {
                    //FLOG(@" new store seems OK...");

                    // Set custom metadata so we know if it is synced in iCloud next time we open it
                    [self setiCloudMetaDataForStore:currentURL ofType:NSSQLiteStoreType iCloud:YES ubiquityName:ubiquityName];

                }
                else  {
                    FLOG(@" error migrating store");
                    FLOG(@" error is %@, %@", error, error.userInfo);

                }
            } else  {
                FLOG(@" store is nil, nothing to migrate!");
            }
        }

    }

// File is NEVER iCloud enabled when we do this.
// Is we do Save As we pnly build a local store wihout iCloud sync.
// User can select iCloud sync once Save As is done
//
- (bool)buildNewStoreAtURL:(NSURL*)newURL type:(NSString *)typeName error:(NSError **)error {

    //FLOG(@"buildNewStoreAtURL:type: called");

    NSError *myError;

    // We only have one store
    NSPersistentStore *currentStore = [self.managedObjectContext.persistentStoreCoordinator.persistentStores objectAtIndex:0];
    NSDictionary *currentOptions = currentStore.options;

    // We usually would need to create a new UUID for the new document if it is in iCloud.
    // But since we create a local copy only we don't need this.
    NSMutableDictionary *newOptions = [[NSMutableDictionary alloc] initWithDictionary:currentOptions];
    [newOptions setObject:@"DELETE" forKey:@"JOURNAL"];

    // Remove any iCloud options (this one includes the unique iCloud UUID
    [newOptions removeObjectForKey:NSPersistentStoreUbiquitousContentNameKey];

    // Remove Core Data ubiquity metadata
    [newOptions setObject:[NSNumber numberWithBool:YES] forKey:NSPersistentStoreRemoveUbiquitousMetadataOption];


    NSPersistentStoreCoordinator *psc = self.managedObjectContext.persistentStoreCoordinator;

    // Now migrate the store to the new location
    NSPersistentStore *newStore = [psc migratePersistentStore:currentStore toURL:newURL options:newOptions withType:typeName error:&myError];

    if (newStore) {

        // Now set up our custom metadata so we can determine if it has been synced in iCloud next time we open it
        NSDictionary *dict = [self getiCloudMetaDataForStore:[psc metadataForPersistentStore:newStore] iCloud:NO ubiquityName:nil];

        [psc setMetadata:dict forPersistentStore:newStore];

        return YES;
    }
    else {

        FLOG(@" problem creating new document");
        FLOG(@"  - error is %@, %@", myError, myError.userInfo);
        *error = myError;
        return NO;
    }

}

谢谢,但是这似乎没有实现iCloud的新iOS7方法(即设置
NSPersistentStoreUbiquitousContentNameKey
)。我将使用新的iOS7方法。您好,您是否找到了满足您需求的解决方案或解决方案?我对我的应用程序有相同的要求。如果您有任何解决方案,请与我们分享。谢谢