You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 11:48:28