2013-12-13 32 views
14

我有一個授權用戶的方法。我需要基本授權。如何獲取AFNetworking中的狀態代碼

NSString *url = [NSString stringWithFormat:@"%@/rest/api/person/auth", host]; 
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
    [manager setRequestSerializer:[AFHTTPRequestSerializer serializer]]; 
    [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:_loginField.text password:_passwordField.text]; 
    [manager setResponseSerializer:[AFJSONResponseSerializer serializer]]; 
    [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     [self parseResponseForUser:responseObject]; 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     NSLog(@"Error %@ ",error); 
    }]; 

這裏的主要問題是確定錯誤類型。我可能有網絡連接問題的授權和錯誤錯誤(主機無法訪問)。 當登錄名和密碼與條件不符時,運行故障塊。例如,如果我把錯誤的密碼和登錄我藉此錯誤消息:

錯誤域= NSCocoaErrorDomain代碼= 3840「的操作不能完成 (可可錯誤3840)」(JSON文本爲了讓沒有設置片段沒有用數組或對象 和選項啓動。)

我應該如何趕上錯誤類型?

+0

你可以發佈你試圖得到的JSON嗎? –

+0

我已經更新了我的問題,我發佈了回覆,我正在努力獲取 – abekenza

回答

30

最後找到答案,可能會對某人有幫助。我只需要使用:

NSInteger statusCode = operation.response.statusCode; 

,我可以抓住它想:

[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     NSLog(@"response:%@", responseObject); 
     [self parseResponseForUser:responseObject]; 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     NSInteger statusCode = operation.response.statusCode; 
     if(statusCode == 401) { 
     } else if (statusCode == 404) { 
     } 
    }]; 
+1

當我們移動到64位拱時,應該使用NSInteger。 – ryanconnellyatl

+4

這對使用任務的'AFURLSessionManager'無效,而不是'AFHTTPRequestOperation' –

-1

您的JSON必須是:

{ 
    "access" : "1", 
    "admin" : "0", 
    "code" : "constantine2", 

    ... 

    "positions" : [ 
       { 
      "departmentID" : "992c93ee-2fa7-4e53-be5f-4e32a45ba5e6", 
      "departmentName" : "Dev-C++ resources page (libraries, sources, updates...)", 
      .... 
     } 
    ], 
    "userid" : "3b660c13-b856-41fa-a386-814a7b43bacc" 
} 
+0

我相信JSON是正確的,因爲我可以解析數據,當我輸入正確的登錄名和密碼時。當我輸入不正確的登錄名或密碼時會出現問題。服務器端向我發送html響應(錯誤401,用戶未被授權)而不是json。我想捕捉錯誤,以便如果錯誤類型等於401,我想顯示一個alertview,如「用戶不被授權」,如果錯誤類型等於404,我想顯示用戶「不正確的URL消息」。任何幫助,將不勝感激。 – abekenza

+0

反而把-1正確地寫你的問題。答案是:[self parseResponseForUser:responseObject];檢查你的responceObject內容和類型,如果(是404?){alert} else {[self parseResponseForUser:responseObject];} – Dimentar

+0

我沒有把-1給你。我只有13個聲望,我甚至不能投票。我現在只能選擇最好的答案 – abekenza

0

它看起來像你的服務器可能與HTML響應,或者它可能與JSON響應。但是當你輸入:

[manager setResponseSerializer:[AFJSONResponseSerializer serializer]]; 

你告訴AFNetworking期望JSON。

相反,嘗試告訴它來處理普通的HTTP響應,如果它不是JSON:現在

NSArray *serializers = @[[AFJSONResponseSerializer serializer], [AFHTTPResponseSerializer serializer]]; 
AFCompoundSerializer *compoundResponseSerializer = [AFCompoundSerializer compoundSerializerWithResponseSerializers:serializers]; 
[manager setResponseSerializer:compoundResponseSerializer]; 

,如果JSON序列化失敗,請求將被傳遞給AFHTTPResponseSerializer,應該打電話給你的不良區使用適當的HTTP錯誤代碼而不是JSON解析錯誤。

順便說一句,AFHTTPResponseSerializer是子類,所以如果您想要更具體的行爲,請隨時查看該選項。

+0

謝謝,AAron。今天,我嘗試了這個解決方案,但是我從我應該導入AFCompoundSerializer的地方開始使用Stucked。閱讀AFNetworking的文檔我找到了獲取statusCode的方法。 – abekenza

0

它經常發生,服務器可能會發送一個不同於請求的內容類型的響應,如果它們發送錯誤。當請求由於認證錯誤失敗

Content-Type: application/json 
Accept: application/json 

,:

例如發送請求時使用JSON爲Content-Type和期待來自服務器的JSON響應,一個將指定以下請求頭服務器可能會向您發送狀態碼401 (Unauthorized)加上包含相關診斷信息的可選響應。

嚴格來說,網絡服務器應該尊重Accept頭,但不幸的是,有些人不會並且會在例如text/html中發送「標準」錯誤響應。不過,詳細信息應該在API中指定。

你的實現應該優雅地處理這種情況。也就是說,您的響應處理程序必須根據響應的Content-Type(如text/html)對響應數據進行編碼(或解析),或者在適當的情況下忽略它。更確切地說,您總是應該查詢HTTP狀態碼和內容類型,然後做出明智的決定,您要如何處理響應。

請參閱Aron Brager的答案如何解決AFN的問題。

6

你可以給一個嘗試,從錯誤獲取代碼,然後相應地顯示消息。

failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    NSInteger statusCode = error.code; 
    if(statusCode == -1001) { 
     // request timed out 
    } else if (statusCode == -1009 || statusCode || -1004) { 
     // no internet connectivity 
    } 
}]; 

同樣,你可以檢查其他代碼。

5

下面是我如何做到這一點。

[self.httpClient GET:@"someAPI" 
      parameters:parametersDictionary 
      success:^(NSURLSessionDataTask *task, id responseObject) { 
      } failure:^(NSURLSessionDataTask *task, NSError *error) { 
       NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response; 
       NSInteger statusCode = [response statusCode]; 
       switch (statusCode) { 
       case 404: 
        break; 
       default: 
        break; 
       } 
      }]; 
17

在AFNetworking 3.0+和在發生錯誤的情況下,可以在故障塊的error.userInfo對象訪問狀態代碼:

failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 

    NSHTTPURLResponse *response = error.userInfo[AFNetworkingOperationFailingURLResponseErrorKey]; 

    NSInteger statusCode = response.statusCode; 

    // Do something with the status code 
}]; 
+0

謝謝它的作品適合我 –

0
通過使用NSURLError枚舉阿洛克塔瓦的

改進的響應:

failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
NSInteger statusCode = error.code; 
if(statusCode == NSURLErrorTimedOut) { 
    // request timed out 
} else if (statusCode == NSURLErrorNotConnectedToInternet || statusCode || NSURLErrorCannotConnectToHost) { 
    // no internet connectivity 
}}]; 
1

這裏是如何做到這一點的斯威夫特

((NSURLSessionDataTask, NSError) -> Void) = { (sessionDataTask :NSURLSessionDataTask, responseError : NSError) -> Void in 
    let response = sessionDataTask.response as! NSHTTPURLResponse 
    switch (statusCode) { 
     case 404: 
     // do stuff 
     case 401: 
     // do stuff 
     default: 
     break; 
    } 
}