Swift 3 — получить все фотографии из библиотеки

Я пытался получить фотографии из библиотеки. Работает, но у меня только 3 фото из 9 фото из библиотеки. Вот мой код:

let options = PHFetchOptions()
    let userAlbums = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.album, subtype: PHAssetCollectionSubtype.any, options: options)

    let userPhotos = PHAsset.fetchKeyAssets(in: userAlbums.firstObject!, options: nil)
    let imageManager = PHCachingImageManager()

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

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

            let options = PHImageRequestOptions()
            options.deliveryMode = .fastFormat
            options.isSynchronous = true

            imageManager.requestImage(for: obj, targetSize: CGSize(width: obj.pixelWidth, height: obj.pixelHeight), contentMode: .aspectFill, options: options, resultHandler: { img, info in

                self.images.append(img!)
            })
        }
    })

Когда я попробовал images.count, он сказал 3. Может ли кто-нибудь помочь мне найти мою ошибку и получить все фотографии? Большое спасибо!


person cath    schedule 20.03.2018    source источник
comment
попробуйте использовать DKImagepickercontrolller сторонний API   -  person Raghav Chopra    schedule 20.03.2018
comment
вам необходимо сначала убедиться, что у вас есть права доступа к фотографиям.   -  person MRizwan33    schedule 20.03.2018


Ответы (3)


Попробуй это,

первые импортные фотографии

import Photos

затем объявите массив для хранения фотографий перед viewDidLoad()

var allPhotos : PHFetchResult<PHAsset>? = nil

Теперь напишите код для загрузки фото в viewDidLoad().

    /// Load Photos
    PHPhotoLibrary.requestAuthorization { (status) in
        switch status {
        case .authorized:
            print("Good to proceed")
            let fetchOptions = PHFetchOptions()
            self.allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
        case .denied, .restricted:
            print("Not allowed")
        case .notDetermined:
            print("Not determined yet")
        }
    }

Теперь напишите этот код для отображения изображения из массива

/// Display Photo
let asset = allPhotos?.object(at: indexPath.row)
self.imageview.fetchImage(asset: asset!, contentMode: .aspectFit, targetSize: self.imageview.frame.size) 


// Or Display image in Collection View cell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as! SelectPhotoCell

    let asset = allPhotos?.object(at: indexPath.row)
    cell.imgPicture.fetchImage(asset: asset!, contentMode: .aspectFit, targetSize: cell.imgPicture.frame.size)

    return cell
}

extension UIImageView{
 func fetchImage(asset: PHAsset, contentMode: PHImageContentMode, targetSize: CGSize) {
    let options = PHImageRequestOptions()
    options.version = .original
    PHImageManager.default().requestImage(for: asset, targetSize: targetSize, contentMode: contentMode, options: options) { image, _ in
        guard let image = image else { return }
        switch contentMode {
        case .aspectFill:
            self.contentMode = .scaleAspectFill
        case .aspectFit:
            self.contentMode = .scaleAspectFit
        }
        self.image = image
    }
   }
}
person Sapana Ranipa    schedule 20.03.2018
comment
что такое self.imageview ?? - person cath; 21.03.2018
comment
self.imageview - это ваш imageView, где вам нужно отображать изображение, например, как изображение профиля, в списке tableview. - person Sapana Ranipa; 21.03.2018
comment
Вы хотите отобразить в виде коллекции, верно? тогда у вас есть imageView в ячейке представления коллекции, верно? - person Sapana Ranipa; 21.03.2018
comment
Будет ли этот код работать и с изображениями iCloud? - person Amalendu Kar; 04.02.2019
comment
Это отлично работает, но когда мне нужно получить исходный размер изображения, время ожидания занимает слишком много времени. Есть ли у вас какие-либо предложения по быстрой загрузке и исходному размеру изображения? - person Esat kemal Ekren; 24.07.2020

Swift 5 – обновление

Первые импортные фотографии

Import Photos

Создайте переменную для хранения всех изображений

var images = [UIImage]()

Основная функция для захвата активов и запроса изображения из актива

fileprivate func getPhotos() {

    let manager = PHImageManager.default()
    let requestOptions = PHImageRequestOptions()
    requestOptions.isSynchronous = false
    requestOptions.deliveryMode = .highQualityFormat
    // .highQualityFormat will return better quality photos
    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

    let results: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    if results.count > 0 {
        for i in 0..<results.count {
            let asset = results.object(at: i)
            let size = CGSize(width: 700, height: 700)
            manager.requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: requestOptions) { (image, _) in
                if let image = image {
                    self.images.append(image)
                    self.collectionView.reloadData()
                } else {
                    print("error asset to image")
                }
            }
        }
    } else {
        print("no photos to display")
    }

}
person Toto    schedule 22.01.2020
comment
добавление объяснения к вашему ответу будет полезно - person RamPrakash; 22.01.2020
comment
Работает отлично, но после получения изображения 3400 из моей библиотеки приложение вылетает из-за этой ошибки: Сообщение от отладчика: завершено из-за проблемы с памятью. Как я могу обработать предупреждение о памяти? - person Ömer Karaca; 17.04.2021

Сначала проверьте в info.plist, что вашему приложению разрешен доступ к фотографиям из библиотеки. чем Используйте приведенный ниже код для доступа ко всем фотографиям:

PHPhotoLibrary.requestAuthorization { (status) in
        switch status {
        case .authorized:
            print("You Are Authrized To Access")
            let fetchOptions = PHFetchOptions()
            let allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
            print("Found number of:  \(allPhotos.count) images")
        case .denied, .restricted:
            print("Not allowed")
        case .notDetermined:
            print("Not determined yet")
        }
    }
person MRizwan33    schedule 20.03.2018
comment
@cathrinnatalia Ваш вопрос о том, как получить фотографии из библиотеки. Пожалуйста, не расширяйте свой вопрос. - person TheTiger; 21.03.2018
comment
расширьте область действия переменной allPhotos, взяв ее сверху и внутри класса, а затем отсчитайте от нее и используйте ее в представлении коллекции. но этот метод должен быть в viewDidLoad. - person MRizwan33; 21.03.2018