使用NSURLSession处理HTTP错误?

时间:2014-03-05 18:34:06

标签: ios http

我正在尝试使用NSURLSession发送HTTP请求。它工作正常,但当服务器没有响应时,我找不到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];

5 个答案:

答案 0 :(得分:50)

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];

答案 1 :(得分:8)

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

答案 2 :(得分:1)

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

一般来说,我应该在会话代理中从URLSession:task:didCompleteWithError:协议实现NSURLSessionTaskDelegate

docs:NSURLSessionTaskDelegate Protocol Reference

答案 3 :(得分:1)

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

答案 4 :(得分:0)

您可以在allHeaderFields

中包含整个标头
let realResponse = response as? NSHTTPURLResponse 
realResponse.allHeaderFields

请将其转换为Objective-C。