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

无法访问Documents目录下已保存文件,权限问题求助

解决方案

1. 移除冗余文件创建调用,改用原子写入

在downloadSong函数中,FileManager.default.createFile(atPath: filePath.path(), contents: nil)属于冗余操作,且可能导致文件权限异常。直接使用原子写入方式,系统会自动创建文件并配置正确的读写权限:

func downloadSong(url: URL) async throws -> String {
    let urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData)
    let (data, response) = try await session.data(for: urlRequest)
    if let code = (response as? HTTPURLResponse)?.statusCode, code != 200 {
        printJSONData(data)
        throw HalpoError.badResponse(code: code)
    }
    let documentsURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    let savedMusicPath = documentsURL.appendingPathComponent("saved", conformingTo: .directory)
    var isDirectory: ObjCBool = true
    if !FileManager.default.fileExists(atPath: savedMusicPath.path(), isDirectory: &isDirectory) {
        try FileManager.default.createDirectory(at: savedMusicPath, withIntermediateDirectories: false)
    }
    let pathComponent = "saved/\(UUID()).mp3"
    let filePath = documentsURL.appendingPathComponent(pathComponent)
    // 移除createFile调用,改用原子写入
    try data.write(to: filePath, options: .atomic)
    return pathComponent
}

2. 调整Documents目录URL获取逻辑

原代码中appropriateFor: .documentsDirectory参数属于误用,该参数主要用于关联临时文件到特定目录,可能干扰沙箱内URL的权限上下文。修改为:

// 在retrieveSong和downloadSong中同步修改
let documentsUrl = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)

3. 手动校验并修正文件权限

如果上述修改后仍有问题,可在文件写入后强制设置正确权限:

try data.write(to: filePath, options: .atomic)
// 强制设置文件权限为应用可读写
try FileManager.default.setAttributes([.posixPermissions: 0o644], ofItemAtPath: filePath.path())

4. 排查iCloud同步干扰

若应用开启了iCloud Documents同步,文件可能因同步延迟导致暂时无法访问:

  • 临时关闭应用的iCloud Documents权限测试
  • 或在写入后调用startDownloadingUbiquitousItem(at:)确保本地存在完整文件:
try data.write(to: filePath, options: .atomic)
try FileManager.default.startDownloadingUbiquitousItem(at: filePath)

5. 验证文件路径有效性

在retrieveSong中打印文件的本地路径而非URL字符串,确认路径格式正确:

if FileManager.default.fileExists(atPath: fileUrl.path()) {
    print("File Exists!\nPath: \(fileUrl.path())")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 06:35:29