问题
I'm trying to implement a Decodable to parse a json request but the json request has a dictionary inside of the object.
Here is my code:
struct myStruct : Decodable {
let content: [String: Any]
}
enum CodingKeys: String, CodingKey {
case content = "content"
}
But I'm getting this error:
Type 'MyClass.myStruct' does not conform to protocol 'Decodable'
How can declare a variable as dictionary without this error?
I'll really appreciate your help
回答1:
You cannot currently decode a [String: Any]
with the Swift coding framework. You'll need to drop to a lower-level deserialization strategy and decode “by hand” if you need to decode a [String: Any]
. For example, if your input is JSON, you can use Foundation's JSONSerialization
or a third-party library like SwiftyJSON.
There has been discussion of this issue on Swift Evolution: “Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4”. Apple's main Coding/Codable programmer, Itai Ferber, has been involved in the discussion and is interested in providing a solution, but it is unlikely to happen for Swift 5 (which will probably be announced at WWDC 2018 and finalized around September/October 2018).
You could copy the implementation of JSONDecoder (it's open source) into your project and modify it to add the ability to get an unevaluated [String: Any]
. Itai discusses the required modifications in the thread I linked above.
回答2:
Well... technically you could do this but it will require you to use a third party component SwiftyJSON for the dictionary representation.
Also, I am assuming you're doing this because content
might have non-normalized data and that you intentionally want to treat it as a dictionary.
In that case, go ahead with this:
import SwiftyJSON
struct MyStruct : Decodable {
//... your other Decodable objects like
var name: String
//the [String:Any] object
var content: JSON
}
Here, JSON
is the SwiftyJSON object that will stand in for your dictionary. Infact it would stand in for an array too.
Working Example:
let jsonData = """
{
"name": "Swifty",
"content": {
"id": 1,
"color": "blue",
"status": true,
"details": {
"array" : [1,2,3],
"color" : "red"
}
}
}
""".data(using: .utf8)!
do {
let test = try JSONDecoder().decode(MyStruct.self,
from: jsonData)
print(test)
}
catch {
print(error)
}
来源:https://stackoverflow.com/questions/50029665/dictionary-of-stringany-does-not-conform-to-protocol-decodable