Ios 核心数据应用程序中的UITableView不会更新第二个设备;除非重新启动应用程序,否则将显示iCloud的主视图,并同步iCloud

Ios 核心数据应用程序中的UITableView不会更新第二个设备;除非重新启动应用程序,否则将显示iCloud的主视图,并同步iCloud,ios,iphone,core-data,notifications,icloud,Ios,Iphone,Core Data,Notifications,Icloud,亲爱的朋友们 我已经用核心数据和iCloud构建了一个应用程序。它是UITabBarController中的一个简单的4选项卡,每个选项卡都是UITableViewController。第一个选项卡名为Timeline,后面是Person、Event和Date 对于设备1,当控制台中显示“使用本地存储:0”时,我添加了一些条目。当我构建第二台设备(在同一个iCloud帐户上)(iPad)时,它首先使用本地存储:1(预期),然后是0(预期)。但是,时间线选项卡(主视图)实际上并不显示新条目,但“人

亲爱的朋友们

我已经用核心数据和iCloud构建了一个应用程序。它是
UITabBarController
中的一个简单的4选项卡,每个选项卡都是
UITableViewController
。第一个选项卡名为Timeline,后面是Person、Event和Date

对于设备1,当控制台中显示“
使用本地存储:0
”时,我添加了一些条目。当我构建第二台设备(在同一个iCloud帐户上)(iPad)时,它首先使用本地存储:1(预期),然后是
0
(预期)。但是,时间线选项卡(主视图)实际上并不显示新条目,但“人员、事件和日期”选项卡会适当地显示它。如果我重新启动应用程序,它就会出现在时间线上

我正在为每个
UITableViewController
使用
nsfetchedresultscoontroller
,并且参考了一个优秀的教程(),在我的时间轴中,我已经输入了以下代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // add iCloud observers
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(storesWillChange) name:NSPersistentStoreCoordinatorStoresWillChangeNotification object:self.managedObjectContext.persistentStoreCoordinator];

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

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(mergeContent:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:self.managedObjectContext.persistentStoreCoordinator];

}

#pragma mark - iCloud Methods

- (void)storesWillChange {

    NSLog(@"\n\nStores WILL change notification received\n\n");

    // disbale UI
    [[UIApplication sharedApplication]beginIgnoringInteractionEvents];

    // save and reset our context
    if (self.managedObjectContext.hasChanges) {
        [self.managedObjectContext save:nil];
    } else {
        [self.managedObjectContext reset];
    }
}

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

    NSLog(@"\n\nStores DID change notification received\n\n");

    // enable UI
    [[UIApplication sharedApplication]endIgnoringInteractionEvents];

    // update UI
    [self.timelineTableView reloadData];
}

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

    NSLog(@"!Merge Content here!");
    [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
我注意到一些奇怪的事情

为清晰起见进行编辑 1) iPad(第二台设备)在初始导入期间或任何后续同步期间都不会运行StoresWirlChange或StoresIDChange

2) iPad的“个人/事件”选项卡已填充,但时间线未填充。只有当我重新运行应用程序或从设备1添加新条目时,iPad的时间线才会得到更新

问题

当iPad第一次连接到iCloud时,我需要做什么才能让它在时间线选项卡中显示数据?这不是耐心的问题,因为我等了43分钟,没有任何变化

当来自iCloud的数据非常重要时,在第二台设备上运行的方法是什么?这是我的钥匙。如果是storesDidChange,我应该把它放在哪里?我已尝试将通知侦听器放置在
viewDidLoad
Timeline视图控制器中,在App委托中的
applicationdifinishlaunchingwithoptions
,以及
NSManagedObjectContext
中,但在任何情况下,它都不会运行

这是一款仅限iOS 7的应用程序

编辑:进一步更新

我现在已经到了一个地步,iPad(第二台设备)仍然没有显示iCloud数据,但如果我在第一台设备上添加一个新条目,它就会合并内容并跨多个设备进行同步

今天早上我已经阅读了很多次苹果指南:,我发现在添加持久存储之前注册storesDidChange是很重要的。这是有道理的,我这样做了,我从storesDidChange方法中获取NSLog

但是,在一次性Ubiquity Store容器完成设置后,它应该再次运行storesWillChange通知以及StoresIDChange

在我的情况下,两者都没有运行

关于这个页面,这似乎正是我在这里面临的问题:,用户在UITableView中重新获取。我正在这样做,但数据还是不会出现在iPad上,这是它第一次运行并与iCloud商店同步

但是,由于它是一个
UITabBarController
,因此其他选项卡正在相应地更新。只是这个标签,它已经在从回退迁移到iCloud存储之前和之后显示

编辑:在此处添加
persistentStoreCoordinator
方法

如果我的persistentStoreCoordinator出现问题,我将在此处添加该代码:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    NSLog(@"Persistent Store");
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Envylope.sqlite"];

    NSError *error = nil;
    // get a reference to your iCloud URL
    NSURL *cloudURL = [self grabCloudPath:@"iCloud"];

    // setup options depending on migration
    NSDictionary *options = nil;
    if ([[NSUserDefaults standardUserDefaults]boolForKey:@"OnLatestVersion"]) {
        options = @{                                       NSMigratePersistentStoresAutomaticallyOption : @YES,
                                                           NSInferMappingModelAutomaticallyOption : @YES,
                                                           NSPersistentStoreUbiquitousContentURLKey: cloudURL, NSPersistentStoreUbiquitousContentNameKey: @"EnvyCloud"};
        NSLog(@"Using iCloud from migration");
    }
    else
    {
        NSLog(@"Using the other store without the iCloud Migration");
        options = @{                                       NSMigratePersistentStoresAutomaticallyOption : @YES,
                                                           NSInferMappingModelAutomaticallyOption : @YES};
    }

    NSLog(@"Just before adding the persistent store");
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    NSLog(@"Just after adding the store");

    return _persistentStoreCoordinator;
}
我之所以使用if语句和userDefaults,是因为我想检查用户的应用程序是否需要迁移到新版本,并在应用程序再次运行时维护该版本。我的意思是,如果我的设备上有App Store版本,其中包含数据并更新到此iCloud版本,它会将数据迁移到iCloud Store。如果我再次运行该应用程序,它不会再次迁移,它只是使用iCloud应用商店。这可以实现同步,虽然我不认为这是问题所在(因为另一台设备确实在其他选项卡上拾取了云信息),但它已经完成了

任何通往正确方向的道路都会非常有用

Amit

我已经做了一些挖掘,我相信你的应用程序的iCloud部分运行良好。问题似乎出在“获取结果”控制器上,在某些设备上,该控制器需要重新获取。最简单的方法是当您收到StoresIDChange通知时。请尝试以下操作,而不是重新加载表视图:

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

    NSLog(@"\n\nStores DID change notification received\n\n");

    // enable UI
    [[UIApplication sharedApplication]endIgnoringInteractionEvents];

    // update UI
    _fetchedResultsController = nil;
    [self fetchedResultsController];
}

首先将变量设为零,然后再次调用自定义初始化器(根据应用程序的需要进行修改)。现在,表视图应该可以很好地更新,并显示iCloud的结果

关于丢失的通知:

你没有收到willChange和didChange的原因很可能是因为你在部署应用程序时没有先从设备上删除它。这不是一个准确的场景:如果实际存储文件没有更改,iOS将不会发布这些通知。通过在重新部署之前删除应用程序,这些通知将正确发布,并有望更新您的获取结果控制器


希望这有帮助

只是想澄清一下:其他三个选项卡是否也从同一个iCloud核心数据堆栈更新?它们是否按预期更新了?感谢Jay,绝对感谢——其他三个选项卡来自同一个iCloud核心数据堆栈,它们只是第一次表示相同的数据,但只是使用特定的谓词来显示略有不同的结果。当我在第二台设备中运行此连接过程时,在控制台中显示“Using Local Storage:0”后,第二台设备会立即使用第一台设备的正确数据更新其第二、第三和第四个选项卡。这只是第一次助教