gpt4 book ai didi

json - 当类型正确时,可解码类型上的 typeMismatch

转载 作者:行者123 更新时间:2023-11-30 11:13:55 26 4
gpt4 key购买 nike

当我使用 Postman 调用配置 API 时,我收到以下 json 响应。在此响应中,两个 apiVersion 键是数字而不是字符串。

{
"data": {
"availability": {
"auth": true,
"ab": true,
"cd": true
},
"helloWorldConfiguration": {
"apiKey": "abcefg",
"rootUrl": "https://foo",
"apiVersion": 3
},
"fooBarConfiguration": {
"baseUrl": "https://foo",
"apiVersion": 1,
"privateApiPath": "",
"publicApiPath": "dev",
"tokenPath": ""
}
},
"errors": []
}

当我尝试解码它时,它失败并出现 typeMismatch 错误。当我输出响应的内容时,我看到以下内容,对我来说看起来不错。

data = {
availability = {
auth = 1;
ab = 1;
cd = 1;
};
helloWorldConfiguration = {
apiVersion = 1;
baseUrl = "https://foo";
privateApiPath = "";
publicApiPath = dev;
tokenPath = "";
};
fooBarConfiguration = {
apiKey = abcefg;
apiVersion = 3;
rootUrl = "https://foo";
};
};
errors = (
);

给我的错误表明data.helloWorldConfiguration.apiVersion是字符串类型而不是int类型。从 Postman 收到的原始 HTTP 响应中我们可以看到情况并非如此。

typeMismatch(Swift.Int, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), CodingKeys(stringValue: "helloWorldConfiguration", intValue: nil), CodingKeys(stringValue: "apiVersion", intValue: nil)], debugDescription: "Expected to decode Int but found a string/data instead.", underlyingError: nil)) 21:17:40 ERROR Unable to decode the response data into a model representation.

我的模型将这些属性表示为整数,因此看起来它接收到响应并将这些数字视为字符串,但事实并非如此。

public struct ServerConfiguration: Decodable {
let availability: AvailabilityConfiguration
let helloWorldConfiguration: HelloWorldConfiguration
let fooBarConfiguration: FooBarConfiguration

init(availability: AvailabilityConfiguration, helloWorldConfiguration: HelloWorldConfiguration, fooBarConfiguration: FloatSinkConfiguration) {
self.availability = availability
self.helloWorldConfiguration = helloWorldConfiguration
self.fooBarConfiguration = fooBarConfiguration
}
}

public struct FooBarConfiguration: Decodable {
let baseUrl: String
let apiVersion: Int
let privateApiPath: String
let publicApiPath: String
let tokenPath: String

init(baseUrl: String, apiVersion: Int, privateApiPath: String, publicApiPath: String, tokenPath: String) {
self.baseUrl = baseUrl
self.apiVersion = apiVersion
self.privateApiPath = privateApiPath
self.publicApiPath = publicApiPath
self.tokenPath = tokenPath
}
}

public struct AvailabilityConfiguration: Decodable {
let auth: Bool
let ab: Bool
let cd: Bool

init(auth: Bool, ab: Bool, cd: Bool) {
self.auth = auth
self.ab = ab
self.cd = cd
}
}

public struct HelloWorldConfiguration: Codable {
let apiKey: String
let rootUrl: String
let apiVersion: Int

init(apiKey: String, rootUrl: String, apiVersion: Int) {
self.apiKey = apiKey
self.rootUrl = rootUrl
self.apiVersion = apiVersion
}
}

如您所见,我的 apiVersion 成员和 json 响应都是整数类型。我在这里做错了什么?我假设发生的情况是 Swift 正在考虑 json 字符串中的数字,无论它们在 json 中实际如何表示。是这样吗?

编辑以显示 Alamofire 响应数据的 utf8 字符串

21:44:06 INFO GET: https:foo/configuration
{
"data" : {
"availability" : {
"auth" : true,
"ab" : true,
"cb" : true
},
"helloWorldConfiguration" : {
"apiKey" : "abcd",
"rootUrl" : "https://foo",
"apiVersion" : "3"
},
"fooBarConfiguration" : {
"baseUrl" : "https://foo",
"apiVersion" : "1",
"privateApiPath" : "",
"publicApiPath" : "dev",
"tokenPath" : "auth/token"
}
},
"errors" : []
}

看起来,尽管 API 正确地将 apiVersion 返回为数字,但 Swift 却将其转换为字符串。我解码错误吗?

func getRoute<TResponseData: Decodable>(route:String, completion: @escaping (TResponseData) -> Void) throws {
let headers = try! self.getHeaders(contentType: ContentType.json)
let completeUrl: String = self.getUrl(route: route, requestUrl: nil)
logger.info("GET: \(completeUrl)")
Alamofire.request(
completeUrl,
method: .get,
parameters: nil,
encoding: JSONEncoding.default,
headers: headers)
.validate()
.responseJSON { (response) -> Void in
self.logger.info("GET Response: \(String(describing:response.response?.statusCode))")

switch response.result {
case .success(_):
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(Date.toFooBarDate)
do {
let result = try decoder.decode(TResponseData.self, from: response.data!)
completion(result)
} catch DecodingError.dataCorrupted(let error) {
self.logger.error(error.underlyingError!)
return
} catch {
print(response.result.value!)
print(error)
self.logger.error("Unable to decode the response data into a model representation.")
return
}
}
}

最佳答案

我检查了我的 Playground ,似乎一切正常。要找到真正的问题,我认为您需要提供获取 json 的真实网址,并且可以使用 alamofire 检查

import Foundation
let json = """
{
"data": {
"availability": {
"auth": true,
"ab": true,
"cd": true
},
"helloWorldConfiguration": {
"apiKey": "abcefg",
"rootUrl": "https://foo",
"apiVersion": 3
},
"fooBarConfiguration": {
"baseUrl": "https://foo",
"apiVersion": 1,
"privateApiPath": "",
"publicApiPath": "dev",
"tokenPath": ""
}
},
"errors": []
}
"""
let data = json.data(using: .utf8)


struct Response : Codable {
let data : Data?
let errors : [String]?
}
struct Availability : Codable {
let auth : Bool?
let ab : Bool?
let cd : Bool?
}

struct Data : Codable {
let availability : Availability?
let helloWorldConfiguration : HelloWorldConfiguration?
let fooBarConfiguration : FooBarConfiguration?
}

struct FooBarConfiguration : Codable {
let baseUrl : String?
let apiVersion : Int?
let privateApiPath : String?
let publicApiPath : String?
let tokenPath : String?
}
struct HelloWorldConfiguration : Codable {
let apiKey : String?
let rootUrl : String?
let apiVersion : Int?
}


let decoder = JSONDecoder()

let response = try decoder.decode(Response.self, from: data!)
print(response)

这是回复

响应(数据:可选(__lldb_expr_11.Data(可用性:可选(__lldb_expr_11.Availability(auth:可选(true)),ab:可选(true),cd:可选(true))),helloWorldConfiguration:可选(__lldb_expr_11. HelloWorldConfiguration(apiKey:可选(“abcefg”),rootUrl:可选(“https://foo”),apiVersion:可选(3))),fooBarConfiguration:可选(__lldb_expr_11.FooBarConfiguration(baseUrl:可选(“https://foo”), apiVersion:可选(1),privateApiPath:可选(“”),publicApiPath:可选(“dev”),tokenPath:可选(“”))))),错误:可选([]))

关于json - 当类型正确时,可解码类型上的 typeMismatch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51924195/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com