Mam aplikację dla OSX i iOS i oba używają iCloud do dzielenia się między nimi podstawowymi danymi. Kiedy wprowadzam zmiany w iPhonie, widzę je w aplikacji OSX, a NSPersistentStoreDidImportUbiquitousContentChangesNotification
jest wywoływany w obu aplikacjach, więc iOS -> Mac działa dobrze. Ale kiedy wprowadzam pewne zmiany w aplikacji Mac, nie widzę ich na iPhonie. IPhone nigdy nie wywołuje NSPersistentStoreDidImportUbiquitousContentChangesNotification
. Jedynym sposobem, w jaki mogę uzyskać zmiany na Macu, jest wprowadzenie pewnych zmian na iPhonie. Wtedy widzę wszystkie zmiany.Współdzielenie danych iCloud pomiędzy OSX i iOS
Integracja iCloud w obu projektach jest taka sama. Główny datamodel danych jest taki sam. Uprawnienia są również takie same.
Całe kod jest oparty na tej biblioteki: http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/
Dlaczego iPhone nie uzyskiwanie zmian Mac aż położę jakąś zmianę na iPhone? Jakieś pomysły?
Inną kwestią
W mojej aplikacji, gdy użytkownik pozwala sprawdzić, jeśli plik jest już w iCloud iCloud. Jeśli plik istnieje, użytkownik może wybrać przywrócenie podstawowych danych z pliku iCloud lub rozpocząć nową kopię z lokalnego magazynu. Aby rozpocząć nową kopię używam tego kodu:
- (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];
}
ten sposób z jednego urządzenia wszystko wydaje się działać dobrze, ale gdy próbuję to z wieloma urządzeniami Dostaję jakieś błędy.
Przykład:
Mam dwa urządzenia. Pierwsza nie jest połączona z iCloud, a druga jest połączona z iCloud. W pierwszym urządzeniem, kiedy włączyć iCloud wybiorę startNewCopy
a następnie w drugim urządzeniu otrzymuję ten błąd:
CoreData: Ubiquity: Librarian returned a serious error for starting downloads Error Domain=BRCloudDocsErrorDomain Code=5 "The operation couldn’t be completed. (BRCloudDocsErrorDomain error 5 - No document at URL)"
NSPersistentStoreCoordinatorStoresDidChangeNotification
nigdy nie jest wywoływana przed błędem.
To jest mój kod na zgłoszenia:
- (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"];
}];
}
jaki sposób można wykryć, że treść została usunięta iCloud i uniknąć błędu powyżej?
To tak naprawdę nie odpowiada na twoje pytanie, ale zrezygnowałem z używania Core Data z obsługą iCloud bardzo dawno temu. Potem napisałem własną synchronizację, ale było to trochę ograniczone. Potem znalazłem Ensembles (http://www.ensembles.io) i używam go od tego czasu. To było dla mnie niesamowite. Dostępna jest darmowa wersja open-source. –
Thx za odpowiedź, ale wolę używać standardowego wsparcia dla iCloud od Apple. – user3065901
Powodzenia! –