1

エラーオブジェクトまたは期待値のいずれかが含まれているstatus値と値を含む連想配列で応答をラップする API があります。datadata

悪い反応:

{
   "status":"error",
   "data":{  
      "errormessage":"Duplicate entry '101' for key 'PRIMARY'",
      "errorcode":1062
   }
}

正常な応答:

{
   "status":"success",
   "data":{  
      "user": {
        "id": 1,
      }
   }
}

これらの応答を検証したい:

public class func validateResponse(_ data : Data) -> WebServicesError?
{
    struct WTPResponse : Decodable
    {
        let status : String
        let data : Data
    }

    do {
        let response = try JSONDecoder().decode(WTPResponse.self, from: data) // FAILS HERE
        if let wtpError = try? JSONDecoder().decode(WTPAPIError.self, from: response.data) {
            return WebServicesError.wtpError(WTPAPIError(code: wtpError.code, message: wtpError.message))
        }
    }
    catch let error {
        return WebServicesError.init(error: error)
    }

    return nil
}

エラーで応答オブジェクトをデコードしようとすると、常に失敗します:オブジェクトを Swift type としてExpected to decode Data but found a dictionary instead.デコードできると思っていましたが、実際には辞書です。dataData[String: Any]

Data1) API から受け取った をどのように検証できますか?

data2) JSON 応答の " " 部分のみDataを型として抽出できる方法はありUserますか?statusdata

4

4 に答える 4

1

応答タイプごとに個別のモデルを生成するために、 quicktype のマルチソース モードを使用しました。Codable

マルチモード

そして、これがコードです。最初にa のデコードを試みることResponseができます。それが失敗した場合は、a のデコードを試みることができますBadResponse

// let response = try? JSONDecoder().decode(Response.self, from: jsonData)
// let badResponse = try? JSONDecoder().decode(BadResponse.self, from: jsonData)

import Foundation

struct Response: Codable {
    let status: String
    let data: ResponseData
}

struct ResponseData: Codable {
    let user: User
}

struct BadResponse: Codable {
    let status: String
    let data: BadResponseData
}

struct BadResponseData: Codable {
    let errormessage: String
    let errorcode: Int
}

struct User: Codable {
    let id: Int
}

単体で表現しようとするよりも、こちらの方がすっきりしていると思います。また、JSON を選択的にデコードするのではなく、すべてをデコードしてから、必要なデータをこれらの型から選択することもお勧めします。

于 2018-02-04T04:04:45.297 に答える