iOS如何持久保存用户视频?重启后不丢失方案咨询
解决iOS相册视频URL持久化访问问题
你的核心问题是跨沙盒持久化访问用户相册中的视频文件,普通书签重启后失效的原因是iOS沙盒权限机制——重启后临时访问权限会被回收,而Security-Scoped Bookmarks正是Apple官方提供的解决此类问题的标准方案,完全适配你的需求。下面是具体实现步骤和注意事项:
一、生成并保存Security-Scoped书签
在didSelect(url: URL?)回调中拿到视频URL后,先获取临时访问权限,再生成带安全作用域的书签,最后将书签数据保存到你指定的documentDirectory/movieDirectory目录:
func didSelect(url: URL?) { guard let videoURL = url else { return } // 启动安全作用域资源访问 guard videoURL.startAccessingSecurityScopedResource() else { // 处理权限获取失败,比如弹窗提示用户 return } do { // 生成带安全作用域的书签数据 let bookmarkData = try videoURL.bookmarkData( options: .securityScopeAllowed, includingResourceValuesForKeys: nil, relativeTo: nil ) // 确保movieDirectory目录存在 let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let movieDir = documentsDir.appendingPathComponent("movieDirectory") try FileManager.default.createDirectory(at: movieDir, withIntermediateDirectories: true) // 将书签数据写入本地文件 let bookmarkFileURL = movieDir.appendingPathComponent("video_bookmark.data") try bookmarkData.write(to: bookmarkFileURL) } catch { print("书签生成/保存失败:\(error.localizedDescription)") } // 必须停止安全作用域访问,避免资源泄漏 videoURL.stopAccessingSecurityScopedResource() }
二、加载书签并恢复视频访问权限
需要播放视频时,读取本地书签数据,解析出URL并重新获取访问权限:
func restoreVideoURL() -> URL? { let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let movieDir = documentsDir.appendingPathComponent("movieDirectory") let bookmarkFileURL = movieDir.appendingPathComponent("video_bookmark.data") // 读取书签数据 guard let bookmarkData = try? Data(contentsOf: bookmarkFileURL) else { return nil } var isBookmarkStale = false do { // 解析书签,恢复URL let restoredURL = try URL( resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isBookmarkStale ) // 如果书签已过期,重新生成并保存新书签 if isBookmarkStale { guard restoredURL.startAccessingSecurityScopedResource() else { return nil } let newBookmarkData = try restoredURL.bookmarkData( options: .securityScopeAllowed, includingResourceValuesForKeys: nil, relativeTo: nil ) try newBookmarkData.write(to: bookmarkFileURL) restoredURL.stopAccessingSecurityScopedResource() } // 获取访问权限后返回URL(使用完记得停止访问) if restoredURL.startAccessingSecurityScopedResource() { return restoredURL } else { return nil } } catch { print("书签解析失败:\(error.localizedDescription)") return nil } }
三、关键注意事项
- Info.plist配置:必须添加
NSPhotoLibraryUsageDescription键,填写访问相册的原因(比如"需要访问您的相册以播放选中的视频"),否则会被系统拒绝访问。 - 权限生命周期:每次使用恢复后的URL前必须调用
startAccessingSecurityScopedResource(),使用完成后务必调用stopAccessingSecurityScopedResource(),避免权限泄漏。 - 书签过期处理:当
isBookmarkStale为true时,说明书签已失效(比如视频被移动或删除),需要重新获取用户授权并生成新书签。 - 本地存储合规:将书签数据保存在
Document目录完全符合iOS本地存储要求,不会上传服务器,满足你的需求。
内容的提问来源于stack exchange,提问作者DannyG
相关产品推荐
相关产品推荐

