I'm trying to use swift 4 to parse a local json file:
{
"success": true,
"lastId": null,
"hasMore": false,
"foundEndpoint": "https://endpoint",
"error": null
}
This is the function I'm using:
func loadLocalJSON() {
if let path = Bundle.main.path(forResource: "localJSON", ofType: "json") {
let url = URL(fileURLWithPath: path)
do {
let data = try Data(contentsOf: url)
let colors = try JSONDecoder().decode([String: Any].self, from: data)
print(colors)
}
catch { print("Local JSON not loaded")}
}
}
}
but I keep getting the error:
Fatal error: Dictionary does not conform to Decodable because Any does not conform to Decodable.
I tried using the "AnyDecodable" approach on this stackoverflow page: How to decode a property with type of JSON dictionary in Swift 4 decodable protocol but it jumps to the 'catch' statement: catch { print("Local JSON not loaded")
when being used. Does anyone know how to parse this JSON data in Swift 4?
Maybe you are misunderstanding how Codable
works. It's based on concrete types. Any
is not supported.
In your case you might create a struct like
struct Something: Decodable {
let success : Bool
let lastId : Int?
let hasMore: Bool
let foundEndpoint: URL
let error: String?
}
And decode the JSON
func loadLocalJSON() {
let url = Bundle.main.url(forResource: "localJSON", withExtension: "json")!
let data = try! Data(contentsOf: url)
let colors = try! JSONDecoder().decode(Something.self, from: data)
print(colors)
}
Any crash will reveal a design error. The sense of using null
in a file in the main bundle is another question.
I used quicktype to generate Codables and marshaling code:
https://app.quicktype.io?gist=02c8b82add3ced7bb419f01d3a94019f&l=swift
I gave it an array of samples based on your sample data:
[
{
"success": true,
"lastId": null,
"hasMore": false,
"foundEndpoint": "https://endpoint",
"error": null
},
{
"success": true,
"lastId": 123,
"hasMore": false,
"foundEndpoint": "https://endpoint",
"error": "some error"
}
]
This tells quicktype to assume that the null
values in your first sample are sometimes Int
and String
– you can change these if they aren't the possible types. The resulting Codable generated is:
struct Local: Codable {
let success: Bool
let lastID: Int?
let hasMore: Bool
let foundEndpoint: String
let error: String?
enum CodingKeys: String, CodingKey {
case success
case lastID = "lastId"
case hasMore, foundEndpoint, error
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.