Swift 4 JSONDecoder 解码协议类型
Posted
技术标签:
【中文标题】Swift 4 JSONDecoder 解码协议类型【英文标题】:Swift 4 JSONDecoder decode a protocol type 【发布时间】:2017-10-14 03:20:11 【问题描述】:以下代码无法编译:
public protocol Foo: Decodable
var message: String get
struct Bar: Foo
let message: String
// the type conforming Foo protocol is passed from somewhere
let type: Foo.Type = Bar.self
decode(type: type, from: Data())
func decode<T>(type: T.Type, from data: Data) Where T: Decodable
let decoder = JSONDecoder()
try! decoder.decode(type, from: data)
它抛出错误:
Cannot invoke 'decode' with an argument list of type '(Foo.Type, from: Data)'
你们有什么想法吗?
【问题讨论】:
我需要像这样将参数约束到协议中:func decode<T: Foo>(type: T, from data: Data) let decoder = JSONDecoder() try! decoder.decode(type, from: data)
@3stud1ant3 decode(type: Bar.self, from: data)
throws Cannot invoke 'decode' with an argument list of type '(T, from: Data)'
JSONEncoder
/ JSONDecoder
期望具体类型,您不能使用协议类型。
比较***.com/q/44441223/2976878
@akabc 你找到解决方案了吗?
【参考方案1】:
你可以这样使用:
public protocol Foo: Decodable
var message: String get
struct Bar: Foo
let message: String
class ViewController: UIViewController
let bar = """
"message": "Sample message"
"""
override func viewDidLoad()
super.viewDidLoad()
let type = Bar.self
decode(type: type, from: bar.data(using: .utf8)!)
func decode<Foo>(type: Foo.Type, from data: Data) where Foo: Decodable
let decoder = JSONDecoder()
let parsedData = try! decoder.decode(type, from: data)
print(parsedData)
【讨论】:
如何编译?let type: Foo.Type = Bar.self decode(type: type, from: bar.data(using: .utf8)!)
,是因为type是从某个地方传过来的,具体类型未知,我只知道符合Foo
您有什么问题吗?【参考方案2】:
您应该在您的Bar
上使用Codable
来代替:
protocol Foo
var message: String get
struct Bar: Foo, Codable
let message: String
用法:
let bar = Bar(message: "Just a message")
if let data = try? JSONEncoder().encode(bar)
print(String(data:data, encoding:.utf8) ?? "") // "message":"Just a message"\n"// lets decode it
if let decodedBar = try? JSONDecoder().decode(Bar.self, from: data)
print(decodedBar.message) //"Just a message\n"
【讨论】:
我希望从某处传递 decode(type) 的参数 你为什么想要那个?只需在要解码的任何地方使用使用代码即可。 我想要Bar.self
可以传递给这个函数func decode(type: Foo.Type, from data: Data)
以上是关于Swift 4 JSONDecoder 解码协议类型的主要内容,如果未能解决你的问题,请参考以下文章
如何在 swift 4.1 和 xcode 9.3 中使用 JSONDecoder 解码嵌套的 JSON 数组和对象?
iOS - JSONEncoder和JSONDecoder介绍
如何在 swift 4 中使用 JSONDecoder 从嵌套 JSON 中获取数据?