Быстро получить фотографии из определенного альбома, используя PHAssetCollection.fetchAssetCollectionsWithType()

когда я запускаю выборку фотографий, например:

let assetCollections: PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .Any, options: nil) 

Я получаю результат нескольких альбомов, поэтому я могу перебрать массив и поместить их названия в tableView.

НО: когда я использую предикат для фильтрации и получения, например, альбома «Фотопленка», результатом всегда является пустой массив: (И я на 100% уверен, что Фотопленка существует, потому что с нулевыми параметрами он ее извлекает)

let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %@", "Camera Roll")
let assetCollections: PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .Any, options: fetchOptions)
let album: PHAssetCollection = assetCollections.firstObject as! PHAssetCollection

Я прочитал 4 или 5 различных методов от людей в Интернете, и все они имеют этот предикат, будь то с «title = %@», или «localizedTitle = %@», или «localizedIdentifier = %@»... Я НЕ ПОЛУЧАЮ ЭТО. Кажется, это работает для людей, а не для меня. Компилятор падает на последней строке, пытаясь «развернуть нулевое необязательное значение» («потому что результат выборки пуст). Почему поиск возвращает ноль, как только включает параметры выборки???


person Hikarus    schedule 12.11.2015    source источник


Ответы (4)


Если вы хотите альбом Camera Roll, вам, вероятно, лучше попросить его символически:

let collections = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)

Подтип SmartAlbumUserLibrary — это то, как вы получаете Фотопленку (которая не всегда так называется).

person rickster    schedule 04.12.2015

решение, похоже, заключается в использовании:

PHAssetCollection.fetchAssetCollectionsWithLocalizedIdentifiesr(identifiers: [String], options: PHFetchOptions)

Таким образом, передача в параметр 'identifier' массива строк с названиями альбомов, которые мы хотим получить, приводит к тому же результату, что и попытка метода предиката, который, похоже, больше не работает.

person Hikarus    schedule 17.11.2015
comment
Хотя этот код может ответить на вопрос, было бы лучше объяснить, как он решает проблему, не вводя других, и зачем его использовать. Ответы, содержащие только код, в долгосрочной перспективе бесполезны. - person JAL; 17.11.2015

Если вам нужен только альбом Camera Roll, вы можете попробовать что-то вроде этого:

func getCameraRoll() -> AlbumModel {
      var cameraRollAlbum : AlbumModel!

      let cameraRoll = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil)

      cameraRoll.enumerateObjects({ (object: AnyObject!, count: Int, stop: UnsafeMutablePointer) in
        if object is PHAssetCollection {
          let obj:PHAssetCollection = object as! PHAssetCollection

          let fetchOptions = PHFetchOptions()
          fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
          fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
          let assets = PHAsset.fetchAssets(in: obj, options: fetchOptions)

          if assets.count > 0 {
            let newAlbum = AlbumModel(name: obj.localizedTitle!, count: assets.count, collection:obj, assets: assets)

            cameraRollAlbum = newAlbum
          }
        }
      })
     return cameraRollAlbum

    }

Обратите внимание, что AlbumModel — это модель, которую я создал, вы можете изменить ее и использовать свою собственную модель данных.

person jamesthakid    schedule 10.10.2017
comment
Привет, почему первый отладчик не заходит внутрь cameraRoll.enumerateObjects. - person Coding; 21.02.2020

Попробуйте формат:

fetchOptions.predicate = NSPredicate(format: "%K == %@", "title", "Camera Roll")

or

fetchOptions.predicate = NSPredicate(format: "%K LIKE[cd] %@", "title", "Camera Roll")

person yujean    schedule 03.12.2015