2013-12-13 18 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

これは、AFHTTPRequestOperationではなく、タスクを使用する 'AFURLSessionManager'に対して有効です。 –

-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が正しいと確信しています。この問題は、誤ったログインまたはパスワードを入力したときに発生します。サーバー側からjsonではなくhtml応答(エラー401、ユーザーは許可されていません)が送信されます。私はエラータイプを401と同じにしたい場合、エラータイプが404ならユーザに "間違ったURLメッセージ"を表示するように、 "User is not authorized"のようなalertviewを表示したいと思います。どんな助けもありがとう。 – abekenza

+0

-1の代わりに質問を正しく書いてください。答えは:最初の[self parseResponseForUser:responseObject];あなたのレスポンスオブジェクトの内容とタイプを確認し、if(404?){alert} else {[self parseResponseForUser:responseObject];} – Dimentar

+0

私は-1をあなたに付けませんでした。私はわずか13の評判しか持っていない、私は投票することさえできない。私は今最高の答えを選択することができます – abekenza

0

サーバーがHTMLで応答可能性がある、またはそれはJSONで応答可能性があるように見えます。しかし、タイプ:

あなたはAFNetworkingにJSONを期待していると言っています。

代わりに、それはJSONではない場合は、通常のHTTPレスポンスを処理するためにそれを言ってみてください:JSONシリアライザが失敗した場合

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

さて、リクエストはあなたの障害ブロックを呼び出す必要がありAFHTTPResponseSerializer、に渡されますJSON解析エラーの代わりに適切なHTTPエラーコードを使用します。

ちなみに、AFHTTPResponseSerializerはサブクラス可能ですので、より具体的な動作が必要な場合は、そのオプションを参照してください。

+0

ありがとう、AAron。今日私はこのソリューションを試しましたが、AFCompoundSerializerをどこからインポートすればいいのでしょうか。 AFNetworkingのドキュメントを読む私はstatusCodeを取得するためのメソッドを見つけました。 – abekenza

0

エラーが送信されている場合、要求されたのとは異なるコンテンツタイプでサーバーが応答を送信することが頻繁に発生します。要求が認証エラーが原因で失敗した場合、

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

は、例えば、コンテンツタイプとしてJSONで要求を送信し、サーバからのJSONレスポンスを期待するとき、人は以下のリクエストヘッダを指定しますサーバーは、401 (Unauthorized)というステータスコードと、関連する診断情報を含むオプションの応答を送信する場合があります。

厳密には、WebサーバーはAcceptヘッダーを尊重する必要がありますが、残念ながらtext/htmlには「標準」エラー応答が送信されず、送信されません。ただし、詳細はAPIで指定する必要があります。

実装では、このケースを適切に処理する必要があります。つまり、レスポンスハンドラは、レスポンスデータのContent-Type(たとえば、text/html)に従ってエンコード(または解析)するか、適切な場合は無視しなければなりません。より正確には、HTTPステータスコードとコンテンツタイプを常に照会してから、レスポンスをどのように処理するかについて情報に基づいた決定を下す必要があります。

AFNでこの問題を解決する方法については、Aron Bragerの回答を参照してください。

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

ここで私はそれをやっています。 AFNetworking 3.0+では、エラーの場合は

[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

、あなたは失敗ブロックの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列挙型を使用してalok Srivastava氏の改善された応答:ここでは

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; 
    } 
} 
でそれを行う方法です
関連する問題