2

JSON があるとします。

{
    "status": "error",
    "data": {
        "errormessage": "Could not get user with ID: -1.",
        "errorcode": 14
    }
}

特定の Error 構造体の場合:

struct APIError: Decodable {
    let code: Int?
    let message: String?

    enum CodingKeys: String, CodingKey {
        case code = "errorcode"
        case message = "errormessage"
    }
}

Web サービスにアクセスし、JSON を取得して、構造体を初期化します。

let urlRequest = URLRequest(url: url)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest)
{ (data, response, error) in
    // Doesn't work because the portion of the JSON we want is in the "data" key
    let e = try? JSONDecoder().decode(APIError.self, from: data)
}
task.resume()

のようなことをする簡単な方法はありますdata["data"]か? 従うべき正しいモデルは何ですか?

解決策 A - データを JSON オブジェクトに変換し、必要なオブジェクトを取得してから、それを Data オブジェクトに変換してデコードします。

let jsonFull = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any]
let json = jsonFull["data"]
let data_error = try? JSONSerialization.data(withJSONObject: json, options: [])
let e = try? JSONDecoder().decode(APIError.self, from: data_error)

解決策 B - ターゲット項目を別の構造体でラップする

struct temp : Decodable {
    let status: String?
    let data: APIError?
}

let e = try? JSONDecoder().decode(temp.self, from: data).data

ソリューション C - ネストされた構造をデコードに設定します (複数のオブジェクトの深さがある場合はどうなりますか?)

let e = try? JSONDecoder().decode([Any, APIError.self], from: data)

不足しているパターンは何ですか? これを行う最もエレガントな方法は何ですか?

4

1 に答える 1