Ios 核心数据应用程序中的UITableView不会更新第二个设备;除非重新启动应用程序,否则将显示iCloud的主视图,并同步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(预期)。但是,时间线选项卡(主视图)实际上并不显示新条目,但“人
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”后,第二台设备会立即使用第一台设备的正确数据更新其第二、第三和第四个选项卡。这只是第一次助教