gpt4 book ai didi

ios - 将 iCloud 数据迁移到本地存储并停止 iCloud 仍然响应

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:04:26 28 4
gpt4 key购买 nike

我非常接近在我的应用程序中完成 iCloud 和核心数据的实现。这是一款仅限 iOS 7 的应用程序。

我在应用程序中为用户提供一个选项,以 UISwitch 的形式说出打开或关闭 iCloud。该应用程序启动并询问用户是否要使用 iCloud,然后可以在应用程序内更改。

我将数据从本地存储(如果存在)迁移到 iCloud。我遇到的一个方面是将数据从 iCloud 商店迁移到本地商店。

场景:- 用户 A 有一部装有我的应用程序和一些数据的 iPhone- 用户 A 将应用程序下载到 iPad 上,选择使用 iCloud,但后来决定不希望在 iPad 上进行同步。所以他们关闭了应用程序内的 iPad iCloud 同步。

在这一点上,我的理解是用户希望数据仍然存在,但在幕后,它现在是“本地”而不是基于“iCloud”的数据,这意味着来自其他方的条目设备不会同步到此设备,反之亦然

所以我正在努力实现这一目标。

问题

我可以让数据从 iCloud 迁移到本地商店,但问题是因为 iCloud 在设备上仍然启用,下次运行应用程序时,我可以看到 iCloud 在应用程序中被禁用但控制台仍然显示 Using Local Storage 1 然后 0 并且来自 iPhone 的任何数据都同步到 iPad,即使 Use iCloud UISwitch 非常明显地关闭。

下面是执行迁移的主要代码:

- (void)migrateiCloudStoreToLocalStore {

NSLog(@"Migrate iCloudToLocalStore");
NSPersistentStore *store = self.persistentStoreCoordinator.persistentStores.lastObject;

//NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Envylope.sqlite"];
NSURL *storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
NSLog(@"Current Store URL (before iCloud to Local migration): %@", [storeURL description]);

NSDictionary *localStoreOptions = nil;
localStoreOptions = @{ NSPersistentStoreRemoveUbiquitousMetadataOption : @YES,
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};

NSPersistentStore *newStore = [self.persistentStoreCoordinator migratePersistentStore:store
toURL:storeURL
options:localStoreOptions
withType:NSSQLiteStoreType error:nil];

[self reloadStore:newStore];
}

- (void)reloadStore:(NSPersistentStore *)store {
NSLog(@"Reload Store");
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Envylope.sqlite"];
NSDictionary *localStoreOptions = nil;
localStoreOptions = @{ NSPersistentStoreRemoveUbiquitousMetadataOption : @YES,
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};

if (store) {
[self.persistentStoreCoordinator removePersistentStore:store error:nil];
}

[self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:localStoreOptions
error:nil];
storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
NSLog(@"Current Store URL (after iCloud to Local migration): %@", [storeURL description]);

NSLog(@"Done reloading");

[[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"MigratedFromiCloudToLocal"];
[[NSUserDefaults standardUserDefaults]synchronize];

}

当然,那里有一些冗余代码,但是在 iCloud 到本地迁移之前的 NSLog 显示:

 Current Store URL (before iCloud to Local migration): file:///var/mobile/Applications/62CAFCEE-450E-410D-9D56-4918DD70EC07/Documents/CoreDataUbiquitySupport/mobile~98457667-A467-4095-BB7F-EF36EB2B0FE1/EnvyCloud/CD08912E-C135-4056-9557-6B47C84ECEF9/store/Envylope.sqlite

迁移数据后的NSLog显示:

Current Store URL (after iCloud to Local migration): file:///var/mobile/Applications/62CAFCEE-450E-410D-9D56-4918DD70EC07/Documents/Envylope.sqlite

这清楚地表明数据已迁移到本地存储。但是,此时在控制台中,我不确定会发生什么,但理想情况下,此过程应该与设备上根本没有启用 iCloud 具有相同的效果(如果我删除我的应用程序,请删除我的 iCloud 帐户在设备上运行应用程序,我得到了预期的结果——在没有任何 iCloud 选项的情况下运行应用程序)。这并没有发生,因为它继续插入 iCloud 更新。无需再次运行该应用程序,其他设备中添加的数据会同步到此处。再次运行应用程序,正在使用本地存储 1 和 0 出现在控制台中。

因此,数据可能已迁移到本地商店,但在应用程序内禁用 iCloud 似乎没有任何效果。

我真的很感激对此的一些想法。

更新:已找到作为以下两个答案的组合的解决方案。对于跟随此问题的任何人以查看下一个场景,请引用此问题:Migrating an iCloud Store to a Local Store and making sure the data is there through each app launch

最佳答案

这是一个两步过程:就像@wottle 建议的那样,从您的应用程序中删除所有三个观察者。在将 iCloud 数据迁移到新的本地存储文件后执行此操作:

- (void)removeCloudObservers {

[[NSNotificationCenter defaultCenter]removeObserver:self name:NSPersistentStoreCoordinatorStoresWillChangeNotification object:self.managedObjectContext.persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter]removeObserver:self name:NSPersistentStoreCoordinatorStoresDidChangeNotification object:self.managedObjectContext.persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter]removeObserver:self name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:self.managedObjectContext.persistentStoreCoordinator];
}

接下来,如果您绝对确定要从 iCloud 中删除整个无处不在的容器(就像我们之前手动所做的那样),您可以在 NSPersistentStoreCoordinator 类上调用一个单例方法 (removeUbiquitousContentAndPersistentStoreAtURL)。获取有问题的 iCloud 存储文件(我将其称为 yourStore),然后使用如下内容:

- (void)removeCloudContainer:(NSPersistentStore *)yourStore {

NSError *error = nil;
if (![NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:yourStore.URL options:yourStore.options error:&error]) {
NSLog(@"That didn't work so well, and here's why: %@", error.localizedFailureReason);
}
}

这将删除整个容器,其他设备将无法再访问 iCloud 数据。一旦 iCloud 商店从协调器中删除并且应用程序已经在本地商店上正常运行,请执行此操作。

从 UI 的角度来看,在所有设备上的所有数据都已迁移到本地存储之后让用户做出此选择可能是一个好主意,而不是将其集成到“关闭 iCloud”例程中 - 仅因为它与仍然期望 iCloud 商店在那里的同行打交道可能会很棘手。

关于ios - 将 iCloud 数据迁移到本地存储并停止 iCloud 仍然响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25186787/

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