Codable 数组和 Alamofire 的问题
Issues with Codable Arrays and Alamofire
我正尝试通过 Alamofire 提交以下请求,但收到以下错误:
2020-01-13 09:41:05.912103-0600 AFNetworkingDemo[29720:604258] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'
我的假设是这是我在对象中定义数组的方式(我正在关注此处找到的一些 material:https://benscheirman.com/2017/06/swift-json)
struct ProgramRequest: Codable {
var userID: Int
var programData: ProgramData
var json: Constants.Json {
return [
"userID": userID,
"programData": programData.json,
]
}
}
struct ProgramData: Codable {
var airhotel: [AirHotel]
var security: [Security]
var json: Constants.Json {
return [
"airhotel": airhotel,
"security": security
]
}
}
struct AirHotel: Codable {
var id: Int
var loyaltyNumber: String
var json: Constants.Json {
return [
"id": id,
"loyaltyNumber": loyaltyNumber
]
}
}
struct Security: Codable {
var vendorCode: String
var loyaltyNumber: String
var json: [String: Any] {
return [
"vendorCode": vendorCode,
"loyaltyNumber": loyaltyNumber
]
}
}
每个级别的 json 字典是为 Alamofire 适当地渲染对象。对于给定的示例,如果我使用以下方式打印出来:
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let jsonData = try jsonEncoder.encode(programRequest)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString) #1
}
print("IsValidJSON: ", JSONSerialization.isValidJSONObject(programRequest)) #2
print(programRequest.json) #3
urlRequest = try! JSONEncoding.default.encode(urlRequest, with: programRequest.json) #4 causes error
1 输出:
{
"userID" : 10021,
"programData" : {
"airhotel" : [],
"security" : [
{
"vendorCode" : "sty",
"loyaltyNumber" : "Loyal1"
}
]
}
}
2输出
IsValidJSON: false
3 输出 - 我注意到输出中的 AFNetworkingDemo.Security 是什么 Alamofire JSONEncoding on:
["programData": ["security": [AFNetworkingDemo.Security(vendorCode: "sty", loyaltyNumber: "Loyal1")], "airhotel": []], "userID": 10021]
我的问题是,我需要对 ProgramRequest 的 AirHotel 和安全部分进行哪些更改才能解决我与 Alamofire 的问题?
第 1 步:停止重新发明 Codable
json 计算的 属性 不需要并且被错误使用。
删除它。
struct ProgramRequest: Codable {
var userID: Int
var programData: ProgramData
}
struct ProgramData: Codable {
var airhotel: [AirHotel]
var security: [Security]
}
struct AirHotel: Codable {
var id: Int
var loyaltyNumber: String
}
struct Security: Codable {
var vendorCode: String
var loyaltyNumber: String
}
第 2 步:开始使用 Codable
现在给定一个 programRequest
,例如。像这样
let programRequest = ProgramRequest(userID: 1, programData: ProgramData(airhotel: [AirHotel(id: 1, loyaltyNumber: "loyaltyNumber")], security: [Security(vendorCode: "loyaltyNumber", loyaltyNumber: "loyaltyNumber")]))
您可以生成代表 JSON 的正确数据值,只需编写
let data = try JSONEncoder().encode(programRequest)
并且(如果需要)您可以将数据转换为字符串
let json = String(data: data, encoding: .utf8)
输出
Optional("{\"userID\":1,\"programData\":{\"airhotel\":[{\"id\":1,\"loyaltyNumber\":\"loyaltyNumber\"}],\"security\":[{\"vendorCode\":\"loyaltyNumber\",\"loyaltyNumber\":\"loyaltyNumber\"}]}}")
就是这样
我正尝试通过 Alamofire 提交以下请求,但收到以下错误:
2020-01-13 09:41:05.912103-0600 AFNetworkingDemo[29720:604258] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'
我的假设是这是我在对象中定义数组的方式(我正在关注此处找到的一些 material:https://benscheirman.com/2017/06/swift-json)
struct ProgramRequest: Codable {
var userID: Int
var programData: ProgramData
var json: Constants.Json {
return [
"userID": userID,
"programData": programData.json,
]
}
}
struct ProgramData: Codable {
var airhotel: [AirHotel]
var security: [Security]
var json: Constants.Json {
return [
"airhotel": airhotel,
"security": security
]
}
}
struct AirHotel: Codable {
var id: Int
var loyaltyNumber: String
var json: Constants.Json {
return [
"id": id,
"loyaltyNumber": loyaltyNumber
]
}
}
struct Security: Codable {
var vendorCode: String
var loyaltyNumber: String
var json: [String: Any] {
return [
"vendorCode": vendorCode,
"loyaltyNumber": loyaltyNumber
]
}
}
每个级别的 json 字典是为 Alamofire 适当地渲染对象。对于给定的示例,如果我使用以下方式打印出来:
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let jsonData = try jsonEncoder.encode(programRequest)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString) #1
}
print("IsValidJSON: ", JSONSerialization.isValidJSONObject(programRequest)) #2
print(programRequest.json) #3
urlRequest = try! JSONEncoding.default.encode(urlRequest, with: programRequest.json) #4 causes error
1 输出:
{
"userID" : 10021,
"programData" : {
"airhotel" : [],
"security" : [
{
"vendorCode" : "sty",
"loyaltyNumber" : "Loyal1"
}
]
}
}
2输出 IsValidJSON: false
3 输出 - 我注意到输出中的 AFNetworkingDemo.Security 是什么 Alamofire JSONEncoding on:
["programData": ["security": [AFNetworkingDemo.Security(vendorCode: "sty", loyaltyNumber: "Loyal1")], "airhotel": []], "userID": 10021]
我的问题是,我需要对 ProgramRequest 的 AirHotel 和安全部分进行哪些更改才能解决我与 Alamofire 的问题?
第 1 步:停止重新发明 Codable
json 计算的 属性 不需要并且被错误使用。
删除它。
struct ProgramRequest: Codable {
var userID: Int
var programData: ProgramData
}
struct ProgramData: Codable {
var airhotel: [AirHotel]
var security: [Security]
}
struct AirHotel: Codable {
var id: Int
var loyaltyNumber: String
}
struct Security: Codable {
var vendorCode: String
var loyaltyNumber: String
}
第 2 步:开始使用 Codable
现在给定一个 programRequest
,例如。像这样
let programRequest = ProgramRequest(userID: 1, programData: ProgramData(airhotel: [AirHotel(id: 1, loyaltyNumber: "loyaltyNumber")], security: [Security(vendorCode: "loyaltyNumber", loyaltyNumber: "loyaltyNumber")]))
您可以生成代表 JSON 的正确数据值,只需编写
let data = try JSONEncoder().encode(programRequest)
并且(如果需要)您可以将数据转换为字符串
let json = String(data: data, encoding: .utf8)
输出
Optional("{\"userID\":1,\"programData\":{\"airhotel\":[{\"id\":1,\"loyaltyNumber\":\"loyaltyNumber\"}],\"security\":[{\"vendorCode\":\"loyaltyNumber\",\"loyaltyNumber\":\"loyaltyNumber\"}]}}")
就是这样