2014-03-05 13 views
26

Ich versuche eine HTTP-Anfrage mit NSURLSession zu senden. Es funktioniert gut, aber wenn der Server nicht antwortet, kann ich nicht finden, wo der HTTP-Fehlercode gespeichert wird. Der dritte Parameter von completionHandler ist nur ein sehr allgemeiner NSError. Ich habe die Referenz von NSURLResponse gelesen, aber nichts gefunden.Handle HTTP-Fehler mit NSURLSession?

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

Antwort

42

Der zweite Parameter der completionHandler ist die NSURLResponse, die bei einer HTTP-Anfrage, ist allgemein eine . Also, würden Sie in der Regel so etwas wie:

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

Hinzufügen von && Antwort == null zu helfen, wenn ([Antwort isKindOfClass: [NSHTTPURLResponse Klasse]]) ein zusätzlicher Vorteil sein kann – prodeveloper

+1

Methinks nicht. 'if ([response isKindOfClass: [NSHTTPURLResponse-Klasse]] && response == nil)' würde niemals wahr sein (entweder 'response' ist 'nil' oder HTTP-Antwort, aber niemals beide gleichzeitig). Vielleicht meintest du 'response! = Nil', aber das ist implizit im Aufruf von' isKindOfClass' (d. H. Wenn 'response'' nil' ist, ist das Aufrufen von 'isKindOfClass' auf' nil' Objekt nicht wahr). Wenn Sie wirklich 'if (response! = Nil && [Antwort isKindOfClass: [NSHTTPURLResponse class]]) 'wollen, ist das nicht falsch und macht die Absicht explizit, ist aber überflüssig. – Rob

+1

Ja, Sie haben Recht. Es gibt einen Tippfehler in dem Kommentar. Ich meine, "|| Antwort" statt "&& Antwort" zu erwähnen – prodeveloper

1

Wenn serverseitige Fehler data Parameter von Abschluss-Handler aufgetreten einige nützliche Informationen

Im Allgemeinen enthalten dünn ich Sie URLSession:task:didCompleteWithError: von NSURLSessionTaskDelegate Protokoll in der Sitzung Delegierte

docs implementieren sollten: NSURLSessionTaskDelegate Protocol Reference

0

Sie den gesamten Header in allHeaderFields

let realResponse = response as? NSHTTPURLResponse 
realResponse.allHeaderFields 

es zu Objective-C freundlich umwandeln können.

5

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 
} 
1

Sie so etwas wie dies versuchen könnte. Ich habe eine einfache Methode erstellt, die in der Lage ist, Daten auf dem Server zu veröffentlichen und die Serverantwort zu erhalten. Sie können den Serverstatuscode über die NSHTTPURLResponse-Klasse abrufen. Hope :)

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