How to get the URL of an image just added in PHPhotoLibrary
Solution 1
I didn't find the way to get URL, but maybe localIdentifier can help you do the same work.
use
NSString* localId = [[assetChangeRequest placeholderForCreatedAsset] localIdentifier];
to get the local ID and get the image later.
__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;
}];
}
}];
Solution 2
If we use the ALAssetsLibrary, it is very simple to save a picture in the Photo Album and get its 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 );
}
}];
But surprisingly it seems not possible to do the same thing with the new PHPhotoLibrary!
A solution to have the same result with PHPhotoLibrary is always welcome.
Solution 3
I don't like this fix, as this could result in a race condition. So far I can't think of a better solution. If someone does I'd love to hear it :) Either way, here is a Swift-version of Rigel Chen's answer
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
}
}
})
})
}
}
Related videos on Youtube
PatrickV
Updated on June 17, 2022Comments
-
PatrickV almost 2 years
I am using the UIImagePickerController in two cases
- to select an existing image in the Photo Library
- to take a new picture
In the first case, when I choose an image form the library, I can easily get the URL in the delegate method:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { // Get the URL NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL]; ... }
But when I take a new picture, the image is not yet in the photo library and has no URL yet. So, I first need to add the image in the Library. But then, how to get the URL of the new asset?
Here is my code to add the image in the Photo Library
- (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 ? ... } ]; }
-
Kevin R about 8 yearsThis works, but feels very scary, I don't know if it will actually happen, but this approach could result in a race condition.
-
SunilG almost 8 yearsThis is good I up voted but I am curios to know what benefit is this line doing let assets = result.objectsAtIndexes(NSIndexSet(indexesInRange: NSRange(location: 0, length: result.count))) as? [PHAsset] ?? [] we can still do result.firsObject
-
passol over 7 yearsALAssetsLibrary somtimes cannot create group ,
-
Rudolf Real about 7 yearsALAssetsLibrary is deprecated and should not be used anymore.
-
Peter Lapisu almost 7 yearswhat race condition? i wouldn't be sure if the localIdentifier is available yet
-
Moeez Akram over 6 yearshello can you please tell what will be the self.assetCollection here, what class it is, thanks