Edw*_*eer 3 json init swift4 codable decodable
我正在尝试创建一个Codable扩展,它能够仅使用json字符串初始化Decodable(Swift 4)对象.那应该是什么工作:
struct MyObject: Decodable {
var title: String?
}
let myObject = MyObject(json: "{\"title\":\"The title\"}")
Run Code Online (Sandbox Code Playgroud)
我认为这意味着我应该创建一个使用Decoder调用self.init的init.这是我提出的代码:
public init?(json: String) throws {
guard let decoder: Decoder = GetDecoder.decode(json: json)?.decoder else { return }
try self.init(from: decoder) // Who what should we do to get it so that we can call this?
}
Run Code Online (Sandbox Code Playgroud)
该代码能够获取解码器,但是在调用init时出现编译器错误.我得到的错误是:
在self.init电话之前使用'self'
这是否意味着无法在Decodable协议中添加init?
更新:
从@appzYourLive调试下面的解决方案后,我发现我与init(json:Decodable和Array上的初始化程序有冲突.我刚刚向GitHub发布了新版本的扩展.我还添加了解决方案作为这个问题的新答案.
一种可能的解决方法
可能的解决方案是定义另一个协议
protocol DecodableFromString: Decodable { }
Run Code Online (Sandbox Code Playgroud)
有自己的初始化程序
extension DecodableFromString {
init?(from json: String) throws {
guard let data = try json.data(using: .utf8) else { return nil }
guard let value = try? JSONDecoder().decode(Self.self, from: data) else { return nil }
self = value
}
}
Run Code Online (Sandbox Code Playgroud)
现在你需要使你的类型符合 DecodableFromString
struct Person:Codable, DecodableFromString {
let firstName: String
let lastName: String
}
Run Code Online (Sandbox Code Playgroud)
最后给了一个JSON
let json = """
{
"firstName": "Luke",
"lastName": "Skywalker"
}
"""
Run Code Online (Sandbox Code Playgroud)
你可以建立自己的价值
if let luke = try? Person(from: json) {
print(luke)
}
Run Code Online (Sandbox Code Playgroud)
人(名字:"卢克",姓氏:"天行者")
| 归档时间: |
|
| 查看次数: |
3054 次 |
| 最近记录: |