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 dificultades para continuar con lo que Apple ha escrito. Esto es lo que tengo hasta ahora, pero no estoy seguro de a dónde ir desde aquí.

UPDATE2

Tengo lo siguiente en mi código para save 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 mismo. Hago clic en el button para save en iCloud Drive, y no aparecen errores, 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 usa iOS 8.1.1.

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

Bueno, me tienes interesado en este asunto yo mismo y, como resultado, he pasado mucho time en esta pregunta, pero ahora que lo estoy trabajando, ¡espero que te ayude también!

Archivo en mi Mac

Para ver lo que realmente sucede en segundo plano, puedes echar un vistazo a ~/Library/Mobile Documents/ , ya que esta es la carpeta donde los files aparecerán finalmente. Otra utilidad muy interesante es brctl , para controlar lo que sucede en tu mac después de almacenar un file en iCloud. Ejecute el brctl log --wait --shorten desde una window de Terminal para iniciar el logging.

Lo primero que debe hacer, después de habilitar la capacidad de iCloud (con los documentos de iCloud seleccionados), es proporcionar información para el soporte de iCloud Drive ( Activación del soporte de iCloud Drive ). También tuve que superar mi versión de package antes de ejecutar la aplicación nuevamente; me tomó un time para resolver esto. Agregue lo siguiente a su info.plist :

 <key>NSUbiquitousContainers</key> <dict> <key>iCloud.YOUR_BUNDLE_IDENTIFIER</key> <dict> <key>NSUbiquitousContainerIsDocumentScopePublic</key> <true/> <key>NSUbiquitousContainerSupportedFolderLevels</key> <string>Any</string> <key>NSUbiquitousContainerName</key> <string>iCloudDriveDemo</string> </dict> </dict> 

A continuación, 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 occurnetworking: %@", 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 file llamado demo.pdf almacenado en la carpeta Documentos, que estaré "cargando".

Resaltaré algunas partes:

URLForUbiquityContainerIdentifier: proporciona el directory raíz para almacenar files, si desea que aparezcan en iCloud Drive en su Mac, entonces debe almacenarlos en la carpeta Documentos, así que aquí agregamos esa carpeta a la raíz:

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

También debe agregar el nombre del file a la URL, aquí copio el nombre del file del localURL (que es demo.pdf):

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

Y eso es básicamente …

Como bonificación, vea cómo puede proporcionar un puntero NSError para get información de error potencial:

 // And finish up the 'store' action NSError *error; if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) { NSLog(@"Error occurnetworking: %@", 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 sabe de ninguna guía de la mano mejor, por lo que esto puede ayudar:

Deberá search la ubiquityURL utilizando la function 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á search en NSMetadataQuery para detectar documentos cargados desde otros dispositivos y, potencialmente, ponerlos en queue para su descarga, y observar la NSPersistentStoreDidImportUbiquitousContentChangesNotification para encontrar acerca de los cambios realizados a través de iCloud, entre otras cosas.

** Edite 2 **

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

Es posible que también necesite search en 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