Обработать ошибку HTTP с помощью NSURLSession?
Я пытаюсь отправить HTTP-запрос с помощью NSURLSession
. Он отлично работает, но когда сервер не отвечает, я не могу найти, где хранится код ошибки HTTP. Третий параметр completionHandler
является просто очень общим NSError
. Я прочитал ссылку NSURLResponse
, но ничего не нашел.
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];
Ответы
Ответ 1
Второй параметр completionHandler
- это NSURLResponse
, который при выполнении HTTP-запроса обычно равен NSHTTPURLResponse
. Итак, вы обычно делаете что-то вроде:
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];
Ответ 2
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
}
Ответ 3
Если возникла ошибка на стороне сервера data
параметр из обработчика завершения может содержать некоторую полезную информацию
В общем, я тонкий, вы должны реализовать URLSession:task:didCompleteWithError:
из NSURLSessionTaskDelegate
протокола в делегате сессии
docs: Ссылка на протокол NSURLSessionTaskDelegate
Ответ 4
Вы можете иметь все заголовки в allHeaderFields
let realResponse = response as? NSHTTPURLResponse
realResponse.allHeaderFields
любезно преобразуйте его в objective-C.
Ответ 5
вы можете попробовать что-то вроде этого. Я создал простой метод, который сможет отправлять данные на сервер и получать ответ сервера. Код состояния сервера можно получить через класс NSHTTPURLResponse.
Надежда поможет:)
-(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];
}