How to delete image from PHAssetCollection? - ios

I have PHAssetCollection in my application which contain all albums of photos app.
Problem is that i can delete images from the All Photos but cant delete images from camera roll,favourites,screenshots etc..
Plz help me to delete from PHAssetCollection.
this is the code i did to delete images.
// Enable the trash button if the asset can be deleted.
BOOL isTrashable = NO;
if (self.assetCollection) {
isTrashable = [self.assetCollection canPerformEditOperation:PHCollectionEditOperationRemoveContent];
}
else {
isTrashable = [self.asset canPerformEditOperation:PHAssetEditOperationDelete];
}
self.trashButton.enabled = isTrashable;
[self updateImage];

reference from Apple developer forum
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest
changeRequestForAssetCollection:self.myAlbum
assets:self.albumAssetsFetchResult];
[request removeAssets:#[asset]];
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished removing asset from the album. %#", (success ? #"Success" : error));
}];
or
// Delete asset from library
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest deleteAssets:#[self.asset]];
} completionHandler:completionHandler];
make sure isTrashable = YES

Comment the above code and set
self.trashbutton.enable=YES;
Images deleted from camera role also deleted from All Photos.

Related

Memory leak when using placeholderForCreatedAsset property in PHAssetChangeRequest

In iOS 10 I start to replace asset-library to PhotoKit to manage image picker. But there is an issue.
The specific step is that app needs system camera and user shot a photo after that the delegate method imagePickerController:didFinishPickingMediaWithInfo: will be called.
Then, here is my code:
UIImage *pickerImage = [[info objectForKey:UIImagePickerControllerOriginalImage] fixOrientation];
PHPhotoLibrary *photoLibrary = [PHPhotoLibrary sharedPhotoLibrary];
__block NSString *localId;
[photoLibrary performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:pickerImage];
localId = [[assetChangeRequest placeholderForCreatedAsset] localIdentifier];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
// to get localIdentifier and reload collectionView
}
}];
line 1 that fixOrientation is a custom category that return UIImage instance.
Only call [PHAssetChangeRequest creationRequestForAssetFromImage:] method performs fine. However, when I want to fetch newly created photo to use [assetChangeRequest placeholderForCreatedAsset] , it shows memory leak and app crash.
Above all, any solution to fetch created photo just moment or other methods to solve that by using Photos Framework?

Add new Asset to a new Asset Collection within one Change Block

After looking into the PHPhotoLibrary Framework, I've been able to successfully create and add new image assets and collections but the issue I've run into is not being able to successfully create a new Asset Collection AND add a new Asset to in within the same change block.
If I create an album as an Asset Collection in one change block, and then on completion, create an image as an Asset in another change block it works as expected. Additionally if I have an album already and query that album, I can add an image as an Asset to that album successfully.
The PHAssetCollectionChangeRequest Class Documentation states:
To add assets to the newly created asset collection or change its title, use the methods listed in Modifying Asset Collections. To reference the newly created asset collection later in the same change block or after the change block completes, use the placeholderForCreatedAssetCollection property to retrieve a placeholder object.
I've either misread it or it doesn't actually have the ability to do as it says - to add assets to a newly created asset collection.
This following code completes "successfully" in the completion handler, but when going into the iOS Photos.app, only the Album is created, with no image added (though the image is added to the camera roll as expected).
The thing that's causing the issue is that a PHObjectPlaceholder can't be used as a PHAssetCollection, so the "reference" they speak of can't be used in this way, so that's the underlying problem I've failed to understand:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create the Asset Creation Request to save the photo to the user's photos - This will add it to the camera roll at the very least
PHAssetChangeRequest *imageCreationRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
// Create the Asset Collection Creation Request to create the new album - This will create the album at the very least
PHAssetCollectionChangeRequest *creationRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:#"New Album"];
PHObjectPlaceholder *collectionPlaceholder = creationRequest.placeholderForCreatedAssetCollection; // Get the placeholder Asset Collection
// Create the Asset Collection Change Request to add the new image Asset to the new album Asset Collection
// Warns about PHObjectPlaceholder* != PHAssetCollection*
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collectionPlaceholder];
[albumChangeRequest addAssets:#[imageCreationRequest.placeholderForCreatedAsset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(#"Saved to iOS Photos after creating album");
}
}];
If it helps, this is the code which works using two change blocks:
__block PHObjectPlaceholder *collectionPlaceholder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create the Asset Collection Creation Request to create the new album - This will create the album at the very least
PHAssetCollectionChangeRequest *creationRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:#"New Album"];
collectionPlaceholder = creationRequest.placeholderForCreatedAssetCollection; // Get the placeholder Asset Collection
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create the Asset Creation Request to save the photo to the user's photos - This will add it to the camera roll at the very least
PHAssetChangeRequest *imageCreationRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
// Get the album collection using the placeholder identifier from the first change block
PHAssetCollection *collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[collectionPlaceholder.localIdentifier] options:nil].firstObject;
// Create the Asset Collection Change Request to add the new image Asset to the new album Asset Collection
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
[albumChangeRequest addAssets:#[imageCreationRequest.placeholderForCreatedAsset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(#"Saved to iOS Photos after creating album");
} else {
NSLog(#"Couldn't save to iOS Photos after creating album (%#)", error.description);
}
}];
}
}];
Have you tried converting the album's placeholder into an album inside the one change request?
PHAssetCollection *collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[collectionPlaceholder.localIdentifier] options:nil].firstObject;
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];

How to save GPS data with a taken photo in ios

I am developing a camera application which can be used to take pictures and save them in a separate album. I used photos framework to save images and now I need to save GPS data (location where the picture is taken) with the picture (may be in metadata). I searched for any method to do this thing using photos framework but I failed, I couldn't find anything related. Any help would be highly appreciated.
This is the peace of code I used to save pictures
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:capturedImage];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:Album options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:Album assets:photosAsset];
[albumChangeRequest addAssets:#[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
}
else
{
}
}];
I assume you want the latitude & longitude. Have you tried the location property of PHAsset class?

delete one video from asset or album

How can delete one video from asset/album in iOS8
When I use UIImagePickerController for purpose of selection
then I select one Video from asset/album
in Info Dictionary I got response on didFinishPickingMediaWithInfo method
{
UIImagePickerControllerMediaType = "public.movie";
UIImagePickerControllerMediaURL = "file:///Users/appaspect2/Library/Developer/CoreSimulator/Devices/A61DFE3B-8BA0-4A18-939A-2B0BC2F6084E/data/Containers/Data/Application/69E55783-CB4F-4620-9C81-B3948F5A843B/tmp/trim.1202C1FA-6130-4BC7-AA31-391CC7E0D7B6.MOV";
UIImagePickerControllerReferenceURL = "assets-library://asset/asset.MOV?id=189B68BD-17D0-4665-A065-11A40B0F2B25&ext=MOV";
}
I want to delete file this file which is select in UIImagePickerControllerReferenceURL or asset/album video
AssestsLibrary do not have any such method. But after searching about this I found in ios8 deleting photos might be possible using the Photos Framework
Check the documentation of Photos Framework
For deleting assets refer to PHAssetChangeRequest
+ (void)deleteAssets:(id<NSFastEnumeration>)assets
Finally so much effort I am enable to delete file of asset/album video for iOS8 Only.
You can add this in didFinishPickingMediaWithInfo Method
PHFetchResult *asset = [[PHAsset fetchAssetsWithALAssetURLs:#[info[#"UIImagePickerControllerReferenceURL"]] options:nil] firstObject];
NSLog(#"asset %#",asset);
[self toggleFavoriteForAsset:(PHAsset *)asset];
and Add One Method For Delete Asset Video
- (void)toggleFavoriteForAsset:(PHAsset *)asset {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create a change request from the asset to be modified.
BOOL req = [asset canPerformEditOperation:PHAssetEditOperationDelete];
if (req) {
NSLog(#"true");
[PHAssetChangeRequest deleteAssets:#[asset]];
}
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished Delete asset. %#", (success ? #"Success." : error));
}];
}

Setting the location property of PHAssetChangeRequest doesn't create a GPS section in image metatdata

When a picture is taken (iOS 8.1) and didFinishPickingMediaWithInfo is called, I'm trying to use PhotoKit to add the GPS data back into the metadata.
This is the code I'm using:
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
newAssetRequest.creationDate = [NSDate date];
newAssetRequest.location = [self deviceLocation];
NSLog(#"didFinishPickingMediaWithInfo: location:%#", newAssetRequest.location);
PHObjectPlaceholder *placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
PHAssetCollectionChangeRequest *addAssetRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.myResults[0]];
[addAssetRequest addAssets:#[placeholderAsset]];
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"didFinishPickingMediaWithInfo: Success saving picture to album");
} else {
NSLog(#"didFinishPickingMediaWithInfo: error saving picture to album %#", error);
}
}];
[picker dismissViewControllerAnimated:YES completion:nil];
The code takes the image and moves it to an album. This part works. The photo ends up in the correct album.
The problem is the GPS data is not present in the metadata even though the location property is properly set. I know the location data is valid.
Shouldn't this work? Is there an alternate approach to get the desired result? I don't really care about all the other metadata, just the GPS coordinates.

Resources