Alamofire“ JSON写入(_SwiftValue)中的无效类型”结构

时间:2019-12-10 00:37:25

标签: swift alamofire

我正在尝试发出Alamofire Post请求,但我的Codable结构失败。

var items: [[InspectionUploadItem]?]?

let params : Parameters = ["key" : key, "items": items]

Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.prettyPrinted, headers: headers).validate().responseJSON { response in

我简化了Parameters,但是我的项目结构失败了。

struct InspectionUploadItem: Codable {

  var id: Int = 0
  var type: String = ""
  var value: String?
  var name: String = ""
  var children: [[InspectionUploadItem]]?

private enum CodingKeys: String, CodingKey {
   case id = "id"
   case type = "type"
   case value = "value"
   case children = "children"
   }
 }

该模型正确,因为我已在Android中成功完成此操作。我避免手动将其转换为JSON对象,因为该对象可以扩展三个子级别并包含数十个项目。

这是我的具体错误:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'

我发现标题相似的帖子指出了在非结构模型上更明显的错误。我有办法专门缩小错误的位置吗?我的代码是否还存在明显的错误?

编辑:输出参数字段

["key": "keyString", "items": Optional([Optional([CompanyName.InspectionUploadItem(id: 317, type: "TEXT", value: Optional("testing field"), name: "One String", children: nil)])])]

2 个答案:

答案 0 :(得分:0)

从根本上讲,您的问题是,您正在将Swift结构传递给使用JSONSerialization的方法,并且两者不兼容。使用request参数的正确Encodable调用是request(_:method:parameters:encoder:headers:)。您可能需要重做您的根参数类型才能起作用。

答案 1 :(得分:0)

使用新的JSONParameterEncoder.prettyPrinted而不是JSONEncoding.prettyPrintedJSONParameterEncoder使用JSONEncoder,而JSONEncoding使用JSONSerializationJSONSerialization不知道如何将Encodable转换为JSON,因此它会到达结构并引发异常。 the docs中的示例:

struct Login: Encodable {
    let email: String
    let password: String
}

let login = Login(email: "test@test.test", password: "testPassword")

AF.request("https://httpbin.org/post",
           method: .post,
           parameters: login,
           encoder: JSONParameterEncoder.default).response { response in
    debugPrint(response)
}

尽管有评论,但这与可选项无关(尽管我会说[[InspectionUploadItem]?]?可能不是必需的并且很难使用)。您所需要做的就是定义一个表示您的参数的结构。

struct InspectionUploadParameters: Codable {
    let key: String
    let items: [[InspectionUploadItem]?]?
}

然后

let params = InspectionUploadParameters(key: "keyString", items: items)
Alamofire.request(url, method: .post, parameters: params, encoding: JSONParameterEncoder.prettyPrinted, headers: headers).validate().responseJSON