Ho un'applicazione per OSX e iOS e entrambi utilizzano iCloud per condividere i dati di base tra di loro. Quando apporto le modifiche nell'iPhone, posso vederle nell'app OSX e lo NSPersistentStoreDidImportUbiquitousContentChangesNotification
viene chiamato in entrambe le app, quindi iOS -> Mac funziona bene. Ma quando apporto alcune modifiche all'app per Mac non riesco a vederle nell'iPhone. L'iPhone non chiama mai lo NSPersistentStoreDidImportUbiquitousContentChangesNotification
. L'unico modo per ottenere le modifiche al Mac è apportare alcune modifiche su iPhone. Quindi posso vedere tutte le modifiche.iCloud Core Condivisione dei dati tra OSX e iOS
L'integrazione di iCloud in entrambi i progetti è la stessa. La datamodel dei dati di base è la stessa. I diritti sono entrambi uguali.
Tutto il mio codice si basa su questa libreria: http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/
Perché l'iPhone non ottenere modifiche Mac finché io ponga qualche cambiamento a iPhone? Qualche idea?
Un'altra domanda
Nella mia app quando l'utente abilita icloud verifico se è già un file a iCloud. Se il file esiste, l'utente può scegliere di ripristinare i dati principali dal file iCloud o avviare una nuova copia dal negozio locale. Per iniziare una nuova copia di questo codice:
- (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];
}
In questo modo da un unico dispositivo tutto sembra funzionare bene, ma quando provo questo con più dispositivi sto ottenendo alcuni errori.
Esempio:
Ho due dispositivi. Il primo non è connesso a iCloud e il secondo è connesso a iCloud. Nel primo dispositivo quando abilito iCloud scelgo startNewCopy
e poi nel secondo dispositivo ottengo questo errore:
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)"
Il NSPersistentStoreCoordinatorStoresDidChangeNotification
non è mai chiamato prima dell'errore.
Questo è il mio codice per la notifica:
- (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"];
}];
}
Come posso rilevare che il contenuto iCloud è stato rimosso ed evitare di ottenere l'errore di cui sopra?
Questo in realtà non risponde alla tua domanda, ma ho rinunciato a utilizzare Core Data con il supporto iCloud molto tempo fa. Ho quindi scritto la mia sincronizzazione, ma era un po 'limitato. Poi ho trovato Ensembles (http://www.ensembles.io) e lo sto usando da allora. È stato fantastico per me. C'è una versione open-source gratuita. –
Thx per la risposta, ma preferisco usare il supporto iCloud standard di Apple. – user3065901
Buona fortuna a te! –