Having studied the structure of PHPhotoLibrary, I was able to successfully create and add new objects and collections of images, but the problem I encountered could not successfully create a new collection of assets and add a new Asset for within the same block of changes.
If I create an album as a collection of assets in one change block, and then at the end create an image as an object in another change block, it will work as expected. In addition, if I already have an album and a request for this album, I can add the image as an Asset for this album successfully.
The documentation for the PHAssetCollectionChangeRequest class states:
To add assets to a newly created asset collection or change its title, use the methods listed in the "Modifying Asset Collections" section. To reference a newly created asset collection later in the same change block or after the change block is completed, use the placeholderForCreatedAssetCollection property to retrieve the placeholder object.
I either read it incorrectly, or really have no way to do what he says - to add assets to the newly created collection of assets.
This following code completes “successfully” in the completion handler, but when you enter iOS Photos.app, only an album is created, without adding an image (although the image is added to the camera frame as expected).
, , , PHObjectPlaceholder PHAssetCollection, "", , , ,
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *imageCreationRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
PHAssetCollectionChangeRequest *creationRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"New Album"];
PHObjectPlaceholder *collectionPlaceholder = creationRequest.placeholderForCreatedAssetCollection;
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");
}
}];
, , :
__block PHObjectPlaceholder *collectionPlaceholder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *creationRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"New Album"];
collectionPlaceholder = creationRequest.placeholderForCreatedAssetCollection;
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *imageCreationRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
PHAssetCollection *collection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionPlaceholder.localIdentifier] options:nil].firstObject;
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);
}
}];
}
}];