How to fetch album poster image using Photo Kit?

bhoomi picture bhoomi · Jan 27, 2015 · Viewed 9.3k times · Source

When using Assets Library you could fetch the album's poster image from ALAssetsGroup. How do you achieve the same when using Photos Framework (Photo kit)?

Answer

jarora picture jarora · May 25, 2015

I do it this way. In the method cellForRowAtIndexPath: in albums tableView add the following code.

Objective C:

    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
    fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
    PHFetchResult *fetchResult = [PHAsset fetchKeyAssetsInAssetCollection:[self.assetCollections objectAtIndex:indexPath.row] options:fetchOptions];
        PHAsset *asset = [fetchResult firstObject];
        PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
        options.resizeMode = PHImageRequestOptionsResizeModeExact;

        CGFloat scale = [UIScreen mainScreen].scale;
        CGFloat dimension = 78.0f;
        CGSize size = CGSizeMake(dimension*scale, dimension*scale);

        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *result, NSDictionary *info) {
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = result;
        });

        }];

Swift 3:

let fetchOptions = PHFetchOptions()
let descriptor = NSSortDescriptor(key: "creationDate", ascending: true)
fetchOptions.sortDescriptors = [descriptor]

let fetchResult = PHAsset.fetchKeyAssets(in: assets[indexPath.row], options: fetchOptions)

guard let asset = fetchResult?.firstObject else {
    return
}

let options = PHImageRequestOptions()
options.resizeMode = .exact

let scale = UIScreen.main.scale
let dimension = CGFloat(78.0)
let size = CGSize(width: dimension * scale, height: dimension * scale)


PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: options) { (image, info) in
    DispatchQueue.main.async {
        cell.imageView.image = image
    }
}

Edit: Looks like fetchKeyAssetsInAssetCollection does not always return correct results (most recently captured images/videos). The definition of keyAssets is vaguely defined by apple. Better use

+ (PHFetchResult *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(PHFetchOptions *)options

to get the fetch results array and then get the firstObject from the fetch results as described before. This will certainly return the correct results. :)