iOS开发如何将应用内视频保存到用户照片库?现有报错代码如何优化?
iOS 视频保存到相册的问题修复与最优实现
现有代码的核心问题
- API过时错误:
UTTypeCopyPreferredTagWithClass是iOS 15之前的旧API,在引入UniformTypeIdentifiers框架后已经被废弃,替换为Swift原生的UTType属性调用,所以会提示不在作用域内。 - 逻辑错误:你调用了图片写入的方法
PHAssetChangeRequest.creationRequestForAssetFromImage,就算修复了编译错误也无法写入视频到相册。 - 错误处理缺失:代码中多处使用
try?忽略抛出的错误,出现异常时无法定位问题。 - 权限逻辑缺失:未判断相册写入权限,系统会直接拦截写入操作。
优化后的正确实现方案
请先在项目的Info.plist中添加
NSPhotoLibraryAddUsageDescription权限声明,填写用户允许相册写入的提示文案,否则写入操作会直接被系统拦截。
完整实现代码:
import UniformTypeIdentifiers import Photos func saveVideoToAlbum(videoData: Data, videoUTI: UTType) throws { // 1. 生成临时文件路径 guard let fileExtension = videoUTI.preferredFilenameExtension else { throw NSError(domain: "VideoSaveError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的视频格式"]) } let fileName = "\(ProcessInfo.processInfo.globallyUniqueString).\(fileExtension)" let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(fileName) // 2. 写入视频数据到临时路径 try videoData.write(to: tempURL, options: .atomic) // 3. 请求相册写入权限(iOS14+支持仅添加权限,用户体验更好) PHPhotoLibrary.requestAuthorization(for: .addOnly) { status in guard status == .authorized else { // 可自行补充权限拒绝的提示逻辑 try? FileManager.default.removeItem(at: tempURL) return } // 4. 写入视频到相册 PHPhotoLibrary.shared().performChanges { // 调用视频专属写入接口 PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: tempURL) } completionHandler: { success, error in // 写入完成后删除临时文件释放空间 try? FileManager.default.removeItem(at: tempURL) if let error = error { // 可自行补充写入失败的提示逻辑 print("视频保存失败:\(error.localizedDescription)") } else if success { // 可自行补充保存成功的回调逻辑 } } } }
调用示例:
如果你的视频是MP4格式,直接传入对应UTI即可:
do { try saveVideoToAlbum(videoData: 你的视频Data变量, videoUTI: .mpeg4Movie) } catch { print("预处理失败:\(error.localizedDescription)") }
轻量可选方案
如果不需要自定义写入逻辑,只需要快速保存已经存在本地的视频文件,可以使用更简洁的系统兼容方法:
// 传入视频本地路径即可,兼容iOS 3.0+ UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self, #selector(videoSaveCompleted(_:didFinishSavingWithError:contextInfo:)), nil) // 保存结果回调方法 @objc func videoSaveCompleted(_ path: String, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) { if let error = error { print("保存失败:\(error.localizedDescription)") } else { print("保存成功") } }
内容的提问来源于stack exchange,提问作者CloakedArrow
相关产品推荐
相关产品推荐

