I'm working on an iOS app in which I need gallery view like Instagram. I have added gallery View, camera View and video View, after taking image it saves to custom album of Photos. Now I want to retrieve those images from custom album and show it to Collection view of Gallery. But I'm getting stuck in retrieving those images from custom album. Any help will be appreciated.
Edit:
I added the PHPhotoLibrary for creating custom photo album, before this I added AssetsLibrary framework.
An Then I created a NSObject class (CustomAlbum) for creating and managing the custom photo album using PHPhotoLibrary.
// CustomAlbum.h
#import <Foundation/Foundation.h>
#import <Photos/Photos.h>
#interface CustomAlbum : NSObject
//Creating album with given name
+(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError;
//Get the album by name
+(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName;
//Add a image
+(void)addNewAssetWithImage:(UIImage *)image toAlbum:(PHAssetCollection *)album onSuccess:(void(^)(NSString *ImageId))onSuccess onError: (void(^)(NSError * error)) onError;
//get the image using identifier
+ (void)getImageWithIdentifier:(NSString*)imageId onSuccess:(void(^)(UIImage *image))onSuccess onError: (void(^)(NSError * error)) onError;
#end
// CustomAlbum.m
#import "CustomAlbum.h"
#implementation CustomAlbum
#pragma mark - PHPhoto
+(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError
{
//Check weather the album already exist or not
if (![self getMyAlbumWithName:title]) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request editing the album.
PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection];
if (placeHolder) {
onSuccess(placeHolder.localIdentifier);
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
if (error) {
onError(error);
}
}];
}
}
+(void)addNewAssetWithImage:(UIImage *)image toAlbum:(PHAssetCollection *)album onSuccess:(void(^)(NSString *ImageId))onSuccess onError: (void(^)(NSError * error)) onError
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request creating an asset from the image.
PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
// Request editing the album.
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset];
[albumChangeRequest addAssets:#[ placeHolder ]];
NSLog(#"%#",placeHolder.localIdentifier);
if (placeHolder) {
onSuccess(placeHolder.localIdentifier);
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
if (error) {
onError(error);
}
}];
}
+(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName
{
#if 0
NSString * identifier = [[NSUserDefaults standardUserDefaults]objectForKey:kAlbumIdentifier];
if (!identifier) return nil;
PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[identifier]
options:nil];
#else
PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAlbumRegular
options:nil];
#endif
NSLog(#"assetCollections.count = %lu", assetCollections.count);
if (assetCollections.count == 0) return nil;
__block PHAssetCollection * myAlbum;
[assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) {
NSLog(#"album:%#", album);
NSLog(#"album.localizedTitle:%#", album.localizedTitle);
if ([album.localizedTitle isEqualToString:AlbumName]) {
myAlbum = album;
*stop = YES;
}
}];
if (!myAlbum) return nil;
return myAlbum;
}
+(NSArray *)getAssets:(PHFetchResult *)fetch
{
__block NSMutableArray * assetArray = NSMutableArray.new;
[fetch enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) {
NSLog(#"asset:%#", asset);
[assetArray addObject:asset];
}];
return assetArray;
}
+ (void)getImageWithIdentifier:(NSString*)imageId onSuccess:(void(^)(UIImage *image))onSuccess onError: (void(^)(NSError * error)) onError
{
NSError *error = [[NSError alloc] init];
PHFetchResult *assets = [PHAsset fetchAssetsWithLocalIdentifiers:#[imageId] options:nil];
if (assets.count == 0) onError(error);
NSArray * assetArray = [self getAssets:assets];
PHImageManager *manager = [PHImageManager defaultManager];
CGRect screenRect = [[UIScreen mainScreen] bounds];
[manager requestImageForAsset:assetArray.firstObject targetSize:screenRect.size contentMode:PHImageContentModeAspectFit options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
onSuccess(result);
}];
}
#end
And then use this method on take Image Button click to create custom album and save images in that custom album.
// Take Image Button Method
- (void)snapButtonPressed:(UIButton *)button
{
[self.camera capture:^(LLSimpleCamera *camera, UIImage *image,
NSDictionary *metadata, NSError *error)
{
if(!error)
{
NSString * info = [NSString stringWithFormat:#"Size: %# - Orientation: %ld", NSStringFromCGSize(image.size), (long)image.imageOrientation];
[CustomAlbum addNewAssetWithImage:image toAlbum:[CustomAlbum getMyAlbumWithName:CSAlbum] onSuccess:^(NSString *ImageId) {
NSLog(#"%#",ImageId);
recentImg = ImageId;
} onError:^(NSError *error) {
NSLog(#"probelm in saving image");
}];
}
else
{
NSLog(#"An error has occured: %#", error);
}
}
exactSeenImage:YES];
}
Here is the code that works.
__block PHAssetCollection *collection;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", #"YOUR_CUSTOM_ALBUM_NAME"];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
PHFetchResult *collectionResult = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
[collectionResult enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) {
//add assets to an array for later use in the uicollectionviewcell
}];
Just try once this code.. You can get all images in one array using this code:-
-(void)getAllPictures
{
__block PHAssetCollection *collection;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", #"YOUR_CUSTOM_ALBUM_NAME"];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
PHFetchResult *collectionResult = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
NSMutableArray *assets = [[NSMutableArray alloc] init];
[collectionResult enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) {
[assets addObject:asset];
}];
PHImageRequestOptions * requestOptions = [[PHImageRequestOptions alloc] init];
//requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
//requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
// this one is key
//requestOptions.synchronous = true;
PHImageManager *manager = [PHImageManager defaultManager];
NSMutableArray *images = [NSMutableArray arrayWithCapacity:[assets count]];
// assets contains PHAsset objects.
__block UIImage *ima;
for (PHAsset *asset in assets) {
// Do something with the asset
[manager requestImageForAsset:asset
targetSize:PHImageManagerMaximumSize//CGSizeMake(300, 300)
contentMode:PHImageContentModeDefault
options:requestOptions
resultHandler:^void(UIImage *image, NSDictionary *info) {
ima = image;
[images addObject:ima];
}];
}
NSLog(#"images %#", images); //You will get all images into this images array.
}
For more details, Please refer Example app using Photos framework.
Hope, this is what you're looking for. Any concern get back to me. :)
Related
I am trying to delete a photo from the photo gallery of the phone, but the deleted image was in the deleted directory, there is a way to delete the picture which is in the deleted directory of the phone?
There is my code :
-(void)deleteCaptureProcess{
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) {
NSLog(#"¨PATH %#",contentEditingInput.fullSizeImageURL);
NSArray *lines = [[NSString stringWithFormat:#"%#", contentEditingInput.fullSizeImageURL] componentsSeparatedByString: #"/"];
NSString *imageNZma = lines[[lines count]-1];
NSMutableArray *persons = [[NSMutableArray alloc]initWithCapacity:0];
[persons addObject:contentEditingInput.fullSizeImageURL];
__block PHAssetCollection *albumCollection = [[PHAssetCollection alloc] init];
PHFetchOptions *albumOptions = [[PHFetchOptions alloc] init];
[albumOptions setPredicate:[NSPredicate predicateWithFormat:#"estimatedAssetCount >= 0"]];
NSLog(#"%#",albumOptions);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request creating an asset from the image.
PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[UIImage imageNamed:imageNZma]];
// Request editing the album.
PHAssetCollectionChangeRequest* albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:albumCollection];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder* assetPlaceholder = [createAssetRequest placeholderForCreatedAsset]; [albumChangeRequest addAssets:#[ assetPlaceholder ]];
} completionHandler:^(BOOL success, NSError* error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
}];
__block PHObjectPlaceholder *assetPlaceholder = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest * request = [PHAssetChangeRequest creationRequestForAssetFromImage: [UIImage imageNamed:imageNZma]];
assetPlaceholder = request.placeholderForCreatedAsset;
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"creation success %d - error: %# - place: %#", success, error, assetPlaceholder);
PHFetchResult * result = [PHAsset fetchAssetsWithLocalIdentifiers: #[assetPlaceholder.localIdentifier] options: nil];
NSLog(#"Asset fetching: %#", result);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges: ^{
[PHAssetChangeRequest deleteAssets: #[asset]];
} completionHandler:^(BOOL success, NSError *error) {
// NSLog(#"deletion success %d - error: %# - place: %#", success, error, assetPlaceholder);
}];
}];
}
}];
}
}
So my question is : there is a way to delete directly the image from the deleted folder after the image in gallery was deleted ?
Thank for help
In my app I used edit pic and saved in custom folder in Gallery called "Fab". now is there anything to delete that image from folder? I have found different solution but they require asset URL. I used Photos framework so how to get asset url for particular image for deletion ?
PHAsset *tempPhasset = [_arrImageForAssetCameraRoll objectAtIndex:index]; // here pass your PHasset that you want to delete .
NSString *localStr=tempPhasset.localIdentifier;
NSRange range = [localStr rangeOfString:#"/"];
NSString *newString = [localStr substringToIndex:range.location];
NSString *appendedString=[NSString stringWithFormat:#"%#%#%#",#"assets-library://asset/asset.JPG?id=",newString,#"&ext=JPG"];
NSLog(#"%# phasset ",appendedString);
NSURL *deleteurl = [NSURL URLWithString:appendedString];
NSArray *arrDelete = [[NSArray alloc] initWithObjects:deleteurl , nil];
PHFetchResult *asset = [PHAsset fetchAssetsWithALAssetURLs:arrDelete options:nil];
[asset enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"%#",[obj class]);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
BOOL req = [obj canPerformEditOperation:PHAssetEditOperationDelete];
if (req) {
NSLog(#"true");
[PHAssetChangeRequest deleteAssets:#[obj]];
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished Delete asset. %#", (success ? #"Success." : error));
if (success) {
NSLog(#"delete successfully");
}else{
NSLog(#"delete Cancel");
}
}];
Any query about my code then put comment .
Happy Coding.
Try this below code
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[viewImage CGImage] orientation:(ALAssetOrientation)[viewImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"error");
} else {
NSLog(#"url %#", assetURL);
}
}];
will return url for saved image.
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'm using Photos.Framework to save photos taken from the camera into my gallery and to retrieve them.
This is the code I'm using to store the photos:
__block PHAssetCollection *album = [self getMyAlbumWithName:#"MyAlbumName"];
if(album == nil)
{
[self makeAlbumWithTitle:#"MyAlbumName" onSuccess:^(NSString *AlbumId) {
album = [self getMyAlbumWithName:#"MyAlbumName"];
[self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId)
{
_imageLocalIdentifier = imageId;
} onError:^(NSError *error) {
// No need to do anything
}];
} onError:^(NSError *error) {
// No need to do anything
}];
}
else
{
[self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId)
{
_imageLocalIdentifier = imageId;
} onError:^(NSError *error) {
// No need to do anything
}];
}
-(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName
{
PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAlbumRegular
options:nil];
NSLog(#"assetCollections.count = %lu", assetCollections.count);
if (assetCollections.count == 0) return nil;
__block PHAssetCollection * myAlbum;
[assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) {
NSLog(#"album:%#", album);
NSLog(#"album.localizedTitle:%#", album.localizedTitle);
if ([album.localizedTitle isEqualToString:AlbumName]) {
myAlbum = album;
*stop = YES;
}
}];
if (!myAlbum) return nil;
return myAlbum;
}
-(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError
{
//Check weather the album already exist or not
if (![self getMyAlbumWithName:title])
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request editing the album.
PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection];
if (placeHolder)
{
onSuccess(placeHolder.localIdentifier);
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
if (error)
{
onError(error);
}
}];
}
}
-(void)addNewAssetWithImage:(UIImage *)image
toAlbum:(PHAssetCollection *)album
onSuccess:(void(^)(NSString *ImageId))onSuccess
onError: (void(^)(NSError * error)) onError
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request creating an asset from the image.
PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
// Request editing the album.
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset];
[albumChangeRequest addAssets:#[ placeHolder ]];
NSLog(#"%#",placeHolder.localIdentifier);
if (placeHolder) {
onSuccess(placeHolder.localIdentifier);
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
if (error) {
onError(error);
}
}];
}
And this is the code I'm using to retrieve this photo:
PHImageManager *imgManager = [[PHImageManager alloc] init];
PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:#[_imageLocalIdentifier] options:nil];
if([fetchResult count] > 0)
{
PHAsset *asset = [fetchResult objectAtIndex:0];
PHImageRequestOptions *option = [PHImageRequestOptions new];
option.synchronous = NO;
option.version = PHImageRequestOptionsVersionCurrent;
option.networkAccessAllowed = YES;
option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
option.resizeMode = PHImageRequestOptionsResizeModeFast;
[imgManager requestImageForAsset:asset
targetSize:CGSizeMake(CAMERA_GALLERY_SIZE, CAMERA_GALLERY_SIZE)
contentMode:PHImageContentModeDefault
options:option
resultHandler:^(UIImage *result, NSDictionary *info) {
[cell.photoIV setImage:result];
}];
}
With this piece of code, over a sample of 12 photos stored (they are ok in my album) 4 or 5 of their localidentifiers returns an empty fetch results.
This is tested in iOS 8, iOS 9 and iOS 10 (with iOS 10 it's indeed worse because almost all of the fetch results are empty).
I've read that something similar to this was a bug in previous versions of iOS, but I guess this is not the reason now.
I've tried with this method to retrieve the photos:
- (PHAsset *)getAssetFromGallery:(NSString *)identifier
{
PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:#[identifier] options:nil].lastObject;
if(asset != nil)
return asset;
__block PHAsset *result;
PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
[fetchOptions setPredicate:[NSPredicate predicateWithFormat:#"localIdentifier == %#", identifier]];
[userAlbums enumerateObjectsUsingBlock:^(id _Nonnull objectCollection, NSUInteger idx, BOOL * _Nonnull stopCollectionEnumeration) {
PHAssetCollection *collection = nil;
if(![objectCollection isKindOfClass:[PHAssetCollection class]])
return;
collection = (PHAssetCollection *)objectCollection;
PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
[assetsFetchResult enumerateObjectsUsingBlock:^(id _Nonnull objectAsset, NSUInteger idx, BOOL * _Nonnull stopAssetEnumeration) {
PHAsset *asset = nil;
if(![objectAsset isKindOfClass:[PHAsset class]])
return;
result = asset;
*stopAssetEnumeration = YES;
*stopCollectionEnumeration = YES;
}];
}];
return asset;
}
I've tried with PHAssetCollectionSubtypeAlbumMyPhotoStream instead of PHAssetCollectionSubtypeAny.
And I've tried with #"localIdentifier ==[cd] %#" instead of #"localIdentifier == %#".
And always the same results, lots of times the fetch results is empty.
Any idea of what is it happening?
My problem was that I wasn't saving the photos in the right way, I was calling onSuccess(placeHolder.localIdentifier); inside the performChanges block instead of inside the completionHandler block.
This is the code I'm using now to save the photos:
__block PHAssetCollection *album = [AuxiliaryFunctions getMyAlbumWithName:#"MyAlbumName" orWithIdentifier:#""];
if(album == nil)
[self makeAlbumWithTitle:#"MyAlbumName" onSuccess:^(NSString *AlbumId) {
album = [self getMyAlbumWithName:#"MyAlbumName" orWithIdentifier:AlbumId];
[self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId)
{
_imageLocalIdentifier = imageId;
} onError:^(NSError *error) {
// No need to do anything
}];
} onError:^(NSError *error) {
// No need to do anything
}];
else
{
[self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId)
{
_imageLocalIdentifier = imageId;
} onError:^(NSError *error) {
// No need to do anything
}];
}
-(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName orWithIdentifier:(NSString *)identifier
{
PHFetchResult *assetCollections = nil;
if(![identifier isEqualToString:#""])
{
PHFetchOptions *options = [PHFetchOptions new];
options.predicate = [NSPredicate predicateWithFormat:#"localIdentifier = %# OR title = %#", identifier, AlbumName];
assetCollections = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[identifier]
options:options];
}
else
{
PHFetchOptions *options = [PHFetchOptions new];
options.predicate = [NSPredicate predicateWithFormat:#"title = %#", AlbumName];
assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:options];
}
NSLog(#"assetCollections.count = %lu", assetCollections.count);
if (assetCollections.count == 0) return nil;
__block PHAssetCollection * myAlbum;
[assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) {
NSLog(#"album:%#", album);
NSLog(#"album.localizedTitle:%#", album.localizedTitle);
if ([album.localizedTitle isEqualToString:AlbumName]) {
myAlbum = album;
*stop = YES;
}
}];
if (!myAlbum) return nil;
return myAlbum;
}
-(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError
{
__block NSString *localIdentifier = #"";
//Check weather the album already exist or not
if (![self getMyAlbumWithName:title orWithIdentifier:#""])
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request editing the album.
PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection];
if (placeHolder)
{
localIdentifier = placeHolder.localIdentifier;
// This line was the problem
//onSuccess(localIdentifier);
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
if(success)
{
onSuccess(localIdentifier);
}
if (error)
{
onError(error);
}
}];
}
}
-(void)addNewAssetWithImage:(UIImage *)image
toAlbum:(PHAssetCollection *)album
onSuccess:(void(^)(NSString *ImageId))onSuccess
onError: (void(^)(NSError * error)) onError
{
__block NSString *localIdentifier = #"";
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request creating an asset from the image.
PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
// Request editing the album.
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset];
[albumChangeRequest addAssets:#[ placeHolder ]];
NSLog(#"%#",placeHolder.localIdentifier);
if (placeHolder) {
localIdentifier = placeHolder.localIdentifier;
// This line was the problem
//onSuccess(localIdentifier);
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
if(success)
{
onSuccess(localIdentifier);
}
if (error)
{
onError(error);
}
}];
}
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