My Swift 5(Xcode 11.5(应用程序将人员保存在文本文件(json格式(中。
我用来解码json文本的struct
:
struct People:Codable {
var groupName:String
var groupLocation:String
var members:[Person]
init(_ gn:String,_ gl:String,_ m:[Person] {
groupName = gn
groupLocation = gl
members = m
}
struct Person:Codable {
var name:String
var age:Int
var profession:String?
init(_ n:String,_ a:Int,_ p:String?) {
name = n
age = a
profession = (p==nil) ? "none" : p!
}
}
解码文本文件的内容:
let jsonData = Data(text.utf8)
let decoder = JSONDecoder()
let people = try decoder.decode(People.self, from: jsonData)
let members = people.members
for (i,member) in members.enumerated() {
//print(member.profession==nil)
//Do stuff
}
profession
是后来添加的,将来可能还会添加更多值,但我希望我的应用程序向后兼容旧文件。如果profession
不存在,它应该使用"none"
(参见上面的代码(,但当我在解码后检查member.profession
时,它仍然是nil
。name
、age
,。。。所有这些都包含正确的值,因此部分可以工作。
如果在json文件中不存在profession
,我如何在结构中给它一个值?做这件事最简单/最干净的方法是什么?如果有必要,我也可以稍后添加(例如生日、性别…(?
如果您需要以Codable
之外的其他方式解析JSON,则需要实现自定义初始值设定项init(from:)
,即
struct Person:Codable {
var name:String
var age:Int
var profession: String
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
self.age = try container.decode(Int.self, forKey: .age)
if let profession = try container.decodeIfPresent(String.self, forKey: .profession) {
self.profession = profession
} else {
self.profession = "none"
}
}
}
此外,由于您总是为profession
给定一个值,因此无需将其设为optional
。