ios - start - nsapptransportsecurity swift 4
¿Manejar error HTTP con NSURLSession? (5)
El segundo parámetro de completionHandler
es el NSURLResponse
, que al realizar una solicitud HTTP, generalmente es un NSHTTPURLResponse
. Entonces, generalmente harías algo como:
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:[self postRequestWithURLString:apiEntry parameters:parameters] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// handle basic connectivity issues here
if (error) {
NSLog(@"dataTaskWithRequest error: %@", error);
return;
}
// handle HTTP errors here
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(@"dataTaskWithRequest HTTP status code: %d", statusCode);
return;
}
}
// otherwise, everything is probably fine and you should interpret the `data` contents
NSLog(@"data: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
[dataTask resume];
Estoy tratando de enviar una solicitud HTTP con NSURLSession
. Funciona bien, pero cuando el servidor no responde no puedo encontrar dónde se almacena el código de error HTTP. El tercer parámetro de completionHandler
es solo un NSError
muy general. Leí la referencia de NSURLResponse
pero no encontré nada.
NSURLSessionDataTask *dataTask =
[session dataTaskWithRequest:[self postRequestWithURLString:apiEntry parameters:parameters]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(!error) NSLog([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}
];
[dataTask resume];
Podrías probar algo como esto. He creado un método simple que podrá publicar datos en el servidor y obtener la respuesta del servidor. Puede obtener el código de estado del servidor a través de la clase NSHTTPURLResponse. La esperanza te ayudará :)
-(void) POST:(NSURL *) url URLparameters:(NSString *) parameters success:(void (^)(NSURLSessionDataTask * task, id responseObject)) successHandler errorHandler:(void (^)(NSURLSessionDataTask * task, NSError * error)) errorHandler{
requestBody = [[NSMutableURLRequest alloc]
initWithURL:url
cachePolicy: NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[requestBody setHTTPMethod:@"POST"];
[requestBody setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[requestBody setHTTPBody:[NSData dataWithBytes:
[parameters UTF8String]length:strlen([parameters UTF8String])]];
NSURLSession *session = [NSURLSession sessionWithConfiguration: sessionConfiguration delegate: self delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:requestBody completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse* respHttp = (NSHTTPURLResponse*) response;
if (respHttp.statusCode == SUCCESS) {
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
successHandler(task, dictionary);
NSLog(@"HTTP_STATUS: success %@", response);
}else if (respHttp.statusCode == UNAUTHORIZE) {
NSLog(@"HTTP_STATUS: anauthorize");
}else if (respHttp.statusCode== BAD_REQUEST) {
NSLog(@"HTTP_STATUS: badrequest");
}else if (respHttp.statusCode == INTERNAL_SERVER_ERROR) {
NSLog(@"HTTP_STATUS: internalerror");
}else if (respHttp.statusCode== NOT_FOUND) {
NSLog(@"HTTP_STATUS: internalerror");
}
errorHandler(task, error);
return;
}];
[task resume];
}
Puedes tener los encabezados completos en todos los allHeaderFields
let realResponse = response as? NSHTTPURLResponse
realResponse.allHeaderFields
amablemente convertirlo en objetivo-c.
Si se produjo un error en el servidor, el parámetro de data
del controlador de finalización puede contener información útil
En general, creo que debería implementar URLSession:task:didCompleteWithError:
from NSURLSessionTaskDelegate
protocol en el delegado de sesión
Swift 3:
// handle basic connectivity issues here
guard error == nil else {
print("Error: ", error!)
return
}
// handle HTTP errors here
if let httpResponse = response as? HTTPURLResponse {
let statusCode = httpResponse.statusCode
if (statusCode != 200) {
print ("dataTaskWithRequest HTTP status code:", statusCode)
return;
}
}
if let data = data {
// here, everything is probably fine and you should interpret the `data` contents
}