首页 > 解决方案 > 如何使用 FileManger 和 JSONEncoder 将 JSON 写入本地文件?迅速

问题描述

所以我想要做的是将代码中创建的 json 写入用户本地文档目录,但似乎可以让它工作。

struct Puzzle: Codable {
  let id: Int?
  let puzzle: Int?
  let moves: Int?
}

class PuzzleController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()

    // create reference to default filemanager object
    let filemgr = FileManager.default

    // get documents directory path
    let dirPath = filemgr.urls(for: .documentsDirectory, in: .userDomainMask)
    let docsDir = dirPath[0].path

    // change to current working directory
    filemgr.changeCurrentDirectoryPath(docsDir)

    // create a new directory
    let docsURL = dirPath[0]
    let newDir = docsURL.appendingPathComponent("json").path

    do {
      try filemgr.createDirectory(atPath: newDir, withIntermediateDirectories: true, attributes: nil)
    } catch let error as NSError {
      print(error.localizeDescription)
    }

    // create arrary of json objects
    let jsonPuzzle = [Puzzle(id: 1, puzzle: 1, moves: 1), Puzzle(id: 2, puzzle: 2, moves: 2), Puzzle(id: 3, puzzle: 3, moves: 3)] 

    // create url to json file
    let jURL = URL(string: newDir)?.appendingPathComponent("pjson.json")

    // write to json file
    do {
      let encoder = JSONEncoder()
      encoder.outputFormatting = .prettyPrinted
      let jsonData = try encoder.encode(jsonPuzzle)
      try jsonData.write(to: jURL)
    } catch let jError {
      print(jError)
    }
  }
}  

我不断收到 CFURLCopyResourcePropertyForKey 失败,因为它传递了一个没有方案的 URL,并且错误 Domain=NSCocoaErrorDomain Code=518 “无法保存文件,因为不支持指定的 URL 类型。”

我究竟做错了什么?在不使用第三方 api 的情况下将 json 写入本地文件所需的正确步骤是什么?

其中一位评论者要求的 jURL 内容。“/Users/blank/Library/Developer/CoreSimulator/Devices/920F6A0F-E814-49E2-A792-04605361F139/data/Containers/Data/Applicatio ... ir/pjson”

标签: iosjsonswift

解决方案


问题是当您在路径之间来回切换时丢失协议(方案)URL,仅使用将修复您的错误。StringURL

这是您的代码的缩短版本,仅URL用于目录和文件路径以确保 URL 有效

let filemgr = FileManager.default

let dirPath = filemgr.urls(for: .documentsDirectory, in: .userDomainMask)

let docsURL = dirPath[0]
let newDir = docsURL.appendingPathComponent("json")

do {
  try filemgr.createDirectory(at: newDir, withIntermediateDirectories: true, attributes: nil)
} catch {
  print(error)
}

let jURL = newDir.appendingPathComponent("pjson.json")

推荐阅读