Tengo un problema en mi código que no puedo resolver, estoy haciendo una solicitud POST a un punto final que se usa para iniciar sesión y no recibo nada de vuelta, pero cuando envío la misma solicitud a Postman, recibir los datos válidos, por lo que el problema está en mi código y, de verdad, no tengo ni idea de cómo solucionarlo ahora, amigos.
El código:
func SignIn() {
let json: [String: Any] = ["User": "test", "Password": "test123"]
let jsonData = try? JSONSerialization.data(withJSONObject: json, options:.fragmentsAllowed)
let url = URL(string: "https://testingkrupi/Signin")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options:.allowFragments)
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()
}
La solicitud que se debe enviar:
POST http://testingkrupi/Signin HTTP/1.1
User-Agent: Fiddler
Host: localhost
Content-Length: 59
Content-Type: application/json; charset=utf-8
{
"User": "test",
"Password": "test123"
}
La respuesta que debo obtener:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 14 Apr 2022 07:00:29 GMT
Content-Length: 351
{
"StatusCode": 0,
"Result": {
"First": "test",
"Last": "test123",
"CompleteName": "test test123",
"PhoneNumber": "+512 512321 125",
"Email": "randomtest@gmail.com",
"IsConnectedToCustomer": true,
"Token": "423tj32o3jg230g923gj023gijf2o02",
"TokenExpireDate": "2020-05-14T09:00:29.2"
}
}
Solución del problema
Esta respuesta es más sobre la habilidad de depuración que necesita tener para avanzar.
En primer lugar, debe encontrar dónde radica el problema. Sabes que está en SignIn()
(supongo).
Ahora, comencemos agregando información para saber qué está pasando, si no sabe (todavía) cómo usar los puntos de interrupción, al menos agregue registros para saber qué está pasando:
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print("HTTPResponse: \(response)")
guard let data = data, error == nil else {
print(error?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options:.allowFragments)
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
} else {
//Here you test nullability of responseJSON AND if it's a [String: Any], so what if it's not null, but not a [String: Any]?
print("Response JSON is nil, or is not a [String: Any]")
}
}
Eso al menos debería darle algunos comentarios, cuál está impreso.
Ahora, continuemos:
Cada vez que haces un try?
(con el signo de interrogación), estás diciendo esto: sé que el método puede arrojar un error, y un error que a menudo tiene una buena explicación de por qué falló exactamente, ayudándome a depurarlo, pero decidí para que no me importe, simplemente lo ignoraré.
Eso es lo mismo que ignorar la advertencia de que el tanque de gasolina/combustible está vacío en su automóvil, no se queje más tarde de que estaba sonando, pero simplemente ignórelo cuando el automóvil se detenga porque no hay más gasolina/combustible.
Puede usar un try!
(con un signo de exclamación), que mostrará el error en la consola, pero hará que la aplicación se bloquee. Al menos no deberías perdértelo.
Pero, se recomienda try
implementar un do
/ try
/ catch
:
do {
let responseJSON = try JSONSerialization.jsonObject(with: data, options:.allowFragments)
} catch {
print("Error while calling JSONSerialization: \(error)")
print("Got stringified response: \(String(data: data, encoding:.utf8)?? "not utf8 stringifiable data")")
//If you enter in the "not utf8 stringifiable data" output, then, check the data, maybe use hex representation, since not all data, like jpg data can be UTF8 interpreted as such, but that's another case.
}
Por ahora, no sé la salida en la consola, pero:
print("HTTPResponse: \(response)")
puede brindarle información importante, generalmente si no es un código HTTP 200, y tendrá al menos una impresión "segura" en la consola para garantizar que el cierre se llame correctamente. print("Error while calling JSONSerialization: \(error)")
& print("Got stringified response: \(String(data: data, encoding:.utf8)?? "not utf8 stringifiable data")")
debería brindarle información sobre los datos reales que está recibiendo, y tal vez por qué los está recibiendo.
Ahora, ¿por qué imprimí la "Respuesta en cadena" & HTTPResponse
? Simplemente porque los desarrolladores a menudo confunden lo que deberían recibir con lo que recibirán e ignoran totalmente lo que en realidad reciben. No seas así, lee lo que estás recibiendo y soluciona tus problemas. Simplemente leer el documento e incluso si lo implementa correctamente no significa que necesariamente tendrá éxito en el primer intento, desde un error en su llamada de implementación, un problema del servidor, un documento desactualizado, etc., todo puede ocurrir.
Sigamos investigando, está utilizando POSTMAN y está funcionando, ¿sabía que POSTMAN puede generar Swift URLSession Code '(y cURL
también, que a menudo también es útil)? No es un código "hermoso Swift", pero funciona. Pruébelo y, si funciona, compárelo con su propia implementación. Puede mostrar un parámetro olvidado, cualquier error tonto o malentendido de la documentación de la API.
Sin relación pero:
Debería comenzar a nombrar sus métodos con minúsculas:
func SignIn()
->
func signIn()
let jsonData = try? JSONSerialization.data(withJSONObject: json, options:.fragmentsAllowed)
No hay necesidad de .fragmentsAllowed
aquí. No está utilizando un String
nivel superior, es un Dictionary
.
No hay comentarios:
Publicar un comentario