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

Swift Playgrounds 4.3保存JSON文件遇权限问题,求解决方法

Swift Playgrounds 4.3(macOS 13)JSON文件保存权限问题解决指南

问题背景

在macOS 13系统上使用Swift Playgrounds 4.3保存JSON文件到本地时,遇到权限不足或文件找不到的问题,具体场景如下:

1. 自定义路径写入报错

尝试直接写入/Users/la/JSON目录时触发权限错误:

import Foundation

struct Driver: Codable { 
    let name: String
    let ownsCar: Bool
    let license_code: String?
    
    init(name: String, ownsCar: Bool, license_code: String? = nil) {
        self.name = name
        self.ownsCar = ownsCar
        self.license_code = license_code
    }
}

class Drivers {
    let filePathURL = URL(fileURLWithPath: "/Users/la/JSON/JSONTestFile.json")
    
    var data: Driver = Driver(name: "Picard", ownsCar: true)
    
    func readFromFile(filePathURL: URL) throws {
        let readData = try Data(contentsOf: filePathURL)
        self.data = try JSONDecoder().decode(Driver.self, from: readData)
    }
    
    func writeToFile(filePathURL: URL) throws {
        let jsonData = try JSONEncoder().encode(self.data)
        try jsonData.write(to: filePathURL)
    }
    
}
let drivers: Drivers = Drivers()
do {
    try drivers.writeToFile(filePathURL: drivers.filePathURL )
}
catch {
    print("Error saving file at path: \(drivers.filePathURL) with error: \(error)")
}

错误信息:

Error saving file at path: file:///Users/la/JSON/JSONTestFile.json
with error: Error Domain=NSCocoaErrorDomain Code=513 "You don’t have
permission to save the file “JSONTestFile.json” in the folder “JSON”."
UserInfo={NSFilePath=/Users/la/JSON/JSONTestFile.json,
NSUnderlyingError=0x7f88474252b0 {Error Domain=NSPOSIXErrorDomain
Code=1 "Operation not permitted"}}

2. 旧版Shared Playground Data路径不可用

尝试使用playgroundSharedDataDirectory时触发API不可用错误:

import Foundation
import PlaygroundSupport
import Swift

struct Driver: Codable {
    let name: String
    let ownsCar: Bool
    let license_code: String?
    
    init(name: String, ownsCar: Bool, license_code: String? = nil) {
        self.name = name
        self.ownsCar = ownsCar
        self.license_code = license_code
    }
}

class Drivers {
  let filePathURL = URL(fileURLWithPath: "/Users/la/Documents/Shared Playground Data/JSONTestFile.json")
  //  print (playgroundSharedDataDirectory)
   // let filePathURL = playgroundSharedDataDirectory.appendingPathComponent("JSONTestFile.json")
    
    var data: Driver = Driver(name: "Picard", ownsCar: true)
    
    func readFromFile(filePathURL: URL) throws {
        let readData = try Data(contentsOf: filePathURL)
        self.data = try JSONDecoder().decode(Driver.self, from: readData)
    }
    
    func writeToFile(filePathURL: URL) throws {
        let jsonData = try JSONEncoder().encode(self.data)
        try jsonData.write(to: filePathURL)
    }
    
}
let drivers: Drivers = Drivers()
do {
    try drivers.writeToFile(filePathURL: drivers.filePathURL )
}
catch {
    print("Error saving file at path: \(drivers.filePathURL) with error: \(error)")
}

报错内容:
'playgroundSharedDataDirectory' is unavailable: playgroundSharedDataDirectory is not supported in Swift Playgrounds

3. DocumentDirectory写入无报错但找不到文件

使用系统DocumentDirectory路径时,代码无报错但无法定位生成的文件:

let fileName = "JSONTestFile.json"

let docDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

let outputFileUrl = docDirectory.appendingPathComponent(fileName)

func documentDirectoryURL() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

func filePathURL() -> URL {
    return documentDirectoryURL().appendingPathComponent(fileName)
}

解决方案

1. 理解沙箱限制

macOS版Swift Playgrounds运行在沙箱环境中,默认仅能访问自身容器内的文件,无法直接读写系统自定义目录或旧版Shared Playground路径,这是系统安全机制的要求。

2. 写入Playgrounds专属可读写目录

Swift Playgrounds 4.x的可读写目录位于其容器内的Documents文件夹,以下是修改后的完整可运行代码:

import Foundation

struct Driver: Codable {
    let name: String
    let ownsCar: Bool
    let license_code: String?
    
    init(name: String, ownsCar: Bool, license_code: String? = nil) {
        self.name = name
        self.ownsCar = ownsCar
        self.license_code = license_code
    }
}

class Drivers {
    var data: Driver = Driver(name: "Picard", ownsCar: true)
    
    // 获取Playgrounds容器内的Documents路径
    private func getDocumentsURL() -> URL {
        let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "com.apple.swiftplaygrounds")!
        return containerURL.appendingPathComponent("Documents")
    }
    
    func writeToFile() throws {
        let filePath = getDocumentsURL().appendingPathComponent("JSONTestFile.json")
        // 确保目录存在
        try FileManager.default.createDirectory(at: getDocumentsURL(), withIntermediateDirectories: true)
        let jsonData = try JSONEncoder().encode(data)
        try jsonData.write(to: filePath)
        print("文件已保存到:\(filePath)")
    }
    
    func readFromFile() throws {
        let filePath = getDocumentsURL().appendingPathComponent("JSONTestFile.json")
        let readData = try Data(contentsOf: filePath)
        data = try JSONDecoder().decode(Driver.self, from: readData)
        print("读取的数据:\(data)")
    }
}

let drivers = Drivers()
do {
    try drivers.writeToFile()
    // 可选:验证读取功能
    try drivers.readFromFile()
} catch {
    print("操作失败:\(error)")
}

3. 找到生成的文件

运行代码后,通过以下步骤定位文件:

  • 在Swift Playgrounds中打开目标项目
  • 点击顶部菜单栏Playground -> Show in Finder
  • 在Finder中右键点击playground文件,选择Show Package Contents
  • 导航到Contents -> Documents,即可找到保存的JSONTestFile.json

4. 手动选择路径(绕过沙箱)

如果需要将文件保存到自定义位置,可使用系统文件选择器让用户主动授权,代码如下:

import Foundation
import AppKit

func saveFileWithPanel(data: Data, fileName: String) {
    let savePanel = NSSavePanel()
    savePanel.title = "保存JSON文件"
    savePanel.nameFieldStringValue = fileName
    savePanel.allowedContentTypes = [.json]
    
    if savePanel.runModal() == .OK {
        do {
            try data.write(to: savePanel.url!)
            print("文件已保存到:\(savePanel.url!)")
        } catch {
            print("保存失败:\(error)")
        }
    }
}

// 使用示例
let driver = Driver(name: "Picard", ownsCar: true)
let jsonData = try! JSONEncoder().encode(driver)
saveFileWithPanel(data: jsonData, fileName: "JSONTestFile.json")

注意:此方案需要导入AppKit框架,运行时会弹出系统保存对话框,用户选择路径后即可完成保存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:14:59