gpt4 book ai didi

core-data - 硬核数据+iCloud场景

转载 作者:行者123 更新时间:2023-12-04 23:56:59 25 4
gpt4 key购买 nike

我有一个很难解决的问题。我有这种情况:

我的应用程序使用 CoreData 来存储对象,我想在设备之间实现 iCloud 同步...并且我的应用程序需要一个初始填充的数据库。

我第一次启动我的应用程序时,它会在云端填充我的数据库,并将某些数据库字段标记为"is",并将其标记为“已安装数据库”。这些字段也在云端同步。

现在,当另一台设备首次启动该应用程序时,我希望检索字段“databaseInstalled”以检查是否注入(inject)了一些数据,但这是错误的...

如果 databaseInstalled 为假,我们注入(inject)数据,如果 databaseInstalled 为真,我们等待 iCloud 同步。

问题是我异步检索了 persistentStoreCoordinator,因为我不想阻止正在等待从 iCloud 下载数据的应用程序...

那么,如果我需要填充数据库,或者它已经在另一台设备上填充,那么我如何才能先验地知道,而我只是从 iCloud 下载填充的那个呢?

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

__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;

// Set up iCloud in another thread:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// ** Note: if you adapt this code for your own use, you MUST change this variable:
NSString *iCloudEnabledAppID = @"this is a secret!";

// ** Note: if you adapt this code for your own use, you should change this variable:
NSString *dataFileName = @"you do not have to know.sqlite";

// ** Note: For basic usage you shouldn't need to change anything else

NSString *iCloudDataDirectoryName = @"Data.nosync";
NSString *iCloudLogsDirectoryName = @"Logs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];

if (iCloud) {

NSLog(@"iCloud is working");

NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];

NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID);
NSLog(@"dataFileName = %@", dataFileName);
NSLog(@"iCloudDataDirectoryName = %@", iCloudDataDirectoryName);
NSLog(@"iCloudLogsDirectoryName = %@", iCloudLogsDirectoryName);
NSLog(@"iCloud = %@", iCloud);
NSLog(@"iCloudLogsPath = %@", iCloudLogsPath);

// da rimuovere

//[fileManager removeItemAtURL:iCloudLogsPath error:nil];
#warning to remove

if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if(fileSystemError != nil) {
NSLog(@"Error creating database directory %@", fileSystemError);
}
}

NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];

//[fileManager removeItemAtPath:iCloudData error:nil];
#warning to remove

NSLog(@"iCloudData = %@", iCloudData);

NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];

[psc lock];

[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];

[psc unlock];
}
else {
NSLog(@"iCloud is NOT working - using a local store");
NSLog(@"Local store: %@", localStore.path);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];

[psc lock];

[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
[psc unlock];

}

dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"iCloud routine completed.");

Setup *install = [[Setup alloc] init];

if([install shouldMigrate]) {
HUD = [[MBProgressHUD alloc] initWithView:self.window.rootViewController.view];
HUD.delegate = self;
HUD.labelText = NSLocalizedString(@"Sincronizzazione del database", nil);
[self.window.rootViewController.view addSubview:HUD];
[HUD showWhileExecuting:@selector(installDatabase) onTarget:install withObject:nil animated:YES];
}
else {
[[NSNotificationCenter defaultCenter] postNotificationName:@"setupCompleted" object:self];
}

//[[NSNotificationCenter defaultCenter] postNotificationName:@"icloudCompleted" object:self userInfo:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"setupCompleted" object:self];
});
});

return __persistentStoreCoordinator;
}

最佳答案

在完成与 iCloud 的同步之前,您无法知道 iCloud 中是否会有数据可用。这意味着您有两个选择:

  • 让用户等到同步完成。

  • 使用您的默认数据库启动并尽可能合并来自 iCloud 的更改。

使用 iCloud,您需要一些 strategy for resolving conflicts本地数据和云数据之间的差异,因为您必须处理用户可能同时更改多个设备上的数据这一事实。准备就绪后,很明显上面的第二个选项是更好的选项:用户可以立即开始使用您的应用程序,并且云中的数据可用时会合并。

关于core-data - 硬核数据+iCloud场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10535440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com