Swift Codable:タイプ[String:Any]または[String:Decodable]の辞書をデコードできません

-3
投票

カスタム初期化子で、JSONから辞書をデコードし、その値をクラスのプロパティに割り当てたいと思います。驚いたことに、コンパイラーでは辞書をデコードできません。エラーが発生します。

カスタム初期化子で、JSONから辞書をデコードし、その値をクラスのプロパティに割り当てたいと思います。驚いたことに、コンパイラは辞書のデコードを許可していません。エラーが発生します。
Value of protocol type 'Any' cannot conform to 'Decodable'; only struct/enum/class types can conform to protocols
Value of protocol type 'Any' cannot conform to 'Decodable'; only struct/enum/class types can conform to protocols プロトコルタイプ「Any」の値は「Decodable」に準拠できません。プロトコルに準拠できるのは、struct/enum/classタイプのみです。

タイプ[文字列:デコード可能]の辞書をデコードしようとすると、エラーメッセージに次のように表示されます。

タイプ[文字列:デコード可能]の辞書をデコードしようとすると、エラーメッセージに次のように表示されます。
Value of protocol type 'Decodable' cannot conform to 'Decodable'; only struct/enum/class types can conform to protocols
Value of protocol type 'Decodable' cannot conform to 'Decodable'; only struct/enum/class types can conform to protocols プロトコルタイプ「Decodable」の値は「Decodable」に準拠できません。プロトコルに準拠できるのは、struct/enum/classタイプのみです。

初期化子は次のようになります:

初期化子は次のようになります:
public let total: Int

required init(from decoder: Decoder) throws {
    let container=try decoder.container(keyedBy: CodingKeys.self)
    ...
    if let dict=try container.decodeIfPresent([String: Any].self, forKey: .tracks),
           let value=dict["total"] as? Int { // Error is displayed at this line
        total=value
    } else {
        total=0
    }
    ...
}
public let total: Int required init(from decoder: Decoder) throws { let container=try decoder.container(keyedBy: CodingKeys.self) ... if let dict=try container.decodeIfPresent([String: Any].self, forKey: .tracks), let value=dict["total"] as? Int { // Error is displayed at this line total=value } else { total=0 } ... } public let total:Int 必要なinit(デコーダーから:デコーダー)は{をスローします コンテナを試してみてくださいdecoder.container(keyedBy:CodingKeys.self) ..。 if let dict=try container.decodeIfPresent([String:Any] .self、forKey:.tracks)、 値=dict["合計"]を? Int {//この行にエラーが表示されます 合計=値 } そうしないと { 合計=0 } ..。 }

答えを探したところ、ATAG-0が見つかりました|

答えを探したところ、this answerこの答えが見つかりました。それによると、上記のコードは問題を引き起こさないはずです。

ソース

swift ios codable

-Larme

1 -Larme

1 答える
1
投票

あなたが探しているのはnestedContainerです。 JSONの階層レベルを「スキップ」するのに役立ちます。つまり、コードではすべて同じレベル(1つの構造体)にあると想像してみましょう。ただし、JSONではそうではなく、サブディクショナリがあります。

テストの目的で、JSONは次のようになります。

プリコード-0|

モデルに必要な場合:

プリコード-1|

CADE-1を使用する必要があります|:

プリコード-2|

サンプルでは、​​CADE-2を使用しました|サブディクショナリーのために。それがテスト目的だったのか、それともサブ辞書が時々存在しなかったのかは不明です。 その場合、次のようなJSONを使用できます:

プリコード-3|

次に、nestedContainer(keyedBy: forKey:)を呼び出す前に、if container.contains(TopLevelKeys.tracks) {}を使用します。 CADE-5で必要に応じてデフォルト値を設定します|ケース。

ソース

興味があるかもしれません

© 2021   KonnichiwaSekai.Com