2014-03-05 90 views
26

我试图发送一个HTTP请求NSURLSession。它工作正常,但是当服务器没有响应时,我找不到HTTP错误代码的存储位置。 completionHandler的第三个参数只是一个非常通用的NSError。我读了NSURLResponse的参考资料,但什么都没发现。用NSURLSession处理HTTP错误?

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

回答

42

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

加入&&响应==零到 如果([响应isKindOfClass:[NSHTTPURLResponse类]])可以是一个额外的好处 – prodeveloper

+1

依吾不。 if([response isKindOfClass:[NSHTTPURLResponse class]] && response == nil)'永远不会是真的('response'是'nil'或者它可能是HTTP响应,但不会同时出现)。也许你的意思是'response!= nil',但这在'isKindOfClass'调用中是隐含的(即如果'response'为'nil',则调用'nil'对象上的'isKindOfClass'不是真)。如果你真的想'if(response!= nil && [response isKindOfClass:[NSHTTPURLResponse class]])',那没有什么问题,并且明确地表示意图,但是是多余的。 – Rob

+1

是的你是对的。评论中有一个错字。我的意思是提及“|| response”而不是“&& response” – prodeveloper

1

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

总的来说,我瘦,你应该实现URLSession:task:didCompleteWithError:NSURLSessionTaskDelegate协议会议代表

文档:NSURLSessionTaskDelegate Protocol Reference

0

你可以拥有整个头在allHeaderFields

let realResponse = response as? NSHTTPURLResponse 
realResponse.allHeaderFields 

好心将其转换为目标-C。

5

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