У меня есть приложение для OSX и iOS, и оба используют iCloud для обмена основными данными между ними. Когда я вношу изменения в iPhone, я вижу их в приложении OSX, а NSPersistentStoreDidImportUbiquitousContentChangesNotification
вызывается в обоих приложениях, поэтому iOS → Mac работает хорошо. Но когда я делаю некоторые изменения в приложении Mac, я не вижу их в iPhone. IPhone никогда не называет NSPersistentStoreDidImportUbiquitousContentChangesNotification
. Единственный способ, которым я могу получить изменения в Mac, - внести некоторые изменения в iPhone. Затем я вижу все изменения.
Интеграция iCloud в обоих проектах одинакова. Основная база данных данных данных одинаков. Права также одинаковы.
Весь мой код основан на этой библиотеке: http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/
Почему iPhone не получает изменения Mac, пока я не сделаю некоторые изменения на iPhone? Любые идеи?
Другой вопрос
В моем приложении, когда пользователь разрешает iCloud, я проверяю, является ли файл iCloud уже. Если файл существует, пользователь может выбрать восстановление данных ядра из файла iCloud или запуск новой копии из локального хранилища. Чтобы начать новую копию, я использую этот код:
- (void)startNewCopy
{
[self removeICloudStore];
[self moveStoreToIcloud];
}
- (void)removeICloudStore
{
BOOL result;
NSError *error;
// Now delete the iCloud content and file
result = [NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:[self icloudStoreURL]
options:[self icloudStoreOptions]
error:&error];
if (!result)
{
NSLog(@"Error removing store");
}
else
{
NSLog(@"Core Data store removed.");
// Now delete the local file
[self deleteLocalCopyOfiCloudStore];
}
}
- (void)deleteLocalCopyOfiCloudStore {
// We need to get the URL to the store
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtURL:[self localUbiquitySupportURL] error:&error];
}
- (void)moveStoreToIcloud
{
// Open the store
NSPersistentStore *sourceStore = [[_persistentStoreCoordinator persistentStores] firstObject];
if (!sourceStore)
{
NSLog(@" failed to add old store");
}
else
{
NSLog(@" Successfully added store to migrate");
NSError *error;
id migrationSuccess = [_persistentStoreCoordinator migratePersistentStore:sourceStore toURL:[self icloudStoreURL] options:[self icloudStoreOptions] withType:NSSQLiteStoreType error:&error];
if (migrationSuccess)
{
NSLog(@"Store migrated to iCloud");
_persistentStoreCoordinator = nil;
_managedObjectContext = nil;
// Now delete the local file
[self deleteLocalStore];
}
else
{
NSLog(@"Failed to migrate store: %@, %@", error, error.userInfo);
}
}
}
- (void)deleteLocalStore
{
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtURL:[self localStoreURL] error:&error];
}
Выполнение этого с одного устройства, похоже, работает хорошо, но когда я пытаюсь использовать это с несколькими устройствами, я получаю некоторые ошибки.
Пример:
У меня есть два устройства. Первый не подключен к iCloud, а второй подключен к iCloud.
В первом устройстве, когда я включаю iCloud, я выбираю startNewCopy
, а затем во втором устройстве получаю эту ошибку:
CoreData: Ubiquity: библиотекарь вернула серьезную ошибку для запуска загрузки. Error Domain = BRCloudDocsErrorDomain Code = 5 "Операция не может быть завершена (ошибка BRCloudDocsErrorDomain 5 - Нет документа по URL-адресу)"
NSPersistentStoreCoordinatorStoresDidChangeNotification
никогда не вызывается перед ошибкой.
Это мой код для уведомления:
- (void)processStoresDidChange:(NSNotification *)notification
{
NSLog(@"processStoresDidChange");
// Post notification to trigger UI updates
// Check type of transition
NSNumber *type = [notification.userInfo objectForKey:NSPersistentStoreUbiquitousTransitionTypeKey];
//NSLog(@" userInfo is %@", notification.userInfo);
//NSLog(@" transition type is %@", type);
if (type.intValue == NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted) {
NSLog(@" transition type is NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted");
} else if (type.intValue == NSPersistentStoreUbiquitousTransitionTypeAccountAdded) {
NSLog(@" transition type is NSPersistentStoreUbiquitousTransitionTypeAccountAdded");
} else if (type.intValue == NSPersistentStoreUbiquitousTransitionTypeAccountRemoved) {
NSLog(@" transition type is NSPersistentStoreUbiquitousTransitionTypeAccountRemoved");
} else if (type.intValue == NSPersistentStoreUbiquitousTransitionTypeContentRemoved) {
NSLog(@" transition type is NSPersistentStoreUbiquitousTransitionTypeContentRemoved");
}
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
if (type.intValue == NSPersistentStoreUbiquitousTransitionTypeContentRemoved) {
[self deleteLocalStore];
_persistentStoreCoordinator = nil;
_managedObjectContext = nil;
NSLog(@" iCloud store was removed! Wait for empty store");
}
// Refresh user Interface
[[NSNotificationCenter defaultCenter] postNotificationName:@"notiIcloud" object:@"storeChanged"];
}];
}
Как я могу обнаружить, что содержимое iCloud было удалено и не удалось получить ошибку выше?