【问题标题】:Alamofire 'Invalid type in JSON write (_SwiftValue)' structAlamofire 'JSON 写入中的无效类型 (_SwiftValue)' 结构
【发布时间】:2020-04-03 03:07:43
【问题描述】:

我正在尝试发出 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

我简化了参数,但我的 items 结构失败了。

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)])])]

【问题讨论】:

  • 发布您收到的正文
  • 这是一个 post 方法,除非你指的是我的输出参数。我只是在上面添加了它们。我的 nil "children" 是否有问题,或者数组被写为 "optional"
  • “可选”是问题所在。尝试删除它!
  • @Zyfe3r 就是这样。虽然我的“值”字段需要是一个可选值,所以我将手动构建我的项目以进行上传,而不是尝试处理传递这个已完成的对象。谢谢!

标签: swift alamofire


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    使用新的JSONParameterEncoder.prettyPrinted 而不是JSONEncoding.prettyPrintedJSONParameterEncoder 使用 JSONEncoder,而 JSONEncoding 使用 JSONSerializationJSONSerialization 不知道如何将 Encodables 转换为 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)
    }
    

    尽管有 cmets,但这与可选性无关(尽管我会说 [[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
    

    【讨论】:

      猜你喜欢
      • 2017-01-27
      • 2017-03-12
      • 2017-01-24
      • 2019-06-13
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多