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)"
}
}
我正在尝试为 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)"
}
}