JSON 中的无效类型写入错误,试图通过 JSON 将自定义 class 发送到 .NET Web 服务

Invalid type in JSON write error trying to send custom class via JSON to .NET web service

我正在尝试将数据发送到接受三个类型为(字符串、字符串、QBUser Class)的参数的 .NET Web 服务。在 Javascript 中,我会像这样在 JSON 中发送参数:

{sKey: "key", sUpdatetype: "edit", oQbUser: QBUser} 

我以前从未遇到过该方法的任何问题,.NET 能够将它直接分类到服务器上的 class 对象中。使用 Swift,我已经成功地发送了书中几乎所有类型 JSON,但是我在发送自定义 classes/struct 作为参数时遇到了问题。这是我当前的代码:

func updateQbUser(k: String, t: String, oUser: QBUUser, completion: @escaping (_ oVisits: AnyObject) -> ()) {
    let params: [String: Any] = ["sKey": k, "sUpdateType": t, "iObjectId": oUser]
    let url = URL(string: "myWebService.asmx/updateQbUser")!
    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    do { request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted) } catch let error { print(error.localizedDescription) }
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
        guard error == nil else { return }
        DispatchQueue.main.async { completion(response!) }
    })
    task.resume()
}

控制台报错如下:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (QBUUser)'

QBUUser class 不是 NSString、NSNumber、NSArray、NSDictionary 或 NSNull 的实例,所以我一直在思考如何将其传送到服务器。

有没有办法在尝试发送之前将 QBUUser class 转换为上面列出的任何对象类型?我试图在 class 上 运行 一个循环,那是一个完全不同的锤子包,但出现了一些错误,关于不能 AnyHashable over Array Literal 或类似的东西。有没有更好的方法我还没有发现?

参数必须是那样的,所以我被困在那里了。我只需要将 class 发送到另一端,因为本质上只是在 key/value 对中。

控制台中打印的 class 如下所示:

  [QBUUser]:
  ID:20786
  created at:2017-05-03 15:05:56 +0000
  updated at:2017-05-03 20:16:52 +0000
  externalUserID:2456369827
  blobID:0
  facebookID:(null)
  twitterID:(null)
  twitterDigitsID:(null)
  full name:Erik Grosskurth
  email:erik@webgraphicsatlanta.com
  login:Erik_2456369827
  phone:(null)
  tags:(
    ""
)
  lastRequestAt:2017-05-03 20:20:16 +0000
  customData:(null)
  website:(null)

您很可能只需要将 QBUUser 对象转换为字典。您可以内联执行此操作,但如果您打算重用该功能,您也可以制作一个辅助函数来执行此操作。

字典应该看起来像这样:

let qbuUser = QBUUser() //presumably you already have a reference to the user in question
let user: [String : Any] = ["id" : qbuUser.ID, "createdAt" : qbuUser.createdAt, "updatedAt" : qbuUser.updatedAt, ...]

如果你想在你的 QBUUser class 中创建一个辅助方法,你可以这样做:

extension QBUUser {
   func toDictionary() -> [String : Any] {
      return ["id", self.ID, "createdAt", self.createdAt, ...]
   }
}

这样您就可以将现有函数更改为如下所示:

let params: [String: Any] = ["sKey": k, "sUpdateType": t, "iObjectId": oUser.toDictionary()]

可能还值得指出的是,参数中 QBUUser 对象的键是 "iObjectId",这(对我而言)意味着他们所需要的只是 ID来自您的用户,这使得整个解决方案没有实际意义。