Недопустимый тип в записи JSON при попытке отправить пользовательский класс через JSON в веб-службу.NET

Я пытаюсь отправить данные в веб-службу.NET, которая принимает три параметра, типы которых (String, String, QBUser Class). В Javascript я бы отправил параметры в JSON следующим образом:

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

У меня никогда не было проблем с этим методом, и.NET мог бы отсортировать его прямо в объект класса на сервере. С Swift я добился успеха, посылая почти все типы в книге, вплоть до JSON, но у меня возникают проблемы с отправкой пользовательских классов /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 не является экземпляром NSString, NSNumber, NSArray, NSDictionary или NSNull, поэтому я застрял на том, как передать это на сервер.

Есть ли способ преобразовать класс QBUUser в любой тип объекта, указанный выше, прежде чем пытаться отправить? Я попытался запустить цикл над классом, и это был совершенно другой пакет молотков, но получил некоторую ошибку о том, не может ли AnyHashable over Array Literal или что-то подобное. Есть ли лучший способ, который я не обнаружил?

Параметры должны быть такими, чтобы я застрял там. Мне просто нужно переслать класс на другую сторону как то, что по сути просто в паре ключ / значение.

вот как выглядит класс, напечатанный в консоли:

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

1 ответ

Решение

Вам, скорее всего, просто нужно конвертировать свои 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 класс вы могли бы сделать что-то вроде:

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 от вашего пользователя, что делает все это решение спорным.

Другие вопросы по тегам