在 Swift 4 中使用 PHAssetCollection 从特定相册中获取特定照片

Get Specific Photo from Specific Photo Album with PHAssetCollection in Swift 4

我正在使用以下代码存储照片。但是现在我必须使用名称从存储中获取照片。

第一个问题:如何使用名称存储照片?我应该将它存储在 Core Data 中吗?

第二个问题:如何使用我之前给它取的名字得到那张照片?

请帮助我。谢谢大家的回复...

class CustomPhotoAlbum: NSObject {
static let albumName = "PhotoAlbumName"
static let sharedInstance = CustomPhotoAlbum()

var assetCollection: PHAssetCollection!

override init() {
    super.init()

    if let assetCollection = fetchAssetCollectionForAlbum() {
        self.assetCollection = assetCollection
        return
    }

    if PHPhotoLibrary.authorizationStatus() != PHAuthorizationStatus.authorized {
        PHPhotoLibrary.requestAuthorization({ (status: PHAuthorizationStatus) -> Void in
            ()
        })
    }

    if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.authorized {
        self.createAlbum()
    } else {
        PHPhotoLibrary.requestAuthorization(requestAuthorizationHandler)
    }
}

func requestAuthorizationHandler(status: PHAuthorizationStatus) {
    if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.authorized {
        // ideally this ensures the creation of the photo album even if authorization wasn't prompted till after init was done
        print("trying again to create the album")
        self.createAlbum()
    } else {
        print("should really prompt the user to let them know it's failed")
    }
}

func createAlbum() {
    PHPhotoLibrary.shared().performChanges({
        PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: CustomPhotoAlbum.albumName)   // create an asset collection with the album name
    }) { success, error in
        if success {
            self.assetCollection = self.fetchAssetCollectionForAlbum()
        } else {
            print("error \(String(describing: error))")
        }
    }
}

func fetchAssetCollectionForAlbum() -> PHAssetCollection? {
    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "title = %@", CustomPhotoAlbum.albumName)
    let collection = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)

    if let _: AnyObject = collection.firstObject {
        return collection.firstObject
    }
    return nil
}

func save(image: UIImage) {
    if assetCollection == nil {
        return                          // if there was an error upstream, skip the save
    }

    PHPhotoLibrary.shared().performChanges({
        let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
        let assetPlaceHolder = assetChangeRequest.placeholderForCreatedAsset
        let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection)
        let enumeration: NSArray = [assetPlaceHolder!]
        albumChangeRequest!.addAssets(enumeration)

    }, completionHandler: nil)
}

}

你可以使用这个class。

import Foundation
import Photos

class FetchPhotos{

    var images:[UIImage] = []
    var imageUrl:String!

    func fetchPhotos() -> String{
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: false)]

        // Fetch the image assets
        let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)

        // If the fetch result isn't empty,
        // proceed with the image request
        if fetchResult.count > 0 {
            let totalImageCountNeeded = 1 // <-- The number of images to fetch
            fetchPhotoAtIndex(0, totalImageCountNeeded, fetchResult)
        }
        return imageUrl
    }


    // Repeatedly call the following method while incrementing
    // the index until all the photos are fetched
    func fetchPhotoAtIndex(_ index:Int, _ totalImageCountNeeded: Int, _ fetchResult: PHFetchResult<PHAsset>) {

        let albumName = "CustonAlbum"
        // Note that if the request is not set to synchronous
        // the requestImageForAsset will return both the image
        // and thumbnail; by setting synchronous to true it
        // will return just the thumbnail
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = true

        let collection: PHFetchResult = 
PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: nil)
        for k in 0 ..< collection.count {
            let obj:AnyObject! = collection.object(at: k)
            if obj.title == albumName {
                print("Yeap!")

                // Perform the image request
                PHImageManager.default().requestImage(for: fetchResult.object(at: index) as PHAsset, targetSize: CGSize(width: 1000, height: 1000), contentMode: PHImageContentMode.aspectFill, options: requestOptions, resultHandler: { (image, info) in

                    if let image = image {
                        // Add the returned image to your array
                        self.images += [image]
                    }
                    // If you haven't already reached the first
                    // index of the fetch result and if you haven't
                    // already stored all of the images you need,
                    // perform the fetch request again with an
                    // incremented index
                    if index + 1 < fetchResult.count && self.images.count < totalImageCountNeeded {
                        self.fetchPhotoAtIndex(index + 1, totalImageCountNeeded, fetchResult)
                    } else {
                        // Else you have completed creating your array
                        print("Completed array: \(self.images[0])")
                        print("Image URL \(String(describing: info!["PHImageFileURLKey"]))")
                        self.imageUrl = "\(info!["PHImageFileURLKey"]!)"
                    }
                })

            }}
    }


}