Подтвердить что ты не робот

Обработать ошибку 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];
4b9b3361

Ответ 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];
}