I am trying to get the geolocation of the image and video though PHAssets, image location is being fetched through.
PHAsset.fetchAssetsWithALAssetURLs([imageUrl], options: opts).
When i used the same below code for video this returned zero.
PHAsset.fetchAssetsWithALAssetURLs([videoUrl], options: opts)
This is tested on iOS 8 and works for videos so it should work similarly for photos with a few tweaks.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *videoUrl = (NSURL *)[info objectForKey:UIImagePickerControllerMediaURL];
NSString *moviePath = [videoUrl path];
if ( UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath) ) {
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) {
CLLocation *location = [asset valueForProperty:ALAssetPropertyLocation];
NSLog(#"Location Meta: %#", location);
} failureBlock:^(NSError *error) {
NSLog(#"Video Date Error: %#", error);
}];
}
}
Get all videos Gelocation
PHPhotoLibrary.requestAuthorization { (status) -> Void in
let videosOption = PHFetchOptions()
videosOption.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
videosOption.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
let allVids = PHAsset.fetchAssets(with: videosOption)
for index in 0..<allVids.count {
//print Location here
print(allVids[index].location as Any)
}
}
Related
I have more than 10 videos url in one view which is coming from Web service. I am showing these videos thumbnails in UITableview.
I am Using following code where I m Saving These Videos to gallery in particular folder
This is my code::
NSURL *url = [NSURL URLWithString:Urlstr];
NSData *data = [NSData dataWithContentsOfURL:url];
// Write it to cache directory
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"file.mov"];
[data writeToFile:path atomically:YES];
// After that use this path to save it to PhotoLibrary
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library addAssetsGroupAlbumWithName:#"MyFolderName" resultBlock:^(ALAssetsGroup *group)
{
//How to get the album URL?
// saving the video in gallery though file path and document directory
[library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:path] completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(#"%#", error.description);
}else {
NSLog(#"Done :)");
}
}];
}
failureBlock:^(NSError *error) {
//Handle the error
}];
Now the issues is it is not saving my video to My folder. But it creates the folder and saving the video in default video folder of gallery.
Anyone please suggest me why it going like this.
- (void)createAlbumInPhotosLibrary:(NSString *)photoAlbumName videoAtFile:(NSURL *)videoURL {
// RELIVIT_moments
__block PHFetchResult *photosAsset;
__block PHAssetCollection *collection;
__block PHObjectPlaceholder *placeholder;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", photoAlbumName];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
// Create the album
if (!collection)
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *createAlbum = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:photoAlbumName];
placeholder = [createAlbum placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
PHFetchResult *collectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[placeholder.localIdentifier]
options:nil];
collection = collectionFetchResult.firstObject;
[self saveVideoInRelivitFolderSetPlaceHolder:placeholder photosAsset:photosAsset collection:collection VideoAtFile:videoURL];
}
}];
} else {
[self saveVideoInRelivitFolderSetPlaceHolder:placeholder photosAsset:photosAsset collection:collection VideoAtFile:videoURL];
}
}
- (void)saveVideoInRelivitFolderSetPlaceHolder:(PHObjectPlaceholder *)placeholderLocal photosAsset:(PHFetchResult *)photosAssetLocal collection:(PHAssetCollection *)collectionLocal VideoAtFile:(NSURL *)videoURL {
__block PHFetchResult *photosAsset = photosAssetLocal;
__block PHAssetCollection *collection = collectionLocal;
__block PHObjectPlaceholder *placeholder = placeholderLocal;
// Save to the album
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:videoURL];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection
assets:photosAsset];
[albumChangeRequest addAssets:#[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
NSLog(#"done");
}
else
{
NSLog(#"%#", error.localizedDescription);
}
}];
}
I am using UIImagePickerController in my application to pick up the image. I need to delete this image synchronously from iOS PhotoLibrary after picking it up in my application.
- (BOOL)createAndInsertNewElementFromDictionary:(NSDictionary*)dict
{
AlbumElement *newElement;
if ([dict[UIImagePickerControllerMediaType]
isEqualToString:(NSString*)kUTTypeMovie])
{
NSURL *mediaUrl = dict[UIImagePickerControllerMediaURL];
newElement = [AlbumElement createElementWithMediaUrl:mediaUrl
inAlbum:_album.name];
}
else if ([dict[UIImagePickerControllerMediaType]
isEqualToString:(NSString*)kUTTypeImage])
{
UIImage *image = [dict[UIImagePickerControllerOriginalImage] copy];
newElement = [AlbumElement createElementWithImage:image
inAlbum:_album.name];
}
if (newElement != nil)
{
[_album.elements insertObject:newElement atIndex:0];
UIImage *icon = [UIImage imageWithContentsOfFile:[newElement iconFullPath]];
[AlbumElement writeImageToFileWithImage:icon
atFullPath:_album.albumIconPath];
}
else
{
NSLog(#"Element was NOT added!");
return NO;
}
return YES;
}
NSURL *url = [dict objectForKey:#"UIImagePickerControllerReferenceURL"] ;
PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];
[library performChanges:^{
// Here assetsURLs is array of url's you want to delete
PHFetchResult *assetsToBeDeleted = [PHAsset fetchAssetsWithALAssetURLs:[NSArray arrayWithObject:url] options:nil];
[PHAssetChangeRequest deleteAssets:assetsToBeDeleted];
} completionHandler:^(BOOL success, NSError *error)
{
// Check error and success here
}];
You can do something like this,
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
NSURL *imgURL = info[UIImagePickerControllerReferenceURL];
[[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
PHAsset *imageAssetTodelete = [PHAsset fetchAssetsWithALAssetURLs:imgURL options:nil];
[PHAssetChangeRequest deleteAssets:imageAssetTodelete];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (error) {
NSLog(#"err description : %#",[error localizedDescription]);
}
if (success) {
NSLog(#"image deleted successfully");
}
}];
}
And don't forget to #import Photos; in your class.
Hope this will help :)
I use the same code like #MOHAMMAD ISHAQ but in my case that not work, the picture are not deleted, I have no any error.
Any help or suggestion please ?
PHAsset *asset = nil;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult != nil && fetchResult.count > 0) {
// get last photo from Photos
asset = [fetchResult lastObject];
}
if (asset) {
PHContentEditingInputRequestOptions *editOptions = [[PHContentEditingInputRequestOptions alloc] init];
[asset requestContentEditingInputWithOptions:editOptions completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
if (contentEditingInput.fullSizeImageURL) {
//do something with contentEditingInput.fullSizeImageURL
NSLog(#"¨PATH %#",contentEditingInput.fullSizeImageURL);
NSMutableArray *persons = [[NSMutableArray alloc]initWithCapacity:0];
[persons addObject:contentEditingInput.fullSizeImageURL];
NSArray *myArray = [[NSArray alloc]initWithArray:persons];
PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];
[library performChanges:^{
PHFetchResult *assetsToBeDeleted = [PHAsset fetchAssetsWithALAssetURLs:myArray options:nil];
[PHAssetChangeRequest deleteAssets:assetsToBeDeleted];
} completionHandler:^(BOOL success, NSError *error)
{
//do something here
NSLog(#"DELETE IAMGE");
}];
}
}];
Thank
I am trying to save a base64 image to camera roll and return the url for the saved image. The code works in so far as I have succeeded in saving to camera roll but I am seeing an error and no URL is returned. The error is:
Error Domain=NSCocoaErrorDomain Code=-1 "(null)"
My code is:
- (void)saveImageDataToLibrary:(CDVInvokedUrlCommand*)command
{
__block CDVPluginResult* result = nil;
NSData* imageData = [NSData dataFromBase64String:[command.arguments objectAtIndex:0]];
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
__block PHObjectPlaceholder *placeholderAsset = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
} completionHandler:^(BOOL success, NSError *error) {
if(success){
NSLog(#"worked");
PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier];
PHContentEditingInputRequestOptions *options = [[PHContentEditingInputRequestOptions alloc] init];
options.networkAccessAllowed = YES; //download asset metadata from iCloud if needed
[asset requestContentEditingInputWithOptions:options
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *assetURL = contentEditingInput.fullSizeImageURL;
NSString* url = [assetURL absoluteString];
NSLog(#"our result is: %#", url);
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:url];
[self invokeCallback:command withResult:result];
}];
} else {
NSLog(#"Error: %#", error);
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description];
[self invokeCallback:command withResult:result];
}
}];
}
- (void) invokeCallback:(CDVInvokedUrlCommand *)command withResult:(CDVPluginResult *)result {
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
Try to use:
PHContentEditingOutput
That object has a property called: renderedContentURL
Use that to get the appropriate URL of your PHAsset.
So to get the URL, your code should look like this:
PHContentEditingOutput *contentEditingOutput = [[PHContentEditingOutput alloc] initWithContentEditingInput:YOUR_PHCONTENTEDITING_INPUT];
NSURL *myPHAssetURL = [contentEditingOutput renderedContentURL];
This is my code. The file is correctly added to photos library, but in instagram app this url -> instagram://library?AssetPath=assets-library%3A%2F%2Fasset%2Fasset.mp4%3Fid=5EDBD113-FF57-476B-AABB-6A59F31170B5&ext=mp4&InstagramCaption=my%caption don't open the last video.
- (void)loadCameraRollAssetToInstagram:(NSURL*)assetsLibraryURL andMessage:(NSString*)message
{
NSString *escapedString = [self urlencodedString:assetsLibraryURL.absoluteString];
NSString *escapedCaption = [self urlencodedString:message];
NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:#"instagram://library?AssetPath=%#&InstagramCaption=%#", escapedString, escapedCaption]];
NSLog(#"instagramURL ==> %#",instagramURL);
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
NSLog(#"Open Instagram!!");
[[UIApplication sharedApplication] openURL:instagramURL];
} else {
NSLog(#"Cant open Instagram!!");
[[[UIAlertView alloc] initWithTitle:#"Instagram" message:#"App not installed" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil] show];
}
}
- (NSString*)urlencodedString:(NSString *)message
{
return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
}
- (void)saveToCameraRoll:(NSURL *)srcURL withCurrentAction:(NSString *)action
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
ALAssetsLibraryWriteVideoCompletionBlock videoWriteCompletionBlock = ^(NSURL *newURL, NSError *error) {
if (error) {
NSLog( #"Error writing image with metadata to Photo Library: %#", error );
[[[UIAlertView alloc] initWithTitle:#"Facebook" message:#"Pal - Currently we can't process your video. Please try again in few moments" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Sign In", nil] show];
} else {
NSLog( #"Wrote image with metadata to Photo Library: %#", newURL.absoluteString);
if ([action isEqualToString:#"instagram"])
[self loadCameraRollAssetToInstagram:newURL andMessage:#"My caption"]; //Can be any text?
}
};
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:srcURL])
{
[library writeVideoAtPathToSavedPhotosAlbum:srcURL completionBlock:videoWriteCompletionBlock];
}
}
something very strange is that worked perfect, until I turned uninstall and then install instagram. Do not know if this has something to do
instagram://library?AssetPath=\(assetsLibraryUrl)
stopped working a while ago. Instagram developers probably moved to Photos framework and no longer use the AssetsLibrary.
Having this assumption I tried several other parameter names and found that instagram://library?LocalIdentifier=\(localID) where localId is the localIdentifier of your PHAsset works for now.
This is still as undocumented as it was so it can break in any future version of the Instagram.
Resuming this task after a long time and considering the borisgolovnev's answer and ALAssetsLibrary is deprecated, the final solution is:
- (void)saveToCameraRollOpt2:(NSURL *)srcURL
{
__block PHAssetChangeRequest *_mChangeRequest = nil;
__block PHObjectPlaceholder *placeholder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
NSData *pngData = [NSData dataWithContentsOfURL:srcURL];
UIImage *image = [UIImage imageWithData:pngData];
_mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
placeholder = _mChangeRequest.placeholderForCreatedAsset;
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
[self loadCameraRollAssetToInstagram:[placeholder localIdentifier]];
}
else {
NSLog(#"write error : %#",error);
[self showAlert:#"Error" msg:#"Error saving in camera roll" action:nil];
}
}];
}
- (void)loadCameraRollAssetToInstagram:(NSString *)localId
{
NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:#"instagram://library?LocalIdentifier=\%#", localId]];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL options:#{} completionHandler:nil];
} else {
[self showAlert:#"Error" msg:#"Instagram app is not installed" action:nil];
}
}
- (NSString*)urlencodedString:(NSString *)message
{
return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
}
Don't forget
#import <Photos/Photos.h>
Add `NSPhotoLibraryUsageDescription` and `QueriesSchemes` inside .plist file
<key>NSPhotoLibraryUsageDescription</key>
<string>Need permission to access to manage your photos library</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
</array>
#borisgolovnev's solution actually works. You can get the localIdentifier of your last saved video using the code below. Passing it with instagram://library?LocalIdentifier=(localID) opens Instagram with your video selected.
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending:false)]
let fetchResult = PHAsset.fetchAssetsWithMediaType(.Video, options: fetchOptions)
if let lastAsset = fetchResult.firstObject as? PHAsset {
self.localIdentifier = lastAsset.localIdentifier
}
use this code
NSURL *instagramURL = [NSURL URLWithString:#"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL])
{
NSURL *videoFilePath = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[request downloadDestinationPath]]]; // Your local path to the video
NSString *caption = #"Some Preloaded Caption";
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:videoFilePath completionBlock:^(NSURL *assetURL, NSError *error) {
NSString *escapedString = [self urlencodedString:videoFilePath.absoluteString];
NSString *escapedCaption = [self urlencodedString:caption];
NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:#"instagram://library?AssetPath=%#&InstagramCaption=%#",escapedString,escapedCaption]];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
}
}];
}
Instagram will only shows those iamges/videos which are saved at path which you set in instagramURL. That path should be absolute.
If it still not shows then add LSApplicationQueriesSchemes in info.plist file of array, add its item0 as instagram.
Replace
- (NSString*)urlencodedString:(NSString *)message{
return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
}
With
- (NSString*)urlencodedString:(NSString *)message{
return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
}
This worked for me!
swift 3 get the latest Identifier simple and fast
var lastIdentifier = ""
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending:false)]
let fetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions)
if let lastAsset: PHAsset = fetchResult.lastObject {
lastIdentifier = lastAsset.localIdentifier
}
Here is code for sharing video on instagram :
May be you need to add condition for substringFromIndex but its working.
- (void)ShareAssetURLvideoToInstagram:(NSURL*)assetsLibraryURL
{
NSMutableDictionary *queryStringDictionary = [[NSMutableDictionary alloc] init];
NSString *strParamater = [assetsLibraryURL.absoluteString substringFromIndex:[assetsLibraryURL.absoluteString rangeOfString:#"?"].location+1];
NSArray *urlComponents = [strParamater componentsSeparatedByString:#"&"];
for (NSString *keyValuePair in urlComponents)
{
NSArray *pairComponents = [keyValuePair componentsSeparatedByString:#"="];
NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];
[queryStringDictionary setObject:value forKey:key];
}
NSString *mediaId = [queryStringDictionary valueForKey:#"id"];
if (mediaId.length > 0) {
NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:#"instagram://library?LocalIdentifier=%#",mediaId]];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
}
}
}
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
NSLog(#"Open Instagram!!"); //enter code here
[[UIApplication sharedApplication/*<enter your code here>*/] openURL:instagramURL];
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 ?
...
}
];
}
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;
}];
}
}];
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.
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
}
}
})
})
}
}
Swift 4 solution that works for me to get the url of last image in Photo Library:
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
let fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions).lastObject
PHImageManager().requestAVAsset(forVideo: fetchResult!, options: nil, resultHandler { (avurlAsset, _, _) in
if let newObj = avurlAsset as? AVURLAsset {
print(newObj.url)
}
})
Hope it helps!
[Swift 4] This method can handle both image and video, enjoy :)
func getURL(of asset: PHAsset, completionHandler : #escaping ((_ responseURL : URL?) -> Void)) {
if asset.mediaType == .image {
let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
return true
}
asset.requestContentEditingInput(with: options, completionHandler: { (contentEditingInput, info) in
completionHandler(contentEditingInput!.fullSizeImageURL)
})
} else if asset.mediaType == .video {
let options: PHVideoRequestOptions = PHVideoRequestOptions()
options.version = .original
PHImageManager.default().requestAVAsset(forVideo: asset, options: options, resultHandler: { (asset, audioMix, info) in
if let urlAsset = asset as? AVURLAsset {
let localVideoUrl = urlAsset.url
completionHandler(localVideoUrl)
} else {
completionHandler(nil)
}
})
}
}
Retrieve image URL:
- (void)processImage:(UIImage*)image type:(NSString*)mimeType forCallbackId:(NSString*)callbackId
{
__block NSString* localId;
// Add it to the photo library
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
localId = [[assetChangeRequest placeholderForCreatedAsset] localIdentifier];
} completionHandler:^(BOOL success, NSError *err) {
if (!success) {
NSLog(#"Error saving image: %#", [err localizedDescription]);
} 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) {
NSURL *fileUrl = [info objectForKey:#"PHImageFileURLKey"];
if (fileUrl) {
NSLog(#"Image path: %#", [fileUrl relativePath]);
} else {
NSLog(#"Error retrieving image filePath, heres whats available: %#", info);
}
}];
}
}];
}