Cómo sincronizar un NSDocument de Mac osx a iPad / iPhone con iCloud

He visto el código de ejemplo de iCloud Document para iOS y lo usé para sincronizar un uidocument ay desde iCloud y ahora estoy intentando sincronizar iCloud con un nsdocument en una aplicación Mac OSX que no tiene UIDocument .

Intenté cambiar UIDocument a NSDocument pero todos los methods de synchronization con icloud son diferentes. No he encontrado ningún código de ejemplo ni tutoriales, excepto la documentation de Apple, que es muy confusa y no está bien escrita.

Por ejemplo, el método a continuación, de UIDocument en iOS no existe en NSDocument en OS X:

 //doc is an instance of subclassed UIDocument [doc openWithCompletionHandler:nil]; 

Apple Documentation proporciona este código para OS X:

 - (void)checkIfCloudAvaliable { NSURL *ubiquityContainerURL = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:@"Documents"]; if (ubiquityContainerURL == nil) { NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: NSLocalizedString(@"iCloud does not appear to be configunetworking.", @""), NSLocalizedFailureReasonErrorKey, nil]; NSError *error = [NSError errorWithDomain:@"Application" code:404 userInfo:dict]; [self presentError:error modalForWindow:[self windowForSheet] delegate:nil didPresentSelector:NULL contextInfo:NULL]; return; } dest = [ubiquityContainerURL URLByAppendingPathComponent: [[self fileURL] lastPathComponent]]; } - (void)moveToOrFromCloud { dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(globalQueue, ^(void) { NSFileManager *fileManager = [[NSFileManager alloc] init]; NSError *error = nil; // Move the file. BOOL success = [fileManager setUbiquitous:YES itemAtURL:[self fileURL] destinationURL:dest error:&error]; dispatch_async(dispatch_get_main_queue(), ^(void) { if (! success) { [self presentError:error modalForWindow:[self windowForSheet] delegate:nil didPresentSelector:NULL contextInfo:NULL]; } }); }); [self setFileURL:dest]; [self setFileModificationDate:nil]; } 

¿Cómo puedo sincronizar iOS y OS X (porque NSDocument no existe en iOS y UIDocument no existe en OS X)? ¿Alguien sabe dónde puedo encontrar una muestra para Mac OSX ( NSDocument syncing)?

¡Logré que funcione! Aquí está mi código del file nsdocument subclasificado en OS X:

Archivo de cabecera:

 #import <Cocoa/Cocoa.h> #import <Foundation/Foundation.h> @interface subclassedNSDocument : NSDocument @property (strong) NSData *myData; @end 

Archivo de implementación:

 - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError { BOOL readSuccess = NO; if (data) { readSuccess = YES; [self setMyData:data]; } [[NSNotificationCenter defaultCenter] postNotificationName:@"dataModified" object:self]; return readSuccess; } - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError { if (!myData && outError) { *outError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteUnknownError userInfo:nil]; } return myData; } 

y en el file AppDelegate.m:

 #define kFILENAME @"mydocument.dox" - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; if (ubiq) { NSLog(@"iCloud access at %@", ubiq); // TODO: Load document... [self loadDocument]; } else { NSLog(@"No iCloud access"); } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataReloaded:) name:@"dataModified" object:nil]; } - (void)update_iCloud { NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:kFILENAME]; self.doc.myData = [NSKeyedArchiver archivedDataWithRootObject:[@"Your Data Array or any data", nil]]; [self.doc saveToURL:ubiquitousPackage ofType:@"dox" forSaveOperation:NSSaveOperation error:nil]; } - (void)loadData:(NSMetadataQuery *)query { if ([query resultCount] == 1) { NSMetadataItem *item = [query resultAtIndex:0]; NSURL *url = [item valueForAttribute:NSMetadataItemURLKey]; NSLog(@"url = %@",url); subclassedNSDocument *doc = [[subclassedNSDocument alloc] initWithContentsOfURL:url ofType:@"dox" error:nil]; [doc setFileURL:url]; self.doc = doc; } else { NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:kFILENAME]; dataUrls *doc = [[dataUrls alloc] init]; [self.doc setFileURL:ubiquitousPackage]; self.doc = doc; [self.doc saveToURL:ubiquitousPackage ofType:@"dox" forSaveOperation:NSSaveOperation error:nil]; } } - (void)queryDidFinishGathering:(NSNotification *)notification { NSMetadataQuery *query = [notification object]; [query disableUpdates]; [query stopQuery]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query]; _query = nil; [self loadData:query]; } - (void)loadDocument { NSMetadataQuery *query = [[NSMetadataQuery alloc] init]; _query = query; [query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]]; NSPnetworkingicate *pnetworking = [NSPnetworkingicate pnetworkingicateWithFormat: @"%K == %@", NSMetadataItemFSNameKey, kFILENAME]; [query setPnetworkingicate:pnetworking]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query]; [query startQuery]; } - (void)dataReloaded:(NSNotification *)notification { self.doc = notification.object; NSArray *arrFromCloud = [NSKeyedUnarchiver unarchiveObjectWithData:self.doc.myData]; //Update you UI with new data } 

Lo único que no he conseguido es que si cambio los datos del documento en el iPad, la aplicación Mac no llama al método readFromData para actualizar desde iCloud, ¿alguien sabe lo que me falta?

En iOS, el método equivalente, loadFromContents , se loadFromContents automáticamente en cada cambio del UIDocument en iCloud. En OS X, readFromData se llama una vez al cargar, pero nunca se vuelve a llamar.

Espero que mi código pueda ayudar, para mí funciona de una manera desde Mac a iPad.

Creo que NSMetadataQueryDidUpdateNotification es lo que está buscando para detectar la actualización de documentos.

Esto se puede usar como NSMetadataQueryDidFinishGatheringNotification .

Si se trata de files además de datos básicos. Aquí hay un tutorial mejor

http://samvermette.com/312