When attempting to parse the response from the Create Team call in Github's REST api, JSONDecoder
fails when parsing many of the snake cased keys for a Repository. When decoding through JSONSerialization
, it is able to find all keys without problem.
For example, when running in Playground in Xcode 11.0 (11A420a), the decoding fails when decoding with JSONDecoder
.
import Foundation
let jsonData = """
{
"id": 12345,
"name": "swift",
"ssh_url": "[email protected]:apple/swift.git"
}
""".data(using: .utf8)!
struct ExampleModel: Codable {
let id: Int
let name: String
let sshURL: String
}
let jsonObject = try! JSONSerialization.jsonObject(with: jsonData, options: []) as! [String: Any]
print("JSONSerialization:", jsonObject["id"]!, jsonObject["name"]!, jsonObject["ssh_url"]!)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let decodedObject = try! decoder.decode(ExampleModel.self, from: jsonData) // Fails here
print("JSONDecoder:", decodedObject.id, decodedObject.name, decodedObject.sshURL)
// Output:
//
// JSONSerialization: 12345 swift [email protected]:apple/swift.git
// Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "sshURL", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"sshURL\", intValue: nil) (\"sshURL\"), converted to ssh_url.", underlyingError: nil)): file MyPlayground.playground, line 22
Is there something different that I should be doing to parse this value?
Swift version:
Apple Swift version 5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)
Target: x86_64-apple-darwin19.0.0
Try changing sshURL
to sshUrl
. The keyDecodingStartegy
will transform sshURL
into ssh_URL
, which doesn't match your key. sshUrl
will be transformed into ssh_url
, which will match your key.