¿Cómo generar miniaturas de imágenes en iCloud Drive?

Esto parece fácil, pero la falta de documentation hace que esta pregunta sea imposible de adivinar.

Tengo imágenes y videos en la unidad icloud de mi aplicación y quiero crear miniaturas de estos activos. Estoy hablando de activos en iCloud Drive, no del flujo de fotos iCloud dentro del rollo de la camera. Estoy hablando de la verdadera carpeta de iCloud Drive.

Crear miniaturas de los videos es "fácil" en comparación con las imágenes. Solo necesitas 2 semanas para descubrir cómo funciona, teniendo en count la pobre documentation que Apple escribió, pero las miniaturas de las imágenes parecen imposibles.

Lo que tengo ahora es una matriz de NSMetadataItem cada uno que describe un elemento en la carpeta iCloud.

Estos son los methods que he intentado hasta ahora y que no funcionan :


MÉTODO 1

 [fileURL startAccessingSecurityScopedResource]; NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init]; __block NSError *error; [coordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly error:&error byAccessor:^(NSURL *newURL) { NSDictionary *thumb; BOOL success = [newURL getResourceValue:&thumb forKey:NSURLThumbnailDictionaryKey error:&error]; UIImage *thumbnail = thumb[NSThumbnail1024x1024SizeKey]; }]; [fileURL stopAccessingSecurityScopedResource]; 

Los resultados de este método son fantásticos. Listo para eso Aquí vamos: success = YES , error = nil y thumbnail = nil .


OTRO MÉTODO

 AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:fileURL options:nil]; AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; imageGenerator.appliesPrefernetworkingTrackTransform = YES; CMTime time = CMTimeMake(0, 60); // time range in which you want NSValue *timeValue = [NSValue valueWithCMTime:time]; [imageGenerator generateCGImagesAsynchronouslyForTimes:@[timeValue] completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * error) { thumbnail = [[UIImage alloc] initWithCGImage:image]; }]; 

error = The requested URL was not found on this server. y thumbnail = nil

Este método parece ser solo para videos. Lo estaba intentando por si acaso. ¿Algún equivalente de este método a las imágenes?


MÉTODO PRIMITIVO

 NSData *tempData = [NSData dataWithContentsOfUrl:tempURL]; 

NOPE – datos = cero


MÉTODO 4

El cuarto método posible estaría utilizando ALAsset pero esto fue obsoleto en iOS 9.

Creo que todos estos methods fallan porque funcionan (error o no) si el recurso es local. ¿Alguna idea sobre cómo download la image para poder get la miniatura?

¿Alguna otra idea?

Gracias


EDITAR: después de varias testings, veo que el Método 1 es el único que parece estar en la dirección correcta. Este método funciona mal, a veces agarrando el ícono pero la mayor parte del time no funciona.


Otro punto es esto. Cualquier cosa que me sugiera la gente, siempre dicen sobre la descarga de la image completa para get la miniatura. No creo que este sea el path a seguir. Simplemente vea cómo funcionan las miniaturas de los videos. No descarga el video completo para get su miniatura.

Entonces esta pregunta permanece abierta.

El Photos-Framework o AssetsLibrary no funcionará aquí, ya que tendría que importar primero sus iCloud Drive Photos a PhotoLibrary para usar cualquier método de estos dos frameworks.

Lo que debe tener en count es ImageIO: Obtenga el contenido de iCloud Drive Photo como NSData y luego proceda de la siguiente manera:

 CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)(imageData), NULL ); NSDictionary* thumbOpts = [NSDictionary dictionaryWithObjectsAndKeys: (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform, (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageAlways, [NSNumber numberWithInt:160],(id)kCGImageSourceThumbnailMaxPixelSize, nil]; CGImageRef thumbImageRef = CGImageSourceCreateThumbnailAtIndex(source,0,(__bridge CFDictionaryRef)thumbOpts); UIImage *thumbnail = [[UIImage alloc] initWithCGImage: thumbImageRef]; 

Después de probar varias soluciones, la que parece funcionar mejor es esta:

 [fileURL startAccessingSecurityScopedResource]; NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init]; __block NSError *error; [coordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly error:&error byAccessor:^(NSURL *newURL) { NSDictionary *thumb; BOOL success = [newURL getResourceValue:&thumb forKey:NSURLThumbnailDictionaryKey error:&error]; UIImage *thumbnail = thumb[NSThumbnail1024x1024SizeKey]; }]; [fileURL stopAccessingSecurityScopedResource]; 

Esta solución no es perfecta. No logrará traer las miniaturas a veces, pero no pude encontrar ninguna otra solución que funcione al 100%. Otros son peores que eso.