Swift 3 - 从图库获取所有照片

19

我试图从图库获取照片。它可以工作,但我只从图库中获得了9张照片中的3张照片。这是我的代码:

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。有人能帮我找到错误并获取所有照片吗?非常感谢!


尝试使用第三方API DKImagepickercontrolller。 - Raghav Chopra
你需要先确保你有权限访问照片。 - MRizwan33
3个回答

34

试试这个,

首先导入照片。

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

self.imageview是您需要显示图像的imageView,例如在tableview列表中的个人资料图片。 - Sapana Ranipa
self.allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions) --> 返回结果为空,你能帮我吗? - trumsuhu
@trumsuhu,你在info.plist文件中添加了照片库访问权限吗? - Sapana Ranipa
@SapanaRanipa 对不起,我的错误,它已经成功加载了,非常感谢您!但是现在,我又遇到了另一个问题,当我从库中加载所有照片(大约3000张照片)时,需要很长时间。有什么建议吗?再次感谢! - trumsuhu
@trumsuhu,如果花费的时间太长,你可以添加加载。 - Sapana Ranipa
显示剩余4条评论

9

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

}

2
添加解释会更有帮助。 - RamPrakash
2
功能完美,但从我的库中获取3400张图像后,应用程序因此错误而崩溃:“来自调试器的消息:由于内存问题终止”。我该如何处理内存警告? - Ömer Karaca

1

首先在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")
        }
    }

@cathrinnatalia,你的问题是关于如何从图库中获取照片。请不要扩大你的问题。 - TheTiger
通过将所有照片变量放在类的顶部并在其中扩展其范围,然后从中计数并在集合视图中使用它来扩展其范围。但是此方法应该在viewDidLoad中。 - MRizwan33

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接