无法访问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
相关产品推荐
相关产品推荐

