私はいくつかの JSON 解析コードを新しい AppleDecodable
プロトコルを使用するように変換し始めており、Apple のテスト中に見逃すにはあまりにも基本的なブロッカーにぶつかったので、何かばかげたことをしているのではないかと思っています。要するに、私はこのような JSON グラフを解析しようとしています。私はデコードしているだけなので、Decodable に準拠するだけで十分だと思いましたが、エラーから、希望するものを取得するには Codable (Decodable & Encodable) に準拠する必要があるようです。デコード効果:
{"keyString": {"nestedKey1" : "value1", "nestedKey1" : "value1" } }
このケースで動作します:
{"keyString": [{"nestedKey1" : "value1", "nestedKey1" : "value1" } ]}
ネストされたオブジェクトの配列ですが、単一のオブジェクトではありません。
これは Swift のバグですか、それとも何か問題がありますか?
問題を証明できるサンプルのプレイグラウンドを次に示します。Animal クラスが準拠してDecodable
いる場合、配列のケースは解析されませんが、Animal を準拠するように設定するCodable
と機能します。ここでは JSON をデコードしているだけなので、これが当てはまるとは思いません。
import Foundation
//class Animal: Codable {
class Animal: Decodable {
var fileURLPath: String = ""
var age: Double = 0
var height: Double = 0
var weight: Double = 0
private enum CodingKeys: String, CodingKey {
case fileURLPath = "path"
case age
case height
case weight
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
fileURLPath = try values.decode(String.self, forKey: .fileURLPath)
age = try values.decode(TimeInterval.self, forKey: .age)
height = try values.decode(Double.self, forKey: .height)
weight = try values.decode(Double.self, forKey: .weight)
}
}
let innerObjectJSON = """
{
"path": "tiger_pic.png",
"age": 9,
"height": 1.23,
"weight": 130
}
"""
let innerObjectData = innerObjectJSON.data(using: String.Encoding.utf8)
let jsonDataNestedObject = """
{ "en" : \(innerObjectJSON)
}
""".data(using: String.Encoding.utf8)
let jsonDataNestedArray = """
{ "en" : [\(innerObjectJSON), \(innerObjectJSON), \(innerObjectJSON) ]
}
""".data(using: String.Encoding.utf8)
print("Nested Array of Objects:")
do {
let result = try JSONDecoder().decode([String: [Animal]].self, from: jsonDataNestedArray!)
result["en"]!.forEach ({ print($0.fileURLPath) }) // This one works
} catch { print(error) }
print("\n\n Single Object:")
do {
let result = try JSONDecoder().decode(Animal.self, from: innerObjectData!)
print(result.fileURLPath)
} catch { print(error) }
print("\n\nNested Object:")
do {
let result = try JSONDecoder().decode([String: Animal].self, from:jsonDataNestedObject!)
print(result["en"]!.fileURLPath) // I would also expect this to work but I get the error: "fatal error: Dictionary<String, Animal> does not conform to Decodable because Animal does not conform to Decodable.: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.45.6/src/swift/stdlib/public/core/Codable.swift, line 3420"
} catch { print(error) }