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

SwiftUI PhotoPicker选中视频重启App后无法访问问题求助

问题原因与解决方案

核心问题大概率是你保存了视频的完整沙盒URL,而非仅保存文件名。iOS模拟器(或真机)的App沙盒容器路径中,Application ID部分会在Xcode重新安装App、重置模拟器等场景下变化,导致之前存储的完整URL直接失效。

具体修正步骤:

  1. 仅保存文件名而非完整URL
    不要把视频的完整路径(如file:///旧容器ID/Documents/mymovie.mp4)存入UserDefaults或其他持久化存储,只保存文件名(比如mymovie.mp4)。

  2. 重启后重新生成有效URL
    当需要访问视频时,用当前App的Documents目录路径拼接保存的文件名,生成最新的有效地址:

    // 从持久化存储中读取保存的文件名
    guard let savedFileName = UserDefaults.standard.string(forKey: "selectedVideoFileName") else {
        return
    }
    // 生成当前有效的视频URL
    let videoURL = URL.documentsDirectory.appendingPathComponent(savedFileName)
    

额外验证与优化:

  • 确认Documents目录扩展正确性
    确保你使用的URL.documentsDirectory扩展能正确指向当前App的Documents目录:

    extension URL {
        static var documentsDirectory: URL {
            guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
                fatalError("无法获取Documents目录")
            }
            return url
        }
    }
    
  • 优化文件复制的错误处理
    你的复制逻辑本身没问题,但建议在错误处理时抛出异常,让上层能及时感知复制失败:

    importing: { received in
        let fileName = received.file.lastPathComponent
        let copyURL = URL.documentsDirectory.appendingPathComponent(fileName)
        
        do {
            if FileManager.default.fileExists(atPath: copyURL.path()) {
                try FileManager.default.removeItem(at: copyURL)
            }
            try FileManager.default.copyItem(at: received.file, to: copyURL)
            return Self.init(url: copyURL)
        } catch {
            Log.e("复制视频失败: \(error.localizedDescription)")
            throw error // 抛出错误,让loadTransferable的failure分支捕获处理
        }
    }
    
  • 模拟器特性说明
    如果你通过Xcode清除构建文件夹、删除模拟器中的App后重新运行,之前的Documents文件会被清除,这是模拟器的正常行为,真机上仅在卸载App时才会出现此情况。

内容的提问来源于stack exchange,提问作者Udi Oshi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:02:53