estimatedAssetCount returns a wrong count

3.5k views Asked by At

I need to display the camera roll album with the count of images in it. I'm using the below code to get the camera roll album.

let smartCollections = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)
smartCollections.enumerateObjectsUsingBlock { object, index, stop in
    if let collection = object as? PHAssetCollection {
        print(collection.estimatedAssetCount)
    }
}

I have only 28 images in the camera roll in the Photos app. But the estimatedAssetCount property returns the value 9223372036854775807!

This only happens for OS created albums like the camera roll. For user created regular albums, the correct value is returned. Am I doing anything wrong or is this a bug?

If it is, is there any other way to get the correct image count?

3

There are 3 answers

1
Isuru On BEST ANSWER

Should have looked a little longer. Going in to the header file of PHAssetCollection reveals this little piece of info.

These counts are just estimates; the actual count of objects returned from a fetch should be used if you care about accuracy. Returns NSNotFound if a count cannot be quickly returned.

So I guess this is expected behavior and not a bug. So I added this below extension method to get the correct image count and it works.

extension PHAssetCollection {
    var photosCount: Int {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.Image.rawValue)
        let result = PHAsset.fetchAssetsInAssetCollection(self, options: fetchOptions)
        return result.count
    }
}
0
inket On

9223372036854775807 is the value of NSNotFound on some systems. The documentation for PHAssetCollection mentions that it could return NSNotFound when the count cannot be returned.

If you want to only resort to fetching when necessary, you should check for NSNotFound:

let smartCollections = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)
smartCollections.enumerateObjectsUsingBlock { object, index, stop in
    guard let collection = object as? PHAssetCollection else { return }

    var assetCount = collection.estimatedAssetCount
    if assetCount == NSNotFound {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.Image.rawValue)
        assetCount = PHAsset.fetchAssetsInAssetCollection(collection, options: fetchOptions).count
    }

    print(assetCount)
}
0
fewlinesofcode On

@Isuru's answer slightly modified for Swift 5

extension PHAssetCollection {
    var photosCount: Int {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.image.rawValue)
        let result = PHAsset.fetchAssets(in: self, options: fetchOptions)
        return result.count
    }

    var videoCount: Int {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.video.rawValue)
        let result = PHAsset.fetchAssets(in: self, options: fetchOptions)
        return result.count
    }
}