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