SwiftUI update/replace 键,JSON 文件中的值
SwiftUI update/replace key, value in a JSON file
我是 SwiftUI 编码的新手。我有一个具有以下数据结构的 JSON 文件。尝试在按下按钮时使用 TextField 变量更新特定键的值。我能够读取 JSON 文件内容,但无法弄清楚如何更新特定密钥并写回文件。这是用于测试 MacOS 应用程序的。请帮我。提前致谢。
\settingsData.json
[
{
"id" : 1001,
"username": "example",
"password": "123456",
}
]
import SwiftUI
import Foundation
var jsonArray: [jsonModel] = readJSON("settingsData")
struct testJSON: View {
@State private var UserName: String = ""
var body: some View {
VStack (alignment: .leading) {
ForEach(jsonArray) { jsonValue in
Text("Username is \(jsonValue.username)")
}
TextField("Username", text: $UserName)
Button(action: {
// Update array and save to file
print("Done")
})
{
Text("Save")
}
}
}
}
这是模型
struct jsonModel: Hashable, Codable, Identifiable {
var id: Int
var username: String
var password: String
}
这是我用来从 App 目录中的文件读取 JSON 数据的简单代码。
func readJSON<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: "json")
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
print(file)
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
let jsonData = try decoder.decode(T.self, from: data)
return jsonData
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
这是一些代码,向您展示如何
在 macOS 上读取和写入文件(给予正确的权限)。
有了这个你应该可以编写代码来
“...更新特定密钥并写回 a
文件...”。
正如我在评论中提到的,应用程序包是只读的。
因此,您必须使用 FileManager 将更新写入“documentDirectory”(例如)。
import Foundation
import SwiftUI
@main
struct MacApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@StateObject var dataManager = DataManager()
@State private var userName: String = ""
var body: some View {
VStack (alignment: .leading) {
ForEach(dataManager.jsonArray) { jsonValue in
Text("Username is \(jsonValue.username)")
}
TextField("Username", text: $userName)
Button(action: {
// Update array, just for testing update all userName
for i in dataManager.jsonArray.indices {
dataManager.jsonArray[i].username = userName
}
// save to file
dataManager.saveToFile()
print("Done")
})
{
Text("Save")
}
}.frame(width: 444, height: 444)
}
}
class DataManager: ObservableObject {
@Published var jsonArray: [JsonModel] = []
var fileName = "settingsData"
init() {
readFromFile()
}
func readFromFile() {
jsonArray = readJSONBundle(fileName) // do this only the first time you open the app
// readJSON() // read from the saved file
}
private func readJSONBundle<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: "json")
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
print(file)
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
let jsonData = try decoder.decode(T.self, from: data)
return jsonData
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
func saveToFile() {
do {
let furl = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent(fileName)
.appendingPathExtension("json")
print("---> writing to: \(furl)")
let data = try JSONEncoder().encode(jsonArray)
try data.write(to: furl)
} catch {
print("---> error saveToFile: \(error)")
}
}
func readJSON() {
do {
let furl = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent(fileName)
.appendingPathExtension("json")
print("---> reading from: \(furl)")
let data = try Data(contentsOf: furl)
let decoder = JSONDecoder()
let jsonData = try decoder.decode([JsonModel].self, from: data)
jsonArray = jsonData
} catch {
print("---> error reading from file: \(error)")
}
}
}
struct JsonModel: Hashable, Codable, Identifiable {
var id: Int
var username: String
var password: String
}
我是 SwiftUI 编码的新手。我有一个具有以下数据结构的 JSON 文件。尝试在按下按钮时使用 TextField 变量更新特定键的值。我能够读取 JSON 文件内容,但无法弄清楚如何更新特定密钥并写回文件。这是用于测试 MacOS 应用程序的。请帮我。提前致谢。
\settingsData.json
[
{
"id" : 1001,
"username": "example",
"password": "123456",
}
]
import SwiftUI
import Foundation
var jsonArray: [jsonModel] = readJSON("settingsData")
struct testJSON: View {
@State private var UserName: String = ""
var body: some View {
VStack (alignment: .leading) {
ForEach(jsonArray) { jsonValue in
Text("Username is \(jsonValue.username)")
}
TextField("Username", text: $UserName)
Button(action: {
// Update array and save to file
print("Done")
})
{
Text("Save")
}
}
}
}
这是模型
struct jsonModel: Hashable, Codable, Identifiable {
var id: Int
var username: String
var password: String
}
这是我用来从 App 目录中的文件读取 JSON 数据的简单代码。
func readJSON<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: "json")
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
print(file)
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
let jsonData = try decoder.decode(T.self, from: data)
return jsonData
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
这是一些代码,向您展示如何 在 macOS 上读取和写入文件(给予正确的权限)。
有了这个你应该可以编写代码来
“...更新特定密钥并写回 a
文件...”。
正如我在评论中提到的,应用程序包是只读的。 因此,您必须使用 FileManager 将更新写入“documentDirectory”(例如)。
import Foundation
import SwiftUI
@main
struct MacApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@StateObject var dataManager = DataManager()
@State private var userName: String = ""
var body: some View {
VStack (alignment: .leading) {
ForEach(dataManager.jsonArray) { jsonValue in
Text("Username is \(jsonValue.username)")
}
TextField("Username", text: $userName)
Button(action: {
// Update array, just for testing update all userName
for i in dataManager.jsonArray.indices {
dataManager.jsonArray[i].username = userName
}
// save to file
dataManager.saveToFile()
print("Done")
})
{
Text("Save")
}
}.frame(width: 444, height: 444)
}
}
class DataManager: ObservableObject {
@Published var jsonArray: [JsonModel] = []
var fileName = "settingsData"
init() {
readFromFile()
}
func readFromFile() {
jsonArray = readJSONBundle(fileName) // do this only the first time you open the app
// readJSON() // read from the saved file
}
private func readJSONBundle<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: "json")
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
print(file)
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
let jsonData = try decoder.decode(T.self, from: data)
return jsonData
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
func saveToFile() {
do {
let furl = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent(fileName)
.appendingPathExtension("json")
print("---> writing to: \(furl)")
let data = try JSONEncoder().encode(jsonArray)
try data.write(to: furl)
} catch {
print("---> error saveToFile: \(error)")
}
}
func readJSON() {
do {
let furl = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent(fileName)
.appendingPathExtension("json")
print("---> reading from: \(furl)")
let data = try Data(contentsOf: furl)
let decoder = JSONDecoder()
let jsonData = try decoder.decode([JsonModel].self, from: data)
jsonArray = jsonData
} catch {
print("---> error reading from file: \(error)")
}
}
}
struct JsonModel: Hashable, Codable, Identifiable {
var id: Int
var username: String
var password: String
}