AFNetworking 2.0 AFHTTPSessionManager:如何在故障块中获取状态代码和响应JSON?

Ole*_*ndr 51 objective-c afnetworking-2

切换到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?
}];
Run Code Online (Sandbox Code Playgroud)

在成功块中,我想检索响应的状态代码.在故障块中,我想检索响应的状态代码和内容(在这种情况下,这是描述服务器端错误的JSON).

NSURLSessionDataTask具有NSURLResponse类型的响应属性,该属性没有statusCode字段.目前我能够像这样检索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);

}];
Run Code Online (Sandbox Code Playgroud)

但这看起来很丑陋.而且仍然无法想象响应的身体.

有什么建议?

pyt*_*hon 64

您可以使用"AFNetworkingOperationFailingURLResponseDataErrorKey"键直接从AFNetworking访问"数据"对象,因此不需要对AFJSONResponseSerializer进行子类化.您可以将数据序列化为可读字典.以下是获取JSON数据的示例代码:

 NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
 NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: errorData options:kNilOptions error:nil];
Run Code Online (Sandbox Code Playgroud)

以下是在Failure块中获取状态代码的代码:

  NSHTTPURLResponse* r = (NSHTTPURLResponse*)task.response;
  NSLog( @"success: %d", r.statusCode ); 
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的指针!然而,应该注意的是,这是一个相对较新的新增功能(AFNetworking 2.4.0,于2014-09-03发布),因此在提出问题时无法使用.@Olx:这应该是公认的答案! (2认同)

sho*_*uro 13

经过几天的阅读和研究,它对我有用:

1)您必须构建自己的AFJSONResponseSerializer子类

文件:JSONResponseSerializerWithData.h:

#import "AFURLResponseSerialization.h"

/// NSError userInfo key that will contain response data
static NSString * const JSONResponseSerializerWithDataKey = @"JSONResponseSerializerWithDataKey";

@interface JSONResponseSerializerWithData : AFJSONResponseSerializer
@end
Run Code Online (Sandbox Code Playgroud)

文件:JSONResponseSerializerWithData.m

#import "JSONResponseSerializerWithData.h"

@implementation JSONResponseSerializerWithData

- (id)responseObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error
{
    id JSONObject = [super responseObjectForResponse:response data:data error:error];
    if (*error != nil) {
        NSMutableDictionary *userInfo = [(*error).userInfo mutableCopy];
        if (data == nil) {
//          // NOTE: You might want to convert data to a string here too, up to you.
//          userInfo[JSONResponseSerializerWithDataKey] = @"";
            userInfo[JSONResponseSerializerWithDataKey] = [NSData data];
        } else {
//          // NOTE: You might want to convert data to a string here too, up to you.
//          userInfo[JSONResponseSerializerWithDataKey] = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            userInfo[JSONResponseSerializerWithDataKey] = data;
        }
        NSError *newError = [NSError errorWithDomain:(*error).domain code:(*error).code userInfo:userInfo];
        (*error) = newError;
    }

    return (JSONObject);
}
Run Code Online (Sandbox Code Playgroud)

2)在AFHTTPSessionManager中设置自己的JSONResponseSerializer

+ (instancetype)sharedManager
{
    static CustomSharedManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[CustomSharedManager alloc] initWithBaseURL:<# your base URL #>];

        // *** Use our custom response serializer ***
        manager.responseSerializer = [JSONResponseSerializerWithData serializer];
    });

    return (manager);
}
Run Code Online (Sandbox Code Playgroud)

资料来源:http://blog.gregfiumara.com/archives/239


oma*_*ojo 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;}
Run Code Online (Sandbox Code Playgroud)


uns*_*ber 0

您可以获取userInfo与该对象关联的字典NSError并向下遍历该字典以获得您需要的确切响应。例如,在我的例子中,我从服务器收到错误,我可以userInfo在 ScreeShot 中看到类似的内容

显示 AFNetworking 错误的屏幕截图