如何将数据从iCloud存储文件迁移到本地存储中的新存储文件?

时间:2012-11-12 12:07:47

标签: objective-c ios core-data persistence icloud

我的应用中有iCloud。我已从我的应用中删除iCloud,但在ios 6应用崩溃时我收到此消息:

  -[NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:](1055): 

CoreData: Ubiquity: Error:以前使用iCloud集成选项添加到协调器的持久存储必须始终使用选项字典中的选项添加到协调器中。如果您希望使用不含iCloud的商店,请将数据从iCloud商店文件迁移到本地存储中的新商店文件。

如何解决此错误?如何将数据从iCloud存储文件迁移到本地存储中的新存储文件?

2 个答案:

答案 0 :(得分:4)

是的,我也有这个问题。 我想将iCloud商店变成本地商店


解决方案1:将managedObjects逐个移动到localStore。

但是如果你有一个大型数据库,它会很慢。

所以我昨天找到了第二个解决方案。


解决方案2:编辑iCloud商店的元数据

并将其保存到新位置。

删除元数据中的“com.apple.coredata.ubiquity。*”键后, 你会得到一个完全本地的商店。


以下是解决方案2的代码:

已经设置了一些属性:

@property (nonatomic, strong) NSPersistentStoreCoordinator *coordinator;
@property (nonatomic, strong) NSManagedObjectContext *context;

@property (nonatomic, strong) NSPersistentStore *iCloudStore;
//represent the iCloud store already using 
//(after [coordinator addPersistentStore] you get this NSPersistentStore)

@property (nonatomic, strong) NSURL *iCloudStoreURL;
//represent the iCloud store real location
//(it is the URL you send to the [coordinator addPersistentStore])

@property (nonatomic, strong) NSURL *iCloudStoreLocalVersionURL;
//represent the location of local version store you want to save

迁移方法:

-(void)migrateCloudStoreToLocalVersion
{
    if(!self.iCloudStore)
        return;

    // remove previous local version
    [FILE_MANAGER removeItemAtURL:self.iCloudStoreLocalVersionURL
                            error:nil];

    // made a copy from original location to the new location
    [FILE_MANAGER copyItemAtURL:self.iCloudStoreURL
                          toURL:self.iCloudStoreLocalVersionURL
                          error:nil];

    //prepare meta data
    NSDictionary *iCloudMetadata = [self.coordinator metadataForPersistentStore:self.iCloudStore].copy;

    NSMutableDictionary *localVersionMetadata = iCloudMetadata.mutableCopy;
    for(NSString * key in iCloudMetadata){
        if([key hasPrefix:@"com.apple.coredata.ubiquity"]){
            [localVersionMetadata removeObjectForKey:key];
        }
    }

    //modify iCloud store
    [self.coordinator setMetadata:localVersionMetadata forPersistentStore:self.iCloudStore];
    [self.coordinator setURL:self.iCloudStoreLocalVersionURL forPersistentStore:self.iCloudStore];

    //save to the localVersion location
    [self.context save:nil];

    //restore iCloud store
    [self.coordinator setMetadata:iCloudMetadata forPersistentStore:self.iCloudStore];
    [self.coordinator setURL:self.iCloudStoreURL forPersistentStore:self.iCloudStore];
}

然后,您可以使用iCloudStoreLocalVersionURL来使用本地版本商店。

您可以将此本地版本存储用作本地存储,而不会出现任何错误。

注意:

注意元数据中的NSStoreUUIDKey

您可以选择将其替换为新商店。

答案 1 :(得分:0)

我相信你也必须更改UUID号码,我会在下次运行应用程序时遇到错误,它正在加载同一个商店两次。所以我做了这个修改

    if (!self.iCloudStore) return;
NSError *error = nil;

NSURL* localStoreURL = [self fallbackStoreURL];

 NSFileManager *fm = [[NSFileManager alloc] init];

 if (!self.fallbackStore) [self loadFallbackStore:&error];

NSString* fallBackUUID;

//find UUID of original to put back in later
NSDictionary *fallBackMetadata = [_psc metadataForPersistentStore:self.fallbackStore].copy;
for(NSString* key in fallBackMetadata)
{
    if([key hasPrefix:@"NSStoreUUID"])
    {
        fallBackUUID = [fallBackMetadata objectForKey:key];
        break;
    }
}

[fm removeItemAtURL:localStoreURL error:nil];


//prepare meta data
NSDictionary *iCloudMetadata = [_psc metadataForPersistentStore:self.iCloudStore].copy;
NSMutableDictionary *localVersionMetadata = iCloudMetadata.mutableCopy;
for(NSString* key in iCloudMetadata)
{
    if([key hasPrefix:@"com.apple.coredata.ubiquity"])
    {
        [localVersionMetadata removeObjectForKey:key];
    }

    if([key hasPrefix:@"NSStoreUUID"])
    {
         if (fallBackUUID) [localVersionMetadata setObject:fallBackUUID forKey:key];
    }
}


//modify iCloud store
[_psc setMetadata:localVersionMetadata forPersistentStore:self.iCloudStore];
[_psc setURL:localStoreURL forPersistentStore:self.iCloudStore];

// make a copy from original location to the new location
[fm copyItemAtURL:[self iCloudStoreURL]
                      toURL:localStoreURL
                      error:nil];

 [_fallbackContext save:nil];


[_psc setMetadata:iCloudMetadata forPersistentStore:self.iCloudStore];
[_psc setURL:[self iCloudStoreURL] forPersistentStore:self.iCloudStore];