sacar - Cómo obtener la URL de una imagen recién agregada en PHPhotoLibrary
obtener url de imagen (3)
Si utilizamos ALAssetsLibrary, es muy sencillo guardar una imagen en el álbum de fotos y obtener su URL:
// Get the image
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Add the image in the Photo Library
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum: [image CGImage]
orientation: (ALAssetOrientation)[image imageOrientation]
completionBlock: ^(NSURL *assetURL, NSError *error)
{
if (error)
{
NSLog( @"error: %@", error );
}
else
{
NSLog( @"assetURL = %@", assetURL );
}
}];
¡Pero sorprendentemente no parece posible hacer lo mismo con la nueva PHPhotoLibrary!
Una solución para tener el mismo resultado con PHPhotoLibrary siempre es bienvenido.
Estoy usando el UIImagePickerController en dos casos
- para seleccionar una imagen existente en la Biblioteca de fotos
- tomar una nueva foto
En el primer caso, cuando elijo una imagen de la biblioteca, puedo obtener fácilmente la URL en el método delegado:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Get the URL
NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL];
...
}
Pero cuando tomo una foto nueva, la imagen aún no está en la biblioteca de fotos y todavía no tiene una URL. Entonces, primero necesito agregar la imagen en la Biblioteca. Pero entonces, ¿cómo obtener la URL del nuevo activo?
Aquí está mi código para agregar la imagen en la Biblioteca de fotos
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Get the image
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Add the image in the library
[[PHPhotoLibrary sharedPhotoLibrary]
performChanges:^
{
// Request creating an asset from the image.
PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
// Get the URL of the new asset here ?
...
}
completionHandler:^(BOOL success, NSError *error)
{
if (!success) { ...; return; }
// Get the URL of the new asset here ?
...
}
];
}
No encontré la manera de obtener la URL, pero tal vez localIdentifier puede ayudarlo a hacer el mismo trabajo.
utilizar
NSString* localId = [[assetChangeRequest placeholderForCreatedAsset] localIdentifier];
para obtener la identificación local y obtener la imagen más tarde.
__block NSString* localId;
// Add it to the photo library
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
if (self.assetCollection) {
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.assetCollection];
[assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
}
localId = [[assetChangeRequest placeholderForCreatedAsset] localIdentifier];
} completionHandler:^(BOOL success, NSError *error) {
PHFetchResult* assetResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[localId] options:nil];
if (!success) {
NSLog(@"Error creating asset: %@", error);
} else {
PHFetchResult* assetResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[localId] options:nil];
PHAsset *asset = [assetResult firstObject];
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
UIImage* newImage = [UIImage imageWithData:imageData];
self.imageView.image = newImage;
}];
}
}];
No me gusta esta solución, ya que podría dar lugar a una condición de carrera. Hasta ahora no puedo pensar en una mejor solución. Si alguien lo hace, me encantaría escucharlo :) De cualquier manera, aquí hay una versión Swift de la respuesta de Rigel Chen
import Photos
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
var localId:String?
let imageManager = PHPhotoLibrary.sharedPhotoLibrary()
imageManager.performChanges({ () -> Void in
let request = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
localId = request.placeholderForCreatedAsset?.localIdentifier
}, completionHandler: { (success, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if let localId = localId {
let result = PHAsset.fetchAssetsWithLocalIdentifiers([localId], options: nil)
let assets = result.objectsAtIndexes(NSIndexSet(indexesInRange: NSRange(location: 0, length: result.count))) as? [PHAsset] ?? []
if let asset = assets.first {
// Do something with result
}
}
})
})
}
}