Guarde los documentos de iOS 8 en iCloud Drive

Quiero que mi aplicación guarde los documentos que crea en iCloud Drive, pero estoy teniendo problemas para seguir lo que Apple ha escrito. Esto es lo que tengo hasta ahora, pero no estoy seguro de a dónde ir desde aquí.

ACTUALIZACIÓN2

Tengo lo siguiente en mi código para guardar manualmente un documento en iCloud Drive:

- (void)initializeiCloudAccessWithCompletion:(void (^)(BOOL available)) completion { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ self.ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; if (self.ubiquityURL != nil) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"iCloud available at: %@", self.ubiquityURL); completion(TRUE); }); } else { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"iCloud not available"); completion(FALSE); }); } }); } if (buttonIndex == 4) { [self initializeiCloudAccessWithCompletion:^(BOOL available) { _iCloudAvailable = available; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:selectedCountry]; NSURL* url = [NSURL fileURLWithPath: pdfPath]; [self.manager setUbiquitous:YES itemAtURL:url destinationURL:self.ubiquityURL error:nil]; }]; } 

Tengo los derechos configurados para la ID de la aplicación y en Xcode. Hago clic en el botón para guardar en iCloud Drive y no aparece ningún error, la aplicación no falla, pero no aparece nada en mi Mac en iCloud Drive. La aplicación se ejecuta en mi iPhone 6 Plus a través de Test Flight mientras uso iOS 8.1.1.

Si lo ejecuto en Simulator (sé que no funcionará debido a que iCloud Drive no funciona con el simulador), 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]' error de locking: 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]'

Bueno, me interesaste en este asunto yo mismo y, como resultado, he dedicado mucho tiempo a esta cuestión, pero ahora que lo estoy haciendo ¡espero que también te ayude!

Archivo en mi Mac

Para ver lo que sucede realmente en el fondo, puede echar un vistazo a ~/Library/Mobile Documents/ , ya que esta es la carpeta donde finalmente se mostrarán los archivos. Otra brctl muy buena es brctl , para monitorear lo que sucede en tu mac después de guardar un archivo en iCloud. Ejecute brctl log --wait --shorten desde una ventana de Terminal para iniciar el registro.

Lo primero que debe hacer, después de habilitar la capacidad de iCloud (con los documentos de iCloud seleccionados), es proporcionar información para la compatibilidad con iCloud Drive ( Habilitar la compatibilidad con iCloud Drive ). También tuve que cambiar la versión de mi paquete antes de ejecutar la aplicación de nuevo; Me tomó un tiempo para resolver esto. Agregue lo siguiente a su info.plist :

 NSUbiquitousContainers  iCloud.YOUR_BUNDLE_IDENTIFIER  NSUbiquitousContainerIsDocumentScopePublic  NSUbiquitousContainerSupportedFolderLevels Any NSUbiquitousContainerName iCloudDriveDemo   

El siguiente, el código:

 - (IBAction)btnStoreTapped:(id)sender { // Let's get the root directory for storing the file on iCloud Drive [self rootDirectoryForICloud:^(NSURL *ubiquityURL) { NSLog(@"1. ubiquityURL = %@", ubiquityURL); if (ubiquityURL) { // We also need the 'local' URL to the file we want to store NSURL *localURL = [self localPathForResource:@"demo" ofType:@"pdf"]; NSLog(@"2. localURL = %@", localURL); // Now, append the local filename to the ubiquityURL ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent]; NSLog(@"3. ubiquityURL = %@", ubiquityURL); // And finish up the 'store' action NSError *error; if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) { NSLog(@"Error occurred: %@", error); } } else { NSLog(@"Could not retrieve a ubiquityURL"); } }]; } - (void)rootDirectoryForICloud:(void (^)(NSURL *))completionHandler { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]; if (rootDirectory) { if (![[NSFileManager defaultManager] fileExistsAtPath:rootDirectory.path isDirectory:nil]) { NSLog(@"Create directory"); [[NSFileManager defaultManager] createDirectoryAtURL:rootDirectory withIntermediateDirectories:YES attributes:nil error:nil]; } } dispatch_async(dispatch_get_main_queue(), ^{ completionHandler(rootDirectory); }); }); } - (NSURL *)localPathForResource:(NSString *)resource ofType:(NSString *)type { NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *resourcePath = [[documentsDirectory stringByAppendingPathComponent:resource] stringByAppendingPathExtension:type]; return [NSURL fileURLWithPath:resourcePath]; } 

Tengo un archivo llamado demo.pdf almacenado en la carpeta Documentos, que voy a ‘cargar’.

Destacaré algunas partes:

URLForUbiquityContainerIdentifier: proporciona el directorio raíz para almacenar archivos, si desea que se muestren en iCloud Drive en su Mac, debe almacenarlos en la carpeta Documentos, de modo que aquí agregamos esa carpeta a la raíz:

 NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]; 

También necesita agregar el nombre del archivo a la URL, aquí copio el nombre de archivo de la URL local (que es demo.pdf):

 // Now, append the local filename to the ubiquityURL ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent]; 

Y eso es básicamente …

Como NSError adicional, compruebe cómo puede proporcionar un puntero NSError para obtener información sobre posibles errores:

 // And finish up the 'store' action NSError *error; if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) { NSLog(@"Error occurred: %@", error); } 

Si tiene la intención de trabajar con UIDocument e iCloud, esta guía de Apple es bastante buena: https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html

EDITADO : No conozco ninguna mejor guía de mano, así que esto puede ayudar:

Tendrá que buscar ubiquityURL utilizando la función NSFileManager en NSFileManager (que debe hacerse de forma asíncrona). Una vez hecho esto, puede usar un código como el siguiente para crear su documento.

 NSString* fileName = @"sampledoc"; NSURL* fileURL = [[self.ubiquityURL URLByAppendingPathComponent:@"Documents" isDirectory:YES] URLByAppendingPathComponent:fileName isDirectory:NO]; UIManagedDocument* document = [[UIManagedDocument alloc] initWithFileURL:fileURL]; document.persistentStoreOptions = @{ NSMigratePersistentStoresAutomaticallyOption : @(YES), NSInferMappingModelAutomaticallyOption: @(YES), NSPersistentStoreUbiquitousContentNameKey: fileName, NSPersistentStoreUbiquitousContentURLKey: [self.ubiquityURL URLByAppendingPathComponent:@"TransactionLogs" isDirectory:YES] }; [document saveToURL:fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { }]; 

También querrá estudiar el uso de NSMetadataQuery para detectar documentos cargados desde otros dispositivos y potencialmente ponerlos en cola para su descarga, y observar el NSPersistentStoreDidImportUbiquitousContentChangesNotification para encontrar cambios realizados a través de iCloud, entre otras cosas.

** Editar 2 **

Parece que está intentando guardar un archivo PDF, que no es exactamente lo que Apple considera un “documento” en términos de sincronización de iCloud. No es necesario usar UIManagedDocument. Elimine las últimas 3 líneas de su controlador de finalización y, en su lugar, simplemente use setUbiquitous de setUbiquitous:itemAtURL:destinationURL:error: function. La primera URL debe ser una ruta local al PDF. La segunda URL debe ser la ruta dentro del contenedor ubiquiuty para guardar como.

Es posible que también deba consultar NSFileCoordinator. Creo que esta guía de Apple puede ser la más relevante: https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/iCloud/iCloud.html