簡體   English   中英

Swift:如何向 JSON 數組添加多個項目?

[英]Swift: How to add more than one item to JSON array?

我正在嘗試為 Swift 中的命令行創建一個基本的待辦事項應用程序。 下面是我向待辦事項數組添加新項目的函數,但新條目不斷覆蓋舊條目,而不是創建新條目。 最后, todo.json文件中只有一個條目。

當我手動將條目和.append語句相乘時,它可以工作,但可能我的大腦現在已經死了,無法弄清楚。


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 的內容:

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將為空。


僅供參考,這是我用來生成上述代碼的代碼。 希望它說明了這個想法。

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)"
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM