51

AFNetworking 2.0 に切り替えると、AFHTTPClient は AFHTTPRequestOperationManager / AFHTTPSessionManager に置き換えられました (移行ガイドに記載されています)。AFHTTPSessionManager を使用するときに最初に遭遇した問題は、失敗ブロックで応答の本文を取得する方法です。

次に例を示します。

[self.sessionManager POST:[endpoint absoluteString] parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
    // How to get the status code?
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    // How to get the status code? response?
}];

成功ブロックで、応答のステータス コードを取得したいと思います。失敗ブロックでは、応答のステータス コードとコンテンツ (この場合はサーバー側のエラーを説明する JSON) の両方を取得したいと考えています。

NSURLSessionDataTask には、statusCode フィールドを持たないタイプ NSURLResponse の応答プロパティがあります。現在、次のように statusCode を取得できます。

[self.sessionManager POST:[endpoint absoluteString] parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
    // How to get the status code?
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
    DDLogError(@"Response statusCode: %i", response.statusCode);

}];

しかし、これは私には醜く見えます。そして、応答の本文についてはまだ理解できません。

助言がありますか?

4

7 に答える 7

68

「AFNetworkingOperationFailingURLResponseDataErrorKey」キーを使用して AFNetworking から「データ」オブジェクトに直接アクセスできるため、AFJSONResponseSerializer をサブクラス化する必要はありません。データを読み取り可能なディクショナリにシリアル化できます。JSON データを取得するためのサンプル コードを次に示します。

 NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
 NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: errorData options:kNilOptions error:nil];

以下は、Failure ブロックでステータス コードを取得するコードです。

  NSHTTPURLResponse* r = (NSHTTPURLResponse*)task.response;
  NSLog( @"success: %d", r.statusCode ); 
于 2015-01-13T08:08:08.333 に答える
12

このようなステータス コードを取得し、失敗ブロックを読み取ることができます...

 NSURLSessionDataTask *op = [[IAClient sharedClient] POST:path parameters:paramsDict constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    } success:^(NSURLSessionDataTask *task, id responseObject) {
        DLog(@"\n============= Entity Saved Success ===\n%@",responseObject);

        completionBlock(responseObject, nil);
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        DLog(@"\n============== ERROR ====\n%@",error.userInfo);
        NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
        int statuscode = response.statusCode;}
于 2014-03-11T22:09:14.817 に答える
4

「AFNetworkingOperationFailingURLResponseDataErrorKey」キーを使用して AFNetworking から「データ」オブジェクトに直接アクセスできるため、AFJSONResponseSerializer をサブクラス化する必要はありません。データを読み取り可能なディクショナリにシリアル化できます。サンプルコードは次のとおりです。

 NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
 NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: errorData options:kNilOptions error:nil];
于 2015-01-13T08:05:26.517 に答える
2

Swift 2.0 の場合 (Alamofire をまだ使用できない場合):

ステータス コードを取得します。

if let response = error.userInfo[AFNetworkingOperationFailingURLResponseErrorKey] as? NSHTTPURLResponse {
    print(response.statusCode)
}

応答データを取得します。

if let data = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as? NSData {
    print("\(data.length)")
}

一部の JSON REST API は、エラー応答でエラー メッセージを返します (Amazon AWS サービスなど)。この関数を使用して、AFNetworking によってスローされた NSError からエラー メッセージを抽出します。

// Example: Returns string "error123" for JSON { message: "error123" }
func responseMessageFromError(error: NSError) -> String? {
    do {
        guard let data = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as? NSData else {
            return nil
        }
        guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [String: String] else {
            return nil
        }
        if let message = json["message"] {
            return message
        }
        return nil
    } catch {
        return nil
    }
}
于 2015-07-28T10:32:54.910 に答える
0

オブジェクトにuserInfo関連付けられた辞書を取得し、それをたどって必要な正確な応答を取得できます。NSErrorたとえば、私の場合、サーバーからエラーが発生し、userInfoScreeShot でそのようなものを見ることができます

AFNetworking エラーを表示するスクリーンショット

于 2013-09-30T19:29:03.030 に答える