简体   繁体   中英

Save photo to a folder in Gallery using Swift

I am working on an iOS Swift 5 project and want to download image from my Project App to a folder in gallery. Folder name would be same as my App name and if doesn't exist in gallery, then code should first create App folder in gallery then save image to it.

Need help to resolve this.

as i implemented a year ago got code from stackoverflow

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

currently i am working on a project in office that's why i am not providing you the exact solution but you can figure it out easily from the above class ... you can use it PhotoManager.instance.saveImageToAlbumInRootFolder(_ albumName: String, image: yourImage) {completion}

import Foundation
import Photos

class CustomPhotoAlbum: NSObject {

static let albumName = "Your App 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)
}

}

how to use it

  func haiJeenyKaMaqsadAuronKKamAna() {
    CustomPhotoAlbum.sharedInstance.createAlbum()
    CustomPhotoAlbum.sharedInstance.save(image: UIImage(named: "help")!)
}

now this is working fine as i copied it from my old project

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM