Dar*_*rko 5 json swift codable decodable
我想在Swift Coding / Encoding功能完成对JSON的解码后做一些初始化逻辑。
struct MyStruct: Codable {
let id: Int
var name: String
init() {
name = "\(id) \(name)"
}
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了编译器错误:
Return from initializer without initializing all stored properties
Run Code Online (Sandbox Code Playgroud)
这对我很清楚,因为init()希望我初始化所有属性。但是添加具有所有必需属性的init()并不能解决该问题,因为当Codable插入时,此初始化器不会被调用(!):
init(id: Int, name: String) {
// This initializer is not called if Decoded from JSON!
self.id = id
self.name = "\(id) \(name)"
}
Run Code Online (Sandbox Code Playgroud)
然而,在解码完成之后,是否有一种方法可以执行一些初始化逻辑,而无需为每个属性手动进行所有解码?因此无需每次都执行init(from decoder: Decoder)。在这个简短的示例中,我只有两个简单的属性,但是生产代码包含数千个属性。
谢谢。
vad*_*ian 10
您可以免费但标准化地获得所有内容,或者必须编写类似的自定义初始化程序
struct MyStruct: Codable {
let id: Int
var name: String
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
let decodedName = try container.decode(String.self, forKey: .name)
name = "\(id) \(decodedName)"
}
}
Run Code Online (Sandbox Code Playgroud)
您可以实现,init()但这独立于解码功能而起作用,并且您必须为所有非可选属性分配默认值,这就是错误的含义。
使用首先使用init(from:)然后调用自定义初始化代码的工厂方法
struct Foo: Decodable {
let name: String
let id: Int
var x: String!
private mutating func finalizeInit() {
self.x = "\(name) \(id)"
}
static func createFromJSON(_ data: Data) -> Foo? {
guard var f = try? JSONDecoder().decode(Foo.self, from: data) else {
return nil
}
f.finalizeInit()
return f
}
}
let sampleData = """
{ "name": "foo", "id": 42 }
""".data(using: .utf8)!
let f = Foo.createFromJSON(sampleData)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8106 次 |
| 最近记录: |