varios usar subir seleccionar restaurar recuperar puedo para herramientas descargar compartir como carpeta borrados archivos objective-c cocoa-touch nsfilemanager icloud

objective c - subir - Cómo usar iCloud para almacenar y sincronizar archivos de aplicaciones



herramientas de icloud (5)

Lo que "funciona" para mí es simple:

NSFileManager *fm = [NSFileManager defaultManager]; NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; if (ubiq == nil) { return NO; } NSError *theError = nil; [fm setUbiquitous:true itemAtURL:backupUrl destinationURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError];

Apple dice que invoque el hilo que no es UI. Tener los archivos "movidos". Puede consultarlos a través de NSMetaDataQuery siguiente manera:

self.query = [[NSMetadataQuery alloc] init]; [self.query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]]; NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K like ''*.db''", NSMetadataItemFSNameKey]; [self.query setPredicate:pred]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:self.query]; [self.query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)notification { NSMetadataQuery *query = [notification object]; [query disableUpdates]; [query stopQuery]; [self loadData:query]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query]; self.query = nil; }

Muestra de enumeración a través de los resultados de la consulta:

- (void)loadData:(NSMetadataQuery *)query { [self.backups removeAllObjects]; for (NSMetadataItem *item in [query results]) { NSURL *url = [item valueForAttribute:NSMetadataItemURLKey]; [self.backups addObject:url.lastPathComponent]; } [_table reloadData]; [self.loadingBackupIndicator stopAnimating]; self.loadingIndicatorLabel.text = [NSString stringWithFormat: @"%d backups found", [self.backups count]]; }

Y para comenzar a "descargar" el archivo concreto:

NSFileManager *fm = [NSFileManager defaultManager]; NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; if (ubiq == nil) { return NO; } NSError *theError = nil; bool started = [fm startDownloadingUbiquitousItemAtURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError]; NSLog(@"started download for %@ %d", backupName, started); if (theError != nil) { NSLog(@"iCloud error: %@", [theError localizedDescription]); }

Con cheques para que el archivo "se descargue":

- (BOOL)downloadFileIfNotAvailable { NSNumber *isIniCloud = nil; NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; NSURL *file = [[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:self.backupName]; if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) { // If the item is in iCloud, see if it is downloaded. if ([isIniCloud boolValue]) { NSNumber* isDownloaded = nil; if ([file getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:nil]) { if ([isDownloaded boolValue]) { [self.loadingBackupIndicator stopAnimating]; self.loadingIndicatorLabel.text = @"Downloaded"; .... [[NSFileManager defaultManager] copyItemAtPath:[file path] toPath:restorePath error:&theError ]; .... return YES; } self.loadingCheckTimer = [NSTimer timerWithTimeInterval:3.0f target:self selector:@selector(downloadFileIfNotAvailable) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:self.loadingCheckTimer forMode:NSDefaultRunLoopMode]; return NO; } } } return YES; }

No esperaba que el código fuera tan largo y lo siento por proporcionar fragmentos muy originales aquí. No hay intención de decir que lo anterior puede ser una calidad de producción de código, simplemente compartiendo el concepto.

Todavía no lo he enviado a Apple en mi aplicación, por lo que no puedo decir que sería "aprobado" para la tienda de aplicaciones (si lo encuentran o les importa ...)

Ya tengo una aplicación de iPhone que almacena datos en un archivo en la carpeta de documentos locales. Ahora aprendí sobre las tecnologías iCloud y mi primera pregunta fue: ¿hay alguna manera de usar iCloud como directorio cuando a veces consulto nuevas versiones?

Quiero decir: ¿puedo evitar usar UIDocument, coordinadores de archivos y presentadores de archivos? Solo quiero saber si podría tratar iCloud como una carpeta especial y solo usar NSFileManager para enviar y recuperar archivos.

Última nota: no uso Core Data ni ninguna base de datos, solo tengo un archivo de datos.

Editar:

Ya leí la documentación oficial de Apple iCloud, así que no me vincules con ellos. Solo necesito algunos ejemplos de código.


Puede cargar archivos individuales en iCloud usando NSFileManager. Publiqué un tutorial completo sobre cómo hacer eso en mi blog, pero aquí está el código de NSFileManager relevante:

NSURL *destinationURL = [self.ubiquitousURL URLByAppendingPathComponent:@"Documents/image.jpg"] [[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:sourceURL destinationURL:destinationURL error:&error]


Realmente no hay una forma de evitar el uso de UIDocument. Intenté hacerlo en uno de mis primeros usos de iCloud, pero resultó ser un desastre sin UIDocument. Usar UIDocument al principio parece mucho trabajo extra, pero no lo es.

Puede subclasificar fácilmente UIDocument en menos de una hora y hacer que funcione con cualquier tipo de archivo (simplemente configure la propiedad de content como NSData). También proporciona numerosos beneficios sobre el sistema de archivos estándar:

  • Seguimiento de cambios
  • Resolución de conflictos de archivos
  • Soporte del estado del documento
  • Funciones de guardar / abrir / cerrar mejoradas

Honestamente, pasar solo una hora o dos leyendo la documentación de Apple y luego usarlo bien vale la pena el tiempo y la capacidad mental. Un buen artículo de inicio sobre el almacenamiento de documentos iCloud se puede encontrar en la documentación del desarrollador de Apple .

He escrito una subclase UIDocument que funcionará con cualquier tipo de archivo (NSData específicamente). Puede ver, descargar y modificar el código de la subclase UIDocument en GitHub .

Crea el documento:

// Initialize a document with a valid file path iCloudDocument *document = [[iCloudDocument alloc] initWithFileURL:fileURL]; // Set the content of the document document.contents = content; // Increment the change count [document updateChangeCount:UIDocumentChangeDone];

Guarde un documento existente:

// Save and close the document [document closeWithCompletionHandler:nil];

Guarde un nuevo documento:

[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:nil];

También puede sincronizar todos los archivos almacenados en iCloud utilizando NSMetadataQuery. Apple proporciona un buen ejemplo del uso de la consulta NSMetadata para sincronizar archivos de aplicaciones. También asegúrese de comprobar si hay iCloud antes de realizar estas operaciones (sugerencia: utilice el método ubiquityIdentityToken en NSFileManager).

También es posible que desee considerar el uso de una biblioteca de código abierto como iCloud Document Sync . El proyecto iCloud Document Sync hace que sea muy fácil almacenar y sincronizar archivos de aplicaciones:

Integre iCloud en proyectos de documentos iOS con métodos de código de una línea. Sincronice, cargue, administre y elimine documentos de iCloud rápida y fácilmente. Ayuda a hacer que iCloud "solo funcione" para los desarrolladores también.

En casi todos los métodos de iCloud Document Sync, todo lo que tienes que hacer es pasar tus datos de archivo como un parámetro y luego se encarga del resto (guardar, sincronizar, etc.).

DESCARGO DE RESPONSABILIDAD : soy un desarrollador contribuyente del proyecto de código abierto, iCloud Document Sync. Sin embargo, creo que este proyecto será beneficioso para usted y es relevante para esta pregunta. Esto no es una promoción o publicidad.


Sé cómo te sientes, iCloud es un poco desalentador. Sin embargo, creo que no hay forma de evitar UIDocument, coordinadores de archivos, etc. y simplemente usar iCloud como una carpeta simple.

Si está buscando un código de muestra fácil de entender, eche un vistazo a esta publicación:

Conceptos básicos y ejemplos de código de iCloud

Incluí un código de muestra completo que cubre los mínimos de iCloud y casi lo usa como un directorio. Quizás esto hace menos desalentador el uso de UIDocument, coordinadores de archivos, etc.

Pero, como tú, desearía que hubiera una manera más fácil y más compatible con la buena idea de la vieja carpeta de documentales. Sin embargo, como esto es iCloud y como iCloud hace varias cosas más (como mantener todo sincronizado en diferentes dispositivos, actualizar constantemente a la nube, etc.), no habrá forma de evitar UIDocument, etc.


Usa este código:

+ (NSString *)Pathsave { NSString *os5 = @"5.0"; NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; if ([currSysVer compare:os5 options:NSNumericSearch] == NSOrderedAscending) { // Lower than 4 return path; } else if ([currSysVer compare:os5 options:NSNumericSearch] == NSOrderedDescending) { // 5.0.1 and above return path; } else { // iOS 5 path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"]; return path; } return nil; }