使用Swift实现将照片保存到iOS系统相册App同名自定义文件夹
前提配置
- 首先在项目的
Info.plist中添加相册权限声明:- 保存图片必备:
NSPhotoLibraryAddUsageDescription,值填写你希望向用户展示的权限申请说明,比如“需要相册权限保存图片到本地” - 若需要兼容iOS 14以下版本的相册读取校验,额外添加
NSPhotoLibraryUsageDescription,值同上述说明
- 保存图片必备:
- 引入系统相册依赖框架:
import Photos
核心实现逻辑
核心逻辑分为4步:1. 获取App名称 2. 校验相册访问权限 3. 查找/创建App同名相册文件夹 4. 保存图片到指定文件夹
完整代码示例
import Photos class PhotoAlbumManager: NSObject { static let shared = PhotoAlbumManager() // 获取App名称 private var appName: String { Bundle.main.infoDictionary?["CFBundleDisplayName"] as? String ?? Bundle.main.infoDictionary?["CFBundleName"] as? String ?? "DefaultAppName" } // 获取App对应的自定义相册,不存在则创建 private func getAppAlbum() -> PHAssetCollection? { // 先查找已存在的同名相册 let fetchOptions = PHFetchOptions() fetchOptions.predicate = NSPredicate(format: "title = %@", appName) let collections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumRegular, options: fetchOptions) if let album = collections.firstObject { return album } // 不存在则创建新相册 var albumId: String? do { try PHPhotoLibrary.shared().performChangesAndWait { albumId = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: self.appName).placeholderForCreatedAssetCollection.localIdentifier } guard let id = albumId else { return nil } return PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: [id], options: nil).firstObject } catch { print("创建相册失败:\(error.localizedDescription)") return nil } } // 对外暴露的保存图片方法 func saveImageToAppAlbum(image: UIImage, completion: @escaping (Bool, Error?) -> Void) { // 先校验相册权限 PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in guard status == .authorized || status == .limited else { completion(false, NSError(domain: "PhotoAlbumError", code: -1, userInfo: [NSLocalizedDescriptionKey: "未获得相册访问权限"])) return } guard let album = self.getAppAlbum() else { completion(false, NSError(domain: "PhotoAlbumError", code: -2, userInfo: [NSLocalizedDescriptionKey: "获取/创建相册失败"])) return } // 保存图片到指定相册 PHPhotoLibrary.shared().performChanges { let assetRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) guard let placeholder = assetRequest.placeholderForCreatedAsset else { return } let albumChangeRequest = PHAssetCollectionChangeRequest(for: album) albumChangeRequest?.addAssets([placeholder] as NSFastEnumeration) } completionHandler: { success, error in DispatchQueue.main.async { completion(success, error) } } } } }
调用示例
// 假设你已经拿到要保存的UIImage对象 guard let targetImage = UIImage(named: "test_image") else { return } PhotoAlbumManager.shared.saveImageToAppAlbum(image: targetImage) { success, error in if success { print("图片保存成功") } else { print("保存失败:\(error?.localizedDescription ?? "未知错误")") } }
注意事项
- 所有相册操作的回调默认在子线程执行,涉及UI更新的逻辑需要手动切回主线程
- iOS 14新增的有限相册权限下,上述代码可正常执行,用户仅能看到你保存到相册的内容
- 如果需要保存网络图片,需要先将网络图片下载转为UIImage对象后再调用上述保存方法
内容的提问来源于stack exchange,提问作者Anam Shafique
相关产品推荐
相关产品推荐

