timateAssetCount возвращает неправильное количество

Мне нужно отобразить альбом фотографий с количеством изображений в нем. Я использую код ниже, чтобы получить альбом с фотографиями.

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

У меня в приложении "Фотоснимок" только 28 изображений. Но estimatedAssetCount свойство возвращает значение 9223372036854775807!

Это происходит только для альбомов, созданных ОС, таких как фотоаппарат. Для созданных пользователем обычных альбомов возвращается правильное значение. Я делаю что-то не так или это ошибка?

Если это так, есть ли другой способ получить правильное количество изображений?

2 ответа

Решение

Должен был выглядеть немного дольше. Переход к заголовку файла PHAssetCollection раскрывает этот маленький кусочек информации.

Эти подсчеты являются лишь оценками; фактическое количество объектов, возвращаемых из выборки, должно использоваться, если вы заботитесь о точности. Возвращает NSNotFound, если счет не может быть быстро возвращен.

Поэтому я предполагаю, что это ожидаемое поведение, а не ошибка. Поэтому я добавил этот метод расширения ниже, чтобы получить правильный счетчик изображений, и он работает.

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
    }
}

9223372036854775807 это значение NSNotFound на некоторых системах. Документация для PHAssetCollection упоминает, что он может вернуться NSNotFound когда счет не может быть возвращен.

Если вы хотите прибегать к извлечению только в случае необходимости, вам следует проверить 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)
}

Ответ @Isuru слегка изменен для 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
    }
}
Другие вопросы по тегам