Swift:如何向JSON数组添加多个项目? [英] Swift: How to add more than one item to JSON array?

查看:130
本文介绍了Swift:如何向JSON数组添加多个项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Swift中为命令行创建一个基本的待办事项应用程序。下面是我向待办事项数组添加新项的功能,但是新条目会覆盖旧条目,而不是创建新条目。最后,在 todo.json 文件中只有一个条目。

I am trying to create a basic to-do application for command-line in Swift. Below is my function to add a new item to the to-do array, but the new entry keeps overwriting the old one, instead of creating a new one. In the end, there is only one entry in the todo.json file.

当我将这些条目与 .append 语句可以手动运行,但是现在我的大脑可能已经死了,无法弄清楚。

When I multiply the entries and .append statements manually it works, but probably my brain is too dead to figure it out at the moment.


struct TodoItem: Codable {
    let name: String
}

var todoList = [TodoItem]()

func addToList(_ item: String) -> String {
    let todoItem = TodoItem(name: item)
    todoList.append(todoItem)

    do {
        let fileURL = try FileManager.default
            .url(for: .applicationSupportDirectory,
                 in: .userDomainMask,
                 appropriateFor: nil,
                 create: true)
             .appendingPathComponent("example")
             .appendingPathExtension("json")

        let encoder = JSONEncoder()
        try encoder.encode(todoList).write(to: fileURL)

    } catch {
        return "Error: \(error.localizedDescription)"
    }
        return "Item added: \(todoItem.name)"
}


推荐答案

您的代码可以正常工作。我认为问题在于运行此命令时 todoList 为空。但是您可以编写代码来检索JSON的内容:

Your code works fine. I think the problem rests in the fact that todoList is empty when you run this. But you can write code to retrieve the contents of the JSON:

var todoList: [TodoItem] = []

func retrieveToDoList() {
    guard let data = try? Data(contentsOf: fileURL) else { return }

    todoList = (try? JSONDecoder().decode([TodoItem].self, from: data)) ?? []
}

例如,考虑:

retrieveToDoList()

addToList("foo")
addToList("bar")
addToList("baz")

print(todoList)

// if you want to check the json

let data = try! Data(contentsOf: fileURL)
let json = String(data: data, encoding: .utf8)!
print(json)

结果是:


[MyApp.TodoItem(name: "foo"), MyApp.TodoItem(name: "bar"), MyApp.TodoItem(name: "baz")]
[
  {
    "name" : "foo"
  },
  {
    "name" : "bar"
  },
  {
    "name" : "baz"
  }
]

如果以后再做:

addToList("abc")
addToList("def")
addToList("hij")

然后我得到:


[
  {
    "name" : "foo"
  },
  {
    "name" : "bar"
  },
  {
    "name" : "baz"
  },
  {
    "name" : "abc"
  },
  {
    "name" : "def"
  },
  {
    "name" : "hij"
  }
]

因此,每次应用启动时,请确保在尝试添加项目之前确保调用 retrieveToDoList ,否则 toDoList 将为空。

So, every time the app starts up, just make sure to call retrieveToDoList before trying to append items or else the toDoList will be empty.

仅供参考,这是我用来生成以上代码的代码。希望它能说明这个想法。

FYI, this is the code I used to generate the above. Hopefully it illustrates the idea.

struct TodoItem: Codable {
    let name: String
}

class ViewController: UIViewController {
    private var todoList: [TodoItem] = []

    private let fileURL = try! FileManager.default
        .url(for: .applicationSupportDirectory,
             in: .userDomainMask,
             appropriateFor: nil,
             create: true)
        .appendingPathComponent("example.json")

    override func viewDidLoad() {
        super.viewDidLoad()

        retrieveToDoList()

        addToList("foo")
        addToList("bar")
        addToList("baz")

        print(todoList)

        // if you want to check the json

        let data = try! Data(contentsOf: fileURL)
        let json = String(data: data, encoding: .utf8)!
        print(json)
    }
}

private extension ViewController {
    func retrieveToDoList() {
        guard let data = try? Data(contentsOf: fileURL) else { return }

        todoList = (try? JSONDecoder().decode([TodoItem].self, from: data)) ?? []
    }

    @discardableResult
    func addToList(_ item: String) -> String {
        let todoItem = TodoItem(name: item)
        todoList.append(todoItem)

        do {
            let encoder = JSONEncoder()
            encoder.outputFormatting = .prettyPrinted
            try encoder.encode(todoList).write(to: fileURL)
        } catch {
            return "Error: \(error.localizedDescription)"
        }

        return "Item added: \(todoItem.name)"
    }
}

这篇关于Swift:如何向JSON数组添加多个项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆