Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 将iCloud存储迁移到本地_Objective C_Core Data_Ios7_Icloud - Fatal编程技术网

Objective c 将iCloud存储迁移到本地

Objective c 将iCloud存储迁移到本地,objective-c,core-data,ios7,icloud,Objective C,Core Data,Ios7,Icloud,移植在模拟器上运行良好。但在设备上,我看不到任何错误消息,但迁移的存储是空的 NSDictionary *iCloudOptions = @{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudNimbleStore", NSPersistentStoreUbiquitousContentURLKey : @"transactions_logs", NSMigratePersistentStoresAutomatica

移植在模拟器上运行良好。但在设备上,我看不到任何错误消息,但迁移的存储是空的

NSDictionary *iCloudOptions = @{
    NSPersistentStoreUbiquitousContentNameKey : @"iCloudNimbleStore",
    NSPersistentStoreUbiquitousContentURLKey : @"transactions_logs",
    NSMigratePersistentStoresAutomaticallyOption : @YES,
    NSInferMappingModelAutomaticallyOption : @YES
};
NSDictionary *localOptions = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
    NSInferMappingModelAutomaticallyOption : @YES
};
if (![[NSFileManager defaultManager]fileExistsAtPath:self.storeURL.path]) {
    @synchronized(@"Migration")
    {
        // thread-safe code
        if ([[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]) {
            NSLog(@"iCloud");
            [self migrateStoreFromURL:[self nb_URLToStoreWithFilename:[self nb_appName]]options:iCloudOptions];
        }else{
            [self migrateStoreFromURL:[self nb_URLToStoreWithFilename:[NSString stringWithFormat:@"%@.sqlite", [self nb_appName]]] options:localOptions];
            //
            [self migrateStoreFromURL:[self nb_URLToOldStoreWithFilename] options:localOptions];
        }
    }
}

NSDictionary *options = @{
    NSMigratePersistentStoresAutomaticallyOption:@YES
    ,NSInferMappingModelAutomaticallyOption:@YES
};
NSError *error = nil;
[_coordinator lock];
_store = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:options error:&error];
[_coordinator unlock];
if (!_store) {
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Loading Fail" message:[NSString stringWithFormat:@"Failed to add store. Error: %@", error] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
    NSLog(@"Failed to add store. Error: %@", error);abort();
} else {
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Loading Success" message:[NSString stringWithFormat:@"Successfully added store: %@", _store] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
    NSLog(@"Successfully added store: %@", _store);
    if (_store && !error) {
        // Encrypt the password database
        NSError *encrError;
        NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
        if (![[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:self.storeURL.path error:&encrError]){
            NSLog(@"Unresolved error with password store encryption %@, %@", encrError, [encrError userInfo]); 
            abort();
        }else {NSLog(@"Encrypted");}
    }
}
以下是迁移过程:

- (void)migrateStoreFromURL:(NSURL *)oldStoreURL options:(NSDictionary *)oldOptions{
if (debug==1) {
    TFLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
}
if (_store)
{
    NSLog(@"NOT NEEDED");
    return;
}

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Migration" message:[NSString stringWithFormat:@"Found old store at %@",oldStoreURL.path] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];

NSFileManager *fileManager = [NSFileManager defaultManager];

if (![fileManager fileExistsAtPath:self.storeURL.path]) {
    NSDictionary *options =
    @{
      NSMigratePersistentStoresAutomaticallyOption:@YES
      ,NSInferMappingModelAutomaticallyOption:@YES
      };
    NSError *error = nil;
    [_coordinator lock];
    NSPersistentStore *srcPS = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                                                  configuration:nil
                                                                                            URL:oldStoreURL
                                                                                        options:oldOptions
                                                                                          error:&error];

    _store = [_coordinator migratePersistentStore:srcPS
                                                                             toURL:self.storeURL
                                                                           options:options
                                                                          withType:NSSQLiteStoreType
                                                                             error:&error];
    [_coordinator unlock];
    if (_store && !error) {
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Migration Success" message:[NSString stringWithFormat:@"Old store successfully migrated from %@",oldStoreURL.path] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];
        // Encrypt the password database
        NSError *encrError;
        NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
        if (![[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:self.storeURL.path error:&encrError]){
            UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Encryption Error" message:[NSString stringWithFormat:@"Unresolved error with password store encryption %@, %@", encrError, [encrError userInfo]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
            [alert show];
        }

    }else{
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Migration Error" message:error.localizedDescription delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];
    }

}
Upd.:我检查了新迁移的存储的大小,它是0。最奇怪的是
\u商店&&!错误
为真。我还尝试将
NSPersistentStoreRemoveUbiquitousMetadataOption:@YES
添加到迁移选项中,但它没有改变任何东西


Upd。2我认为在设备上,iCloud存储url在加载之前是零。我需要一些变通方法来等待迁移完成。

我不能100%确定我是否理解您试图对迁移执行的操作。通过迁移在空存储中播种数据是很常见的,但看起来您正在尝试将数据从iCloud迁移到本地存储中。是这样吗?你不应该这样做。iCloud应自动将来自其他设备的数据添加到您的存储中

这一行看起来也不对:

NSPersistentStoreUbiquitousContentURLKey : @"transactions_logs",
我想您应该使用一个指向iCloud容器中事务日志目录的URL。例如

NSURL *containerURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSURL *url = [containerURL URLByAppendingPathComponent:@"transactions_logs"];
在使用iCloud时,重要的是要认识到数据不是即时传输的。它可能需要一段时间才能到达,而您的应用程序实际上无法确定是否有数据。您可以通过元数据查询来监控元数据,但即使是这样,也常常是在其他设备上的数据已经生成之后的某个时间到达的

因此,仅仅在ubiquity容器中查找数据不会有多大帮助,因为可能有数据可用,也可能没有数据可用。你只是不知道,你必须在头脑中发展你的方法,这样它才能处理任何延迟


使iCloud sync与核心数据协同工作所需的迁移既混乱又不必要。您可能更有可能使用自动完成这些工作的框架(如核心数据集成)使事情正常工作。(披露:我是Ensembles的开发者。)

您是否等待迁移完成的时间足够长?打开核心数据记录,在Xcode中监视iCloud网络流量,看看发生了什么。不,我没有等。问题是,在设备上,迁移后我得到了空存储。在启用iCloud的模拟器上,一切都进行得很顺利。从TestFlight安装更新时,我无法使用日志记录。我尝试用您的行替换内容url,但没有帮助。由于iOS7,这一行是完全有效的(它是在WWDC2013、核心数据和iCloud讲座上介绍的)。我使用了Nimble框架,该框架是专门为使用iOS7 iCloud sync的优点而编写的,但是它在数据模型版本控制中工作错误,所以我决定将存储迁移到本地。在Xcode中测试时,迁移工作正常,但在iPad上测试时,它会创建0大小的文件,没有任何错误……您确定迁移的文件实际上是空的吗?你是如何测试的?您是查看存储文件大小,还是从存储中提取对象?我问这个问题的原因是,使用新的日志功能,如果缓冲数据没有达到某个级别,sqlite存储可以保持为空。是的,我使用AlertView进行了测试,当通过TestFlight安装时,它为零。就在一分钟前,我决定检查应用程序的早期版本,当我通过TestFlight发送时,它的商店也为零。所以这次迁移似乎没有什么问题,但是TestFlight更新开始删除文档和数据。前段时间我更改了配置文件,也许这就是原因。