Which PHAssetCollection to use for saving an image?
Asked Answered
B

2

18

In iOS 8's Photos.framework, I'm trying to save a UIImage to the user's photo library, much in the same way you can long-press an image in Safari and choose the "Save Image". In iOS 7, this would be by just calling ALAssetLibrary's writeImageToSavedPhotosAlbum:metadata:completionBlock.

For iOS 8 we need to pick an asset collection to add a PHAsset to, but I can't figure out which PHAssetCollection is closest to just saving to the user's "camera roll" (even though there isn't one, really, in iOS 8)

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
    newAssetRequest.creationDate = time;
    newAssetRequest.location = location;

    PHObjectPlaceholder *placeholderAsset = newAssetRequest.placeholderForCreatedAsset;

    PHAssetCollectionChangeRequest *addAssetRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:WHICH_ASSET_COLLECTION];
    addAssetRequest addAssets:@[placeholderAsset];

} completionHandler:^(BOOL success, NSError *error) {
    NSLog(@"Success: %d", success);
}];

I tried accessing the "Recently Added" smart album, but it does not allow adding new content to it.

Brewster answered 26/9, 2014 at 18:9 Comment(0)
Z
30

You don't need to mess around with PHAssetCollection. Just add by doing:

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:<#your photo here#>];
    } completionHandler:^(BOOL success, NSError *error) {
        if (success) {
            <#your completion code here#>
        }
        else {
            <#figure out what went wrong#>
        }
    }];
Zinck answered 13/11, 2014 at 17:54 Comment(7)
in completion handler, how do you get the new asset?Apologete
You use @property(nonatomic, strong, readonly) PHObjectPlaceholder *placeholderForCreatedAsset to, according to the docs, "Use this property if you need to reference the asset created by a change request within the same change block. For example, the following code, when included in a photo library change block, creates an asset and then adds it to a collection:" For more information on the Placeholder, I suggest reading the docs on it.Zinck
i already tried placeholder object. The example adds the placeholder object to album change request, but im maintaining an array of assets. Adding placeholder object to array didn't work.Apologete
I would suggest opening a new questions so I can adequately see the issue and respond accordingly.Zinck
nice touch adding placeholder tokens to your sample code!Hyperopia
@SushiGrassJacob - How do I write the metadata to the photo using the PHAssetChangeRequest creationRequestForAssetFromImage. It doesn't seem to have a way to set GPSDictionary or EXIFDictionary.Telangiectasis
@user1191140, please open a new question.Zinck
M
6

Actually in 8.1 the Camera Roll is back. It is the smart album whose subtype is SmartAlbumUserLibrary.

Marris answered 13/11, 2014 at 17:59 Comment(6)
You have done very well, by the way, understanding what a placeholder is for.Marris
I think if he were to try to add it to that ALAssetCollection it would still be readonly and not be able to be added. Just adding it like in my answer will do what he desires.Zinck
@SushiGrassJacob The Camera Roll is writable.Marris
Apparently Swift has SmartAlbumUserLibrary, but the doc for objective-C doesn't show it being present: typedef enum : NSInteger { ... PHAssetCollectionSubtypeSmartAlbumBursts = 207, PHAssetCollectionSubtypeSmartAlbumSlomoVideos = 208, PHAssetCollectionSubtypeAny = NSIntegerMax } PHAssetCollectionSubtype;Austroasiatic
@ToddHoff The docs have not been revised, but that's irrelevant; it's in the header: PHAssetCollectionSubtypeSmartAlbumUserLibrary = 209Marris
Thanks matt. Silly me for thinking the docs were generated from the code :-)Austroasiatic

© 2022 - 2024 — McMap. All rights reserved.