59

所以,它终于发生了。对于任何独立的 iPhone 开发者来说,最糟糕的情况发生了。升级我的应用程序后,有几个用户报告完全丢失数据。iCloud 核心数据同步不工作。我的用户部分使用这个应用程序来经营他们的业务。这是一个真正的灾难性失败

我唯一更改的与 iCloud 相关的事情是将键值存储添加到 iCloud。核心数据代码保持完全相同,相同的模型版本(无迁移)等。

在我的测试中,一切都很顺利!但令我沮丧的是,用户报告说,当他们打开更新的应用程序时,他们的数据已经不存在了。

这可能是什么原因?

  • 持久存储 URL (一个普遍存在的URL)不应更改。
  • 合并冲突也不太可能发生,因为这个问题应该在更新之前出现。
  • 也许对新的无处不在的键值存储有一些干扰?
    (我几乎排除了这一点。)

请在下面找到我的托管对象模型和持久存储的代码。如果您需要其他任何东西来评估问题,请告诉我。

- (NSManagedObjectContext *)managedObjectContext {

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

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [managedObjectContext_ performBlockAndWait:^{
            [managedObjectContext_ setPersistentStoreCoordinator:coordinator];
            if (useICloud) {
                [managedObjectContext_ setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
                [[NSNotificationCenter defaultCenter] addObserver:self
           selector:@selector(mergeiCloud:)
           name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
           object:coordinator];
            }
        }];
    }
    return managedObjectContext_;
}

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

    NSMutableDictionary *options = [NSMutableDictionary dictionary];
    NSURL *storeURL = [[self applicationDocumentsDirectory] 
            URLByAppendingPathComponent:@"SalesCalls.sqlite"];

    [options setObject:[NSNumber numberWithBool:YES] 
                  forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:YES] 
                  forKey:NSInferMappingModelAutomaticallyOption];

    if (useICloud) {  // this is an internal flag set to YES
        NSURL *iCloudURL = [[NSFileManager defaultManager] 
                               URLForUbiquityContainerIdentifier:nil];

        if (nil!=iCloudURL) {
            NSString *cloudData = [[iCloudURL path] 
                       stringByAppendingPathComponent:@"data"];
            iCloudURL = [NSURL fileURLWithPath:cloudData];      

            [options setObject:@"at.topofmind.salesplus.store" 
                        forKey:NSPersistentStoreUbiquitousContentNameKey];
            [options setObject:iCloudURL 
                        forKey:NSPersistentStoreUbiquitousContentURLKey];

            NSURL *nosyncDir = [iCloudURL 
                        URLByAppendingPathComponent:@"data.nosync"];
            [[NSFileManager defaultManager] createDirectoryAtURL:nosyncDir 
                        withIntermediateDirectories:YES 
                        attributes:nil error:nil];

            storeURL = [nosyncDir 
                        URLByAppendingPathComponent:@"SalesCalls.sqlite"];
        }
    }

    NSError *error = nil;
    persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] 
             initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator_ 
                  addPersistentStoreWithType:NSSQLiteStoreType
                  configuration:nil URL:storeURL options:options error:&error]) 
   {
        NSLog(@"Cannot create persistent store coordinator, %@, %@", 
                        error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator_;
}

欢迎评论、意见、猜测等(当然还有解决方案!)。

更新:

我的一位客户丢失了所有数据,并且在重新安装和重置所有内容(重新启动设备等)后,他无法再与 iCloud 同步。该符号根本不会显示在“设置”中。

4

1 回答 1

1

我遇到了类似的情况,用途很少(根据您的描述,我认为您的音量比我大得多,这可能是几种情况的原因)

就我而言,Apple 似乎在没有提前通知的情况下删除了 icloud 中的 20gb 可用空间。我注意到,作为电力数据使用用户的 2 个用户丢失了我的应用程序中的新数据(用于处理历史股票定价),而其他用户我们只需下载相同的数据大小即可。

我跟进了这两个,帮助他们清理东西以在 icloud 中腾出更多空间,瞧,再次下载数据后它工作正常。

于 2013-02-02T05:21:08.463 回答