// // PhotoManager.swift // TSLiveWallpaper // // Created by 100Years on 2024/12/24. // import Photos import UIKit let PhotoManagerShared = PhotoManager.shared class PhotoManager { static let shared = PhotoManager() func saveImagesToUniqueAlbum(images: [UIImage], baseAlbumName: String, completion: @escaping (Bool, Error?) -> Void) { // 检查并请求权限 PHPhotoLibrary.requestAuthorization { status in guard status == .authorized else { completion(false, NSError(domain: "PhotoLibrary", code: 1, userInfo: [NSLocalizedDescriptionKey: "未获得相册访问权限"])) return } // 获取所有相册名称 let allAlbumNames = self.fetchAllAlbumNames() let uniqueAlbumName = self.generateUniqueAlbumName(baseName: baseAlbumName, existingNames: allAlbumNames) // 保存图片到生成的相册 self.saveImagesToAlbum(images: images, albumName: uniqueAlbumName, completion: completion) } } // 获取所有相册名称 private func fetchAllAlbumNames() -> [String] { var albumNames: [String] = [] let userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil) userCollections.enumerateObjects { collection, _, _ in if let album = collection as? PHAssetCollection, let albumName = album.localizedTitle { albumNames.append(albumName) } } return albumNames } // 生成唯一的相册名称 private func generateUniqueAlbumName(baseName: String, existingNames: [String]) -> String { var uniqueName = baseName var index = 1 while existingNames.contains(uniqueName) { uniqueName = "\(baseName)-\(index)" index += 1 } return uniqueName } // 保存图片到指定相册(之前提供的 saveImagesToAlbum 方法) private func saveImagesToAlbum(images: [UIImage], albumName: String, completion: @escaping (Bool, Error?) -> Void) { var albumPlaceholder: PHObjectPlaceholder? let fetchOptions = PHFetchOptions() fetchOptions.predicate = NSPredicate(format: "title = %@", albumName) let collection = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions) if let existingAlbum = collection.firstObject { saveImages(images: images, to: existingAlbum, completion: completion) } else { PHPhotoLibrary.shared().performChanges { let creationRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName) albumPlaceholder = creationRequest.placeholderForCreatedAssetCollection } completionHandler: { success, error in guard success, let placeholder = albumPlaceholder else { completion(false, error) return } let fetchResult = PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: [placeholder.localIdentifier], options: nil) if let newAlbum = fetchResult.firstObject { self.saveImages(images: images, to: newAlbum, completion: completion) } else { completion(false, NSError(domain: "PhotoLibrary", code: 2, userInfo: [NSLocalizedDescriptionKey: "创建相册失败"])) } } } } // 保存图片到指定相册 private func saveImages(images: [UIImage], to album: PHAssetCollection, completion: @escaping (Bool, Error?) -> Void) { PHPhotoLibrary.shared().performChanges { let assetRequest = images.map { PHAssetChangeRequest.creationRequestForAsset(from: $0) } let assetPlaceholders = assetRequest.compactMap { $0.placeholderForCreatedAsset } guard !assetPlaceholders.isEmpty else { return } if let albumChangeRequest = PHAssetCollectionChangeRequest(for: album) { albumChangeRequest.addAssets(assetPlaceholders as NSArray) } } completionHandler: { success, error in completion(success, error) } } /// 保存图片到相册 /// - Parameters: /// - image: 要保存的 UIImage /// - completion: 保存结果的回调,返回成功与否和错误信息 func saveImageToAlbum(_ image: UIImage, completion: @escaping (Bool, Error?) -> Void) { // 检查相册权限 PHPhotoLibrary.requestAuthorization { status in DispatchQueue.main.async { switch status { case .authorized: // 权限已授权,保存图片 self.save(image: image, completion: completion) case .limited: // 在受限权限下保存图片 self.save(image: image, completion: completion) case .denied, .restricted: // 权限被拒绝或受限 completion(false, NSError(domain: "PhotoSaver", code: 1, userInfo: [NSLocalizedDescriptionKey: "Photo Library access is denied."])) case .notDetermined: // 不会进入这个分支,因为已经请求了权限 completion(false, NSError(domain: "PhotoSaver", code: 2, userInfo: [NSLocalizedDescriptionKey: "Photo Library access not determined."])) @unknown default: completion(false, NSError(domain: "PhotoSaver", code: 3, userInfo: [NSLocalizedDescriptionKey: "Unknown authorization status."])) } } } } /// 保存图片到相册的具体实现 private func save(image: UIImage, completion: @escaping (Bool, Error?) -> Void) { PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.creationRequestForAsset(from: image) }) { success, error in DispatchQueue.main.async { completion(success, error) } } } }