【问题标题】:What causes iOS iCloud error: Error Domain=BRCloudDocsErrorDomain Code=12 "The operation couldn’t be completed." Retrying after delay: 60什么导致 iOS iCloud 错误:Error Domain=BRCloudDocsErrorDomain Code=12 "The operation could not be completed."延迟后重试:60
【发布时间】:2015-07-23 13:25:34
【问题描述】:

iPhone/iOS 应用使用 CoreData + SQLite (NSSQLiteStoreType) + iCloud iOS。当应用程序在第一次安装时启动(或通过 xcode 删除并重新安装后),并且 iCloud 中有先前安装或同一帐户中其他设备的先前应用程序数据,会发生以下错误,然后重试延迟 60 秒,然后成功迁移到 iCloud。结果是应用程序的用户认为他们的数据在应用程序升级时丢失了。但是,在 60 秒延迟后,数据会恢复。错误和一些代码如下。

是什么导致了这个错误?我在哪里可以了解有关此错误的更多信息?

[4972:2014294] CoreData:iCloud:错误:初始同步通知返回错误(错误域=BRCloudDocsErrorDomain Code=12“操作无法完成。(BRCloudDocsErrorDomain 错误 12.)”)

[4972:2014294] -PFUbiquitySetupAssistant finishSetupWithRetry:: CoreData: Ubiquity: : Retrying after delay: 60 Error Domain=BRCloudDocsErrorDomain Code=12 “操作无法完成。(BRCloudDocsErrorDomain 错误 12。)”

这是一个代码 sn-p 和更详细的日志以提供更多上下文。

来自应用委托:

        - (void)applicationDidFinishLaunching:(UIApplication *)application { 

            ... standard iCloud and app setup ...

            NSManagedObjectContext *context = [self managedObjectContext];

            ...

            ... query the db ...
        }

        /**
         Returns the managed object context for the application.
         If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
         */
        - (NSManagedObjectContext *) managedObjectContext {

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

            NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
            if (coordinator != nil) {
                managedObjectContext = [[NSManagedObjectContext alloc] init];
                [managedObjectContext setPersistentStoreCoordinator: coordinator];
            }
            managedObjectContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;  
            return managedObjectContext;
        }

        ...

        /**
         Returns the managed object model for the application.
         If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
         */
        - (NSManagedObjectModel *)managedObjectModel {

            if (managedObjectModel != nil) {
                return managedObjectModel;
            }
            managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
            return managedObjectModel;
        }

        ...

        /**
         Returns the persistent store coordinator for the application.
         If the coordinator doesn't already exist, it is created and the application's store added to it.
         */
        - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

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




            NSURL *storeUrl = [NSURL fileURLWithPath: [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent: @"myapp.sqlite"]];

            NSLog(@"App Store URL : %@", storeUrl);

            NSError *error = nil;
            persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];


            NSDictionary *storeOptions;
            storeOptions = @{
                             NSMigratePersistentStoresAutomaticallyOption : @YES,
                             NSInferMappingModelAutomaticallyOption : @YES,
                             NSPersistentStoreUbiquitousContentNameKey: @"AppCloudStore"
                             };
            #ifdef FREE
            storeOptions = @{
                             NSMigratePersistentStoresAutomaticallyOption : @YES,
                             NSInferMappingModelAutomaticallyOption : @YES,
                             NSPersistentStoreUbiquitousContentNameKey: @"FreeAppCloudStore"
                             };
            #endif

            // Register for Notifications
            NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

            [notificationCenter addObserver:self
                                   selector:@selector(storesDidChange:)
                                       name:NSPersistentStoreCoordinatorStoresDidChangeNotification
                                     object:self.persistentStoreCoordinator];

            [notificationCenter addObserver:self
                                   selector:@selector(persistentStoreDidImportUbiquitousContentChanges:)
                                       name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
                                     object:self.persistentStoreCoordinator];

            [notificationCenter addObserverForName:NSPersistentStoreCoordinatorStoresWillChangeNotification
             object:self.persistentStoreCoordinator
             queue:[NSOperationQueue mainQueue]
             usingBlock:^(NSNotification *note) {
                 NSLog(@"Stores Will Change...");

                     if ([self.managedObjectContext hasChanges]) {
                         NSError *saveError;
                         if (![self.managedObjectContext save:&saveError]) {
                             NSLog(@"Save error: %@", saveError);
                         }
                     } else {
                         // drop any managed object references
                         [self.managedObjectContext reset];
                     }

             }];


            NSPersistentStore *store = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl  options:storeOptions error:&error];

            if (store == nil || error != nil) {
                NSLog(@"Error: %@, %@", error, [error userInfo]);
                abort();
            }


            NSURL *finaliCloudURL = [store URL];
            NSLog(@"Created persistent store okay.  Final iCloud URL is: %@", finaliCloudURL);

            return persistentStoreCoordinator;
        }

    ...

    - (void)persistentStoreDidImportUbiquitousContentChanges:(NSNotification *)notification {

        NSLog(@"persistentStoreDidImportUbiquitousContentChanges: Called.  Content has changed via Core Data iCloud: *******************************************");

            // Received and merge updates from iCloud
            [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
            [self notifyAndRefreshAllDataDueToCloudEvent];
    }

    ...

    - (void)storesDidChange:(NSNotification *)notification {

        // Tell me: why did my stores changes?
        NSNumber *transitionType = [notification.userInfo objectForKey:NSPersistentStoreUbiquitousTransitionTypeKey];
        int theCause = [transitionType intValue];

        NSLog(@"storesDidChange: NSPersistentStoreCoordinatorStoresDidChange Notification = %@", notification);

        switch (theCause) {
            case NSPersistentStoreUbiquitousTransitionTypeAccountAdded: {
                NSLog(@"storesDidChange: Account Added");
                // account was added
            }
                break;
            case NSPersistentStoreUbiquitousTransitionTypeAccountRemoved: {
                NSLog(@"storesDidChange: Account Removed");
                // account was removed
            }
                break;
            case NSPersistentStoreUbiquitousTransitionTypeContentRemoved: {
                NSLog(@"storesDidChange: Content Removed");
                // content was removed
            }
                break;
            case NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted: {
                NSLog(@"storesDidChange: Initial Import:");
                // initial import
            }
                break;

            default:
                break;

        }

    ... 

        [[NSNotificationCenter defaultCenter]
         postNotificationName:@"*****DidChangeByPersistentStoreChangesNotification"
         object:self];

        [[NSNotificationCenter defaultCenter]
         postNotificationName:@"*****DidChangeByPersistentStoreChangesNotification"
         object:self];

        [[NSNotificationCenter defaultCenter]
         postNotificationName:@"*****DidChangeByPersistentStoreChangesNotification"
         object:self];

    }

更详细的日志:

2015-05-12 10:22:23.367 [4972:2014228] storesDidChange: NSPersistentStoreCoordinatorStoresDidChange Notification = NSConcreteNotification 0x17005f470 {name = NSPersistentStoreCoordinatorStoresDidChangeNotification; object = <NSPersistentStoreCoordinator: 0x170072100>; userInfo = {
    added =     (
        "<NSSQLCore: 0x12dd100b0> (URL: file:///var/mobile/Containers/Data/Application/****/Documents/CoreDataUbiquitySupport/mobile~****-7B78C4F2FDB2/FreeAppCloudStore/2***/store/app.sqlite)"
    );
}}
2015-05-12 10:22:23.409 [4972:2014228] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](808): CoreData: Ubiquity:  mobile~****:FreeAppCloudStore
Using local storage: 1
2015-05-12 10:22:23.410 [4972:2014228] Created persistent store okay.  Final iCloud URL is: file:///var/mobile/Containers/Data/Application/****/store/app.sqlite
2015-05-12 10:22:23.477 [4972:2014228] AppTableViewController:viewWillAppear: enter
2015-05-12 10:22:23.478 [4972:2014228] getSharedAdBannerView: enter
2015-05-12 10:22:23.518 [4972:2014228] queryDidUpdate: MSMetadataQuery Notification: - NSMetadataQueryDidFinishGatheringNotification
2015-05-12 10:22:23.519 [4972:2014228] queryDidUpdate: NSMetadataQuery returned 25 results
2015-05-12 10:22:23.524 [4972:2014228] setProcessTimer: 15.000000
2015-05-12 10:22:23.531 [4972:2014228] TableViewController:viewDidAppear: enter
2015-05-12 10:22:23.531 [4972:2014228] TableViewController:loadData (or reload): enter
2015-05-12 10:22:23.582 [4972:2014294] CoreData: iCloud: Error: initial sync notification returned an error (Error Domain=BRCloudDocsErrorDomain Code=12 "The operation couldn't be completed. (BRCloudDocsErrorDomain error 12.)")
2015-05-12 10:22:23.594 [4972:2014294] -[PFUbiquitySetupAssistant finishSetupWithRetry:](826): CoreData: Ubiquity:  <PFUbiquitySetupAssistant: 0x12de18940>: Retrying after delay: 60
Error Domain=BRCloudDocsErrorDomain Code=12 "The operation couldn't be completed. (BRCloudDocsErrorDomain error 12.)"
2015-05-12 10:22:23.854 [4972:2014228] didFailToReceiveAdWithError
2015-05-12 10:22:55.150 [4972:2014228] bannerViewDidLoadAd
2015-05-12 10:23:24.178 [4972:2014228] queryDidUpdate: MSMetadataQuery Notification: - NSMetadataQueryDidUpdateNotification
2015-05-12 10:23:24.178 [4972:2014228] queryDidUpdate: NSMetadataQuery returned 25 results
2015-05-12 10:23:25.039 [4972:2014228] Stores Will Change...
2015-05-12 10:23:25.101 [4972:2014228] storesDidChange: NSPersistentStoreCoordinatorStoresDidChange Notification = NSConcreteNotification 0x170254940 {name = NSPersistentStoreCoordinatorStoresDidChangeNotification; object = <NSPersistentStoreCoordinator: 0x170072100>; userInfo = {
    NSPersistentStoreUbiquitousTransitionTypeKey = 4;
    added =     (
        "<NSSQLCore: 0x12dd100b0> (URL: file:///var/mobile/Containers/Data/Application/****/FreeAppCloudStore/20EF5D1C-4748-4AB2-BCE1-91B228437D77/store/app.sqlite)"
    );
    removed =     (
        "<NSSQLCore: 0x12dd100b0> (URL: file:///var/mobile/Containers/Data/Application/*****/store/app.sqlite)"
    );
}}
2015-05-12 10:23:25.101 [4972:2014646] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](808): CoreData: Ubiquity:  mobile~*****FreeAppCloudStore
Using local storage: 0

【问题讨论】:

  • 看起来它正在按预期工作,如下所示: - 设备打开 iCloud 存储 - Core Data 创建一个临时本地存储并使其可用于应用程序(使用本地存储:1 条消息) - Core Data 然后创建一个 iCloud 存储(本地副本)并下载任何基本存储数据和日志文件并导入它们 - 然后 Core Data 将临时存储与本地 iCloud 存储合并并切换应用程序以使用它(使用本地存储:0消息)并且 Core Data 错误可能与等待 iCloud 基础存储和日志下载有关。通常只提供信息。
  • 具有 iCloud/NSSQLiteStoreType 的应用程序运行完美,除了描述的 60 秒超时。我认为 iCloud 不需要出错然后在 60 秒内重试,“延迟后重试:60”我有应用用户通过电子邮件评论他们丢失了应用数据,我怀疑这仅仅是由于超时和他们不等待它。我希望有人可能已经看到了这些错误。感谢您的评论。
  • Apple 不提供任何服务水平协议,说明 iCloud 同步将在任何定义的时间范围内发生。在我的测试中,等待期可能比 60 秒长得多。执行元数据查询以查找尚未下载的 iCloud 文件。您的用户显然需要访问 iCloud 才能执行此操作。如果是这样,您可以监控下载状态,一旦下载,通常会很快。查看此站点以获取一些示例应用程序。 ossh.com.au/design-and-technology/softwre-development/sample-library-style-ios-core-data-app-with-icloud-integration/
  • 嗨@BillBunting - 你有没有想过解决这个问题?在过去的两个月中,我也遇到了完全相同的错误和问题。当我制作了我的应用程序的新版本并将其发布到 App Store(没有 iCloud/Core Data 更改)时,当我升级到那个版本时,我的数据都从应用程序中消失了。我没有等待数据进来,我只是惊慌失措并从商店中拉出应用程序,但我不知道修复是什么。关键是,当应用程序第一次使用商店中的现有数据启动时,我在 Xcode 中遇到了完全相同的错误,等等。
  • @BillBunting 所以我将我的应用程序保存在不同的国家/地区的商店中,以便继续测试它。我刚刚再次测试它,即使在等待之后,数据也不会出现.我启用了 iCloud Drive。如果您仍然遇到此问题,或者如果问题得到解决,我很乐意与您合作解决问题

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


【解决方案1】:

我希望我的回答可以为遇到这个错误的人节省很多时间。

当应用程序的删除和安装之间的时间小于某个时间间隔时,会发生此错误。不知道是不是和我一样,我的是15秒。

愚蠢的错误,浪费了几个小时。

【讨论】:

  • 这真的很有趣。感谢您在这里的回答,虽然这不是我的问题,但我遇到了同样的问题。您对 iCloud/Core Data 丢失的数据有什么想法吗?虽然这可能是一个单独的问题,但这个问题和我有同样的问题。更新到 App Store 版本时,所有数据都不再在应用中
  • 同时忽略这个错误信息会有一些后果。测试用户在“错误期”之间添加新记录的情况。有时这些记录会在 iCloud 再次开始同步后消失。
  • 这解释了很多。谢谢,你的回答真的很有帮助。
  • 我已经被这个问题困扰了好几个小时了!我现在觉得自己好傻。大声笑.. 感谢您的回答!
  • 感谢分享。也被卡住了。无论如何,这不会在生产中发生。用户需要删除并重新下载应用的时间应该在15s以上。
猜你喜欢
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多