iOS开发:如何在保存至自定义相册前修改图片名称并替换已存在文件
实现自定义图片文件名及替换同名图片的方案
核心说明
iOS 13及以上版本中,PHAssetChangeRequest新增了filename属性,可直接设置图片的自定义文件名。要实现"检查同名图片存在则替换"的需求,需先查询相册中是否存在目标文件名的资产,存在则先删除,再创建新的带自定义文件名的图片并添加到指定相册。
完整实现代码
import Photos let targetFilename = "PG-1000" let myAlbumName = "CustomAlbum" // 检查目标相册是否存在,不存在则创建 func getOrCreateAlbum(completion: @escaping (PHAssetCollection?) -> Void) { let options = PHFetchOptions() options.predicate = NSPredicate(format: "title = %@", myAlbumName) let fetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: options) if let existingAlbum = fetchResult.firstObject { completion(existingAlbum) return } // 相册不存在则创建 PHPhotoLibrary.shared().performChanges({ let request = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: myAlbumName) }, completionHandler: { success, error in if success { let newFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: options) completion(newFetchResult.firstObject) } else { print("创建相册失败: \(error?.localizedDescription ?? "Unknown error")") completion(nil) } }) } // 查询是否存在同名图片 func checkExistingImage(with filename: String, completion: @escaping ([PHAsset]) -> Void) { let options = PHFetchOptions() options.predicate = NSPredicate(format: "filename = %@", filename) let fetchResult = PHAsset.fetchAssets(with: options) var assets = [PHAsset]() fetchResult.enumerateObjects { asset, _, _ in assets.append(asset) } completion(assets) } // 执行删除、创建、添加到相册的完整流程 func saveImageWithCustomFilename(image: UIImage) { getOrCreateAlbum { album in guard let album = album else { return } checkExistingImage(with: targetFilename) { existingAssets in PHPhotoLibrary.shared().performChanges({ // 删除已存在的同名图片 if !existingAssets.isEmpty { PHAssetChangeRequest.deleteAssets(existingAssets as NSArray) } // 创建带自定义文件名的图片 guard let assetRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) else { return } assetRequest.filename = targetFilename // 设置自定义文件名 let assetPlaceholder = assetRequest.placeholderForCreatedAsset // 将新图片添加到相册 guard let albumChangeRequest = PHAssetCollectionChangeRequest(for: album) else { return } albumChangeRequest.addAssets([assetPlaceholder] as NSArray) }, completionHandler: { success, error in if success { print("图片处理完成:已保存/替换为 \(targetFilename) 至相册 \(myAlbumName)") } else { print("图片处理失败: \(error?.localizedDescription ?? "Unknown error")") } }) } } } // 调用示例(传入你要保存的UIImage实例) // saveImageWithCustomFilename(image: yourTargetImage)
关键代码解释
- 相册检查与创建:通过
PHFetchOptions的predicate筛选同名相册,避免重复创建相册。 - 同名图片查询:利用
filename字段作为查询条件,准确找到需要替换的资产。 - 自定义文件名设置:在
PHAssetChangeRequest创建时,直接赋值filename属性,注意该属性仅在iOS 13+可用。 - 原子化操作:将删除旧资产、创建新资产、添加到相册的操作放在同一个
performChanges块中,保证操作的原子性,避免出现中间状态。
内容的提问来源于stack exchange,提问作者richard
相关产品推荐
相关产品推荐

