ios 使用 NSURLSession 处理 HTTP 错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22206274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:39:07  来源:igfitidea点击:

Handle HTTP error with NSURLSession?

ioshttp

提问by Lai Yu-Hsuan

I'm trying to send a HTTP request with NSURLSession. It works fine, but when the server doesn't respond I can't find where the HTTP error code is stored. The third parameter of completionHandleris just a very general NSError. I read the reference of NSURLResponsebut found nothing.

我正在尝试使用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];

回答by Rob

The second parameter of the completionHandleris the NSURLResponse, which when doing a HTTP request, is generally a NSHTTPURLResponse. So, you'd generally do something like:

的第二个参数completionHandlerNSURLResponse,在执行 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];

回答by MrAn3

Swift 3:

斯威夫特 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
}

回答by vidalbenjoe

you could try something like this. I've created a simple method that will be able to post a data into server and get the server response. You can get the server status code via NSHTTPURLResponse class. Hope will help :)

你可以尝试这样的事情。我创建了一个简单的方法,可以将数据发布到服务器并获得服务器响应。您可以通过 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];
}

回答by sage444

If server-side error occurred dataparameter from completion handler may contain some useful info

如果data来自完成处理程序的服务器端错误发生参数可能包含一些有用的信息

In general I thin you should implement URLSession:task:didCompleteWithError:from NSURLSessionTaskDelegateprotocol in session delegate

一般来说,我认为你应该URLSession:task:didCompleteWithError:NSURLSessionTaskDelegate会话委托中的协议中实现

docs: NSURLSessionTaskDelegate Protocol Reference

文档:NSURLSessionTaskDelegate 协议参考

回答by Code Tree

You can have the entire headers in allHeaderFields

您可以将整个标题放在 allHeaderFields

let realResponse = response as? NSHTTPURLResponse 
realResponse.allHeaderFields

kindly convert it to objective-C.

请将其转换为objective-C。