![](/img/trans.png)
[英]How can I fix NewtonSoft (json.net) errors after Xamarin update?
[英]How can I Read/Write array of objects from/to JSON using a Swift class that matches JSON from NewtonSoft (JSON.Net) component?
我正在尝试读取在另一个(Windows)程序中使用NewtonSoft JSON.Net解析器创建的JSON文件。 JSON是由JSON.Net组件在序列化对象数组时创建的。 样本JSON如下所示(在此示例中,我仅显示两个对象):
[{"MaxLength":23,"HasSpecialChars":false,"HasUpperCase":true,"Key":"firstOne"},
{"MaxLength":0,"HasSpecialChars":false,"HasUpperCase":false,"Key":"secondOne"}]
请注意,这是json中的对象数组。
现在,我需要一些Swift代码,该代码将读入JSON并在程序中更改值后将其写出。
我尝试过的
我找到了这个SO条目: 使用Swift读取JSON文件但是,为了获得对象数组,该条目使用了可编码的单独结构,如下所示:
struct ResponseData: Decodable {
var thisNameShowsUpInJson: [SiteKey]
}
这迫使外部数组在json中拥有自己的name属性。
例如,该文章中代码的唯一工作方式是将我的JSON更改为包含名称(SiteKey)的外部对象,如下所示:
{"thisNameShowsUpInJson": [{"MaxLength":23,"HasSpecialChars":false,"HasUpperCase":true,"Key":"firstOne"},
{"MaxLength":0,"HasSpecialChars":false,"HasUpperCase":false,"Key":"secondOne"}]
}
但是,对于JSON.Net将对象数组写入文件的方式,这是不正确的。
这是我想要序列化和反序列化的简单Swift类:
class SiteKey : Codable{
var Key : String
var MaxLength : Int
var HasSpecialChars : Bool
var HasUpperCase : Bool
init(key : String, maxLength : Int,
hasSpecialChars : Bool,
hasUpperCase : Bool){
Key = key;
MaxLength = maxLength;
HasSpecialChars = hasSpecialChars;
HasUpperCase = hasUpperCase;
}
}
我想从命名文件中读取数据,然后将数据反序列化为对象。 然后,我想将内存对象序列化回我的示例文件。
想象一下,您有一组可编码的对象
var array = [SiteKey]()
那么您只需使用JSONEncoder
将整个数组编码为Data
do {
let encoded = try JSONEncoder().encode(array)
} catch { print(error) }
要将Data
解码为对象数组,可以使用JSONDecoder
do {
array = try JSONDecoder().decode([SiteKey].self, from: encoded)
} catch { print(error) }
我的建议:
init
因为您可以免费获得一个 struct SiteKey : Codable {
var key : String
var maxLength : Int
var hasSpecialChars : Bool
var hasUpperCase : Bool
enum CodingKeys: String, CodingKey {
case key = "Key"
case maxLength = "MaxLength"
case hasSpecialChars = "HasSpecialChars"
case hasUpperCase = "HasUpperCase"
}
}
我发现了需要在Swift中使用的代码,该代码使我可以读写JSON.Net输出的JSON(对象数组)。
我向SiteKey对象添加了两个方法:
func loadJson(filename fileName: String) -> [SiteKey]
func writeJson(filename fileName: String, allSiteKeys : [SiteKey])
第一个函数采用指向json文件的字符串,并返回文件中的SiteKeys数组。 第二个函数采用文件名和SiteKey对象数组,并将它们写入文件。
这是带有附加功能的更改后的SiteKey类。
class SiteKey : Codable{
var Key : String
var MaxLength : Int
var HasSpecialChars : Bool
var HasUpperCase : Bool
init(key : String, maxLength : Int,
hasSpecialChars : Bool,
hasUpperCase : Bool){
Key = key;
MaxLength = maxLength;
HasSpecialChars = hasSpecialChars;
HasUpperCase = hasUpperCase;
}
func loadJson(filename fileName: String) -> [SiteKey]? {
if let url = Bundle.main.url(forAuxiliaryExecutable: fileName) {
do {
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
let allKeys = try decoder.decode([SiteKey].self, from: data)
return allKeys
} catch {
print("error:\(error)")
}
}
return nil
}
func writeJson(filename fileName: String, allSiteKeys : [SiteKey]){
let Data = try? JSONEncoder().encode(allSiteKeys)
let pathAsURL = URL(fileURLWithPath: fileName)
do {
try Data?.write(to: pathAsURL)
}
catch {
print("Failed to write JSON data: \(error.localizedDescription)")
}
}
}
用法如下:
let newSiteKey = siteKey.loadJson(filename: "/Users/fakeUser/Documents/Dev/all.json")
当loadJson方法返回时,newSiteKey将包含可以迭代的SiteKey类对象的数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.