使用 Swift 将照片保存到图库中的文件夹

Posted

技术标签:

【中文标题】使用 Swift 将照片保存到图库中的文件夹【英文标题】:Save photo to a folder in Gallery using Swift 【发布时间】:2021-12-07 20:41:01 【问题描述】:

我正在开发一个 ios Swift 5 项目,并希望将图像从我的项目应用程序下载到图库中的文件夹。文件夹名称将与我的 App 名称相同,如果图库中不存在,则代码应首先在图库中创建 App 文件夹,然后将图像保存到其中。

需要帮助来解决这个问题。

【问题讨论】:

请提供足够的代码,以便其他人更好地理解或重现问题。 【参考方案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
            
        )
    

目前我正在办公室做一个项目,这就是为什么我没有为您提供确切的解决方案,但您可以从上面的课程中轻松解决... 你可以使用它 PhotoManager.instance.saveImageToAlbumInRootFolder(_ albumName: String, image: yourImage) completion

【讨论】:

这段代码对我不起作用。它从不调用 fetchFolderWithIdentifier 函数,而且我总是在 self.folder 变量中得到 nil。 我会在完成我的工作后检查它 并在上面发布了另一个答案工作正常只需运行代码检查您的照片库【参考方案2】:
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)

如何使用它

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

现在这工作正常,因为我从旧项目中复制了它

【讨论】:

以上是关于使用 Swift 将照片保存到图库中的文件夹的主要内容,如果未能解决你的问题,请参考以下文章

swift 3中的按钮背景图像

Flutter:捕获照片 - 保存到图库 - 从图库中读取照片

Android笔记67Android之使用系统中的相机功能(拍照保存照片显示拍摄的照片照片保存到图库等操作)

如何将图像从相机保存到 iPhone 画廊中的特定文件夹?

照片永远不会在新文件夹中的图库中显示

Android - 将图像存储到图库