关于AFNetWorking3.0在failure回调时获取响应体信息

关键词:AFNetWorking3.0 failure回调 响应体

情景:

最近在开发中由于后台接口进行了重构,新版的接口执行restful api标准(反正后台是这么说的).于是作为苦逼前端的我们也跟着进行了接口联调更新.在调整是发现了回调时参数变化较大,
原来的接口返回标准是:一个请求无论请求的目的是否达到(比如,这个请求是用户注册是否成功)只要请求成功,后台则返回http状态码为200,通过响应体中包含的信息来进一步描述这个用户注册成功或者注册失败.
但是新版的接口返回标准改为:一个请求的目的达到与否直接影响到http状态码的返回,比如,同样是请求用户注册:

  • 如果注册成功,则后台返回http状态码为200.如果有其他信息则进一步在响应体中描述.
  • 如果注册失败(用户注册的目的没有达到)则后台的返回http状态码为400(甚至所有没有达到目的请求都会返回http状态码为400),而在在响应体中进一步用信息描述请求没有达到的原因,比如errorcode=4000001为用户已存在,errorcode=4000002...,errorcode=4000002....等等.前端则依照这个errorcode给用户以相应的提示.

问题:

那么问题来了,在AFNetworking的封装中会判断http状态码是否为200,如果是则进行successBlock的回调,回调参数中的responseObject则是响应体.如果是400的状态码,则进行failure的回调,而这个回调中参数只有这两个:

(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)

我去,那我怎么拿到响应体啊?我需要响应体里的errorcode来区分是哪个错误才能提示用户啊.

分析:

首先在苹果原生的NSURLSession中只要是网络请求都会有响应头和响应体,
以下是一个标准的NSURLSession请求回调:

NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;       
  NSInteger statusCode = response.statusCode;
  NSLog(@"http状态码:%ld", statusCode);
  NSLog(@"响应体信息:%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];

这里的statusCode就是http状态码.而响应体信息就是回调的data,那么既然AFNetworking的封装没有回调data,我又需要data,难道要我换掉AFNetworking的网络框架么?这太蠢了.或者在AFNetworking的failure中再次用NSURLSessionDataTask再次请求这个借口从而获得data么?这个也很蠢,因为同样的接口要请求两遍,耗时自然是double,而且会消耗大量的资源.正在思考这解决方法时,打印出来的error错误信息提醒了我.研究了一番error感觉回调的响应体数据是有长度,不过我确定那个究竟是error相关信息还是请求的响应体.点开NSERROR类

@interface NSError : NSObject <NSCopying, NSSecureCoding> {
    @private
    void *_reserved;
    NSInteger _code;
    NSString *_domain;
    NSDictionary *_userInfo;
}

你会发现有个叫userInfo的成员变量,而在这个成员中,包含着若干个键值对,其中有个key叫做

@"com.alamofire.serialization.response.error.data"

这个key对应的value是一串data类型的数据,ok,我们把这个data转换成NSString类型打印出来一看,正是返回的响应体数据,其中就包括了需要的errorcode.这样的处理方式就做到在一次请求中,无论请求目的是否达到,都能获得请求的响应体信息从而正确的提醒用户.

解决问题&show me code


errorBlock:^(NSURLSessionDataTask * _Nullable __strong task, NSError * _Nonnull error) {
    NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
    NSInteger statusCode = response.statusCode;
    //如果响应头http状态码是400了则进一步查下原因
    if (statusCode == 400) {
        NSData *errorData = error.userInfo[@"com.alamofire.serialization.response.error.data"];
        NSDictionary *errorDataDict = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"400请求后进一步查询响应体:%@",errorDataDict);
        NSArray *allKeys = [errorDataDict allKeys];
        if ([allKeys containsObject:@"errorCode"]) {
            NSInteger errorCode = [errorDataDict[@"errorCode"] integerValue];
            //此处写根据errorCode对用户提醒弹窗(如果你用hud记得回调回主线程)或者回调.......
        } 
}

一点小tips:

  • @"com.alamofire.serialization.response.error.data"这个key只会出现在有响应体存在情况下的error.userInfo中,不用担心其他error的时候会取到奇怪的东西,同样的当出现其他类似的key的时候也可以关注一下,看看会有什么样的错误结果.
  • 其实NSError这个类的功能非常强大,如果遇到有报错的时候可以花时间研究下错误信息,没准就找到解决之道了,尤其是其中的error.userInfo.再不行通过error.code去查也更快更方便.
  • 最后,如有错误,恳请斧正.
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容