Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetch only PHAssetCollections containing at least one photo

In iOS PhotoKit, I can fetch all non-empty albums like this:

let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "estimatedAssetCount > 0")
let albumFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: albumFetchOptions)

albumFetchResult.enumerateObjects({ (collection, _, _) in
    // Do something with the album...
})

Then I can get only photos from the album like this:

let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetResourceType.photo.rawValue)
let fetchResults = PHAsset.fetchAssets(in: collection, options: fetchOptions)

But the first part can give me albums with only videos, which means that after I apply the predicate to the second part, the album will be empty. Is there a way to filter out those albums in the first part, before I start using them?

like image 960
Phlippie Bosman Avatar asked Jun 28 '17 11:06

Phlippie Bosman


1 Answers

It seems that collections cannot be filtered like this without also fetching the items in the collections. See the docs for available fetch options; none allow filtering by number of a specific type of media.

The way I would achieve this is by fetching all albums created by the user, and then fetching the assets from the albums with a predicate that returns only images.

So to put it in code:

var userCollections: PHFetchResult<PHAssetCollection>!
// Fetching all PHAssetCollections with at least some media in it
let options = PHFetchOptions()
    options.predicate = NSPredicate(format: "estimatedAssetCount > 0")
// Performing the fetch
userCollections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumRegular, options: options)

Next, fetch the assets from a collection that are images by specifying a predicate:

// Getting the specific collection (I assumed to use a tableView)
let collection = userCollections[indexPath.row]
let optionsToFilterImage = PHFetchOptions()
    optionsToFilterImage.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Image.rawValue)
// Fetching the asset with the predicate to filter just images
let justImages = PHAsset.fetchAssets(in: collection, options: optionsToFilterImage)

Lastly, count the number of images:

if justImages.count > 0 {
    // Display it
} else {
    // The album has no images
}
like image 162
Marco Avatar answered Oct 10 '22 03:10

Marco