在自定义相册中创建文件夹

时间:2017-03-30 12:31:27

标签: ios swift phasset

我有一张自定义相册,我的应用可以从相机中保存图片。我想知道是否有一种方法可以在我的相册中创建文件夹,以便我可以在其中堆叠某些图像?

ANSWER

正如其他成员所说,遗憾的是你无法在专辑中创建一个文件夹。

2 个答案:

答案 0 :(得分:4)

您应该尝试下面的代码。它的 Swift 3.0 语法。 :)

import Foundation
import Photos


class CustomPhotoAlbum: NSObject {
    static let albumName = "Album Name"
    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 \(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)
    }
}

答案 1 :(得分:1)

您可以在用户的​​相册中的文件夹内添加相册。今天,我刚刚想出了方法:

import Photos

class PhotoManager {
    static let instance = PhotoManager()
    var folder: PHCollectionList?

    /// Fetches an existing folder with the specified identifier or creates one with the specified name
    func fetchFolderWithIdentifier(_ identifier: String, name: String) {
        let fetchResult = PHCollectionList.fetchCollectionLists(withLocalIdentifiers: [identifier], options: nil)
        guard let folder = fetchResult.firstObject else {
            createFolderWithName(name)
            return
        }

        self.folder = folder
    }

    /// Creates a folder with the specified name
    private func createFolderWithName(_ name: String) {
        var placeholder: PHObjectPlaceholder?

        PHPhotoLibrary.shared().performChanges({
            let changeRequest = PHCollectionListChangeRequest.creationRequestForCollectionList(withTitle: name)
            placeholder = changeRequest.placeholderForCreatedCollectionList
        }) { (success, error) in
            guard let placeholder = placeholder else { return }
            let fetchResult = PHCollectionList.fetchCollectionLists(withLocalIdentifiers: [placeholder.localIdentifier], options: nil)
            guard let folder = fetchResult.firstObject else { return }

            self.folder = folder
        }
    }

    /// Creates an album with the specified name
    private func createAlbumWithName(_ name: String, completion: @escaping (PHAssetCollection?) -> Void) {
        guard let folder = folder else {
            completion(nil)
            return
        }

        var placeholder: PHObjectPlaceholder?
        PHPhotoLibrary.shared().performChanges({
            let listRequest = PHCollectionListChangeRequest(for: folder)
            let createAlbumRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: name)
            listRequest?.addChildCollections([createAlbumRequest.placeholderForCreatedAssetCollection] as NSArray)
            placeholder = createAlbumRequest.placeholderForCreatedAssetCollection
        }) { (success, error) in
            guard let placeholder = placeholder else {
                completion(nil)
                return
            }

            let fetchResult = PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: [placeholder.localIdentifier], options: nil)
            let album = fetchResult.firstObject
            completion(album)
        }
    }

    /// Saves the image to a new album with the specified name
    func saveImageToAlbumInRootFolder(_ albumName: String, image: UIImage?, completion: @escaping (Error?) -> Void) {
        createAlbumWithName(albumName) { (album) in
            guard let album = album else {
                return
            }

            PHPhotoLibrary.shared().performChanges({
                let albumChangeRequest = PHAssetCollectionChangeRequest(for: album)
                let createAssetRequest = PHAssetChangeRequest.creationRequestForAsset(from: image!)
                let photoPlaceholder = createAssetRequest.placeholderForCreatedAsset!
                albumChangeRequest?.addAssets([photoPlaceholder] as NSArray)
            }, completionHandler: { (success, error) in
                if success {
                    completion(nil)
                } else if let error = error {
                    // Failed with error
                } else {
                    // Failed with no error
                }
            })
        }
    }
}

这允许您执行以下操作:

let defaults = UserDefaults.standard
let identifier = defaults.string(forKey: "myFolder")!
PhotoManager.instance.fetchFolderWithIdentifier(identifier, name: "My Folder")
PhotoManager.instance.saveImageToAlbumInRootFolder("My Album", image: UIImage(named: "my_image")) { (error) in
     // Handle error
}