KeyDecodingStrategy .convertFromSnakeCase 不起作用
KeyDecodingStrategy .convertFromSnakeCase doesn't work
我有一个名为 ServiceHealthApi 的适配器 class,它具有以下功能:
final class ServiceHealthApi {
let mockApi = "https://staging.myapp.com/health"
func getHealth() -> Single<ServiceHealthResponseModel> {
let url = URL(string: mockApi)
guard let validUrl = url else { return .never() }
var urlRequest = URLRequest(url: validUrl)
urlRequest.httpMethod = "GET"
let headers = [
"Content-Type" : "application/json; charset=utf-8"
]
urlRequest.allHTTPHeaderFields = headers
return URLSession.shared.rx.data(request: urlRequest)
.take(1)
.map {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return try JSONDecoder().decode(ServiceHealthResponseModel.self, from: [=10=]) }
.asSingle()
}
}
struct HealthResponseModel: Decodable {
struct DataResponse: Decodable {
let serviceName: String
let serviceStatus: String
let serviceOperational: Bool
}
struct Meta: Decodable {
let statusCode: Int
let statusMessage: String
}
let data: [DataResponse]
let meta: Meta
}
要解析的JSON
字符串是这样的:
{
"data": [
{
"service_name": "web",
"service_status": "UP",
"service_operational": true
},
{
"service_name": "orm",
"service_status": "UP",
"service_operational": true
}
],
"meta": {
"status_code": 200,
"status_message": "OK"
}
}
现在,当我尝试 运行 我的集成测试时,它因来自 JSONDecoder
:
的错误而失败
error keyNotFound(CodingKeys(stringValue: "serviceName", intValue:
nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue:
"data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue:
0)], debugDescription: "No value associated with key
CodingKeys(stringValue: \"serviceName\", intValue: nil)
(\"serviceName\").", underlyingError: nil))
有趣的是,如果我禁用 .convertFromSnakeCase,并且只对响应模型中的变量名使用驼峰式命名法,它工作得很好。我知道我可能可以使用编码键,但我只是想知道,为什么我的实现不起作用?
提前致谢。
PS:我试过直接解析 JSON
字符串而不调用 API
,它确实有效。
您正在创建第二个 JSONDecoder
,没有任何策略
替换
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return try JSONDecoder().decode(ServiceHealthResponseModel.self, from: [=10=]) }
与
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return try decoder.decode(ServiceHealthResponseModel.self, from: [=11=]) }
我有一个名为 ServiceHealthApi 的适配器 class,它具有以下功能:
final class ServiceHealthApi {
let mockApi = "https://staging.myapp.com/health"
func getHealth() -> Single<ServiceHealthResponseModel> {
let url = URL(string: mockApi)
guard let validUrl = url else { return .never() }
var urlRequest = URLRequest(url: validUrl)
urlRequest.httpMethod = "GET"
let headers = [
"Content-Type" : "application/json; charset=utf-8"
]
urlRequest.allHTTPHeaderFields = headers
return URLSession.shared.rx.data(request: urlRequest)
.take(1)
.map {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return try JSONDecoder().decode(ServiceHealthResponseModel.self, from: [=10=]) }
.asSingle()
}
}
struct HealthResponseModel: Decodable {
struct DataResponse: Decodable {
let serviceName: String
let serviceStatus: String
let serviceOperational: Bool
}
struct Meta: Decodable {
let statusCode: Int
let statusMessage: String
}
let data: [DataResponse]
let meta: Meta
}
要解析的JSON
字符串是这样的:
{
"data": [
{
"service_name": "web",
"service_status": "UP",
"service_operational": true
},
{
"service_name": "orm",
"service_status": "UP",
"service_operational": true
}
],
"meta": {
"status_code": 200,
"status_message": "OK"
}
}
现在,当我尝试 运行 我的集成测试时,它因来自 JSONDecoder
:
error keyNotFound(CodingKeys(stringValue: "serviceName", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"serviceName\", intValue: nil) (\"serviceName\").", underlyingError: nil))
有趣的是,如果我禁用 .convertFromSnakeCase,并且只对响应模型中的变量名使用驼峰式命名法,它工作得很好。我知道我可能可以使用编码键,但我只是想知道,为什么我的实现不起作用?
提前致谢。
PS:我试过直接解析 JSON
字符串而不调用 API
,它确实有效。
您正在创建第二个 JSONDecoder
,没有任何策略
替换
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return try JSONDecoder().decode(ServiceHealthResponseModel.self, from: [=10=]) }
与
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
return try decoder.decode(ServiceHealthResponseModel.self, from: [=11=]) }