AFNetworking 3.x 使用心得

AFNetworking毫无疑问是目前iOS开发中(Objective-C)最好的第三方网络库。一般规模的app使用AFNetworking就可以完成所有需求,不需要自己造轮子。
在使用AFNetworking的过程中遇到了许多坑,也获得了不少经验,在这里总结一下,希望能够帮助到大家。

AFNetworking进一步封装

AFNetworking 3.x 已经为我们提供了丰富而且易用的API,但还是不够。AFNetworking是一个通用的库,而在我们自己的项目中,有特定的需求,而且往往在许多类中都需要用到网络请求。对AFNetworking进一步封装,能够大大简化代码,减少重复。
举个例子,新建一个CDMNetworkManager类,继承AFHTTPSessionManager。

//CDMNetworkManager.h
#import <AFNetworking/AFNetworking.h>

typedef void(^requestSuccessBlock) (NSURLSessionTask *task, id resposeObject);
typedef void(^requestFailureBlock) (NSURLSessionTask *task, NSError *error);

@interface CDMNetworkManager : AFHTTPSessionManager
+(instancetype)sharedManager;
-(void)sendPostRequest:(NSString *)path parameters:(NSDictionary *)parameters success:(requestSuccessBlock)success failure:(requestFailureBlock)failure;
//CDMNetworkManager.m
#import "CDMNetworkManager.h"

typedef void(^requestSuccessBlock) (NSURLSessionTask *task, id resposeObject);
typedef void(^requestFailureBlock) (NSURLSessionTask *task, NSError *error);

@implementation CDMNetworkManager

+(instancetype)sharedManager{
    static CDMNetworkManager *manager = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
       manager = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.someurl.com/"]];

    });
    return manager;
}

-(void)sendPostRequest:(NSString *)path parameters:(NSDictionary *)parameters success:(requestSuccessBlock)success failure:(requestFailureBlock)failure{
    [self POST:path parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject){
        success(task,responseObject);
    } failure:^(NSURLSessionTask *task, NSError *error){
        failure(task,error);
    }];
}

初始化方法中使用了单例模式,这样与服务器的连接不会断掉,省去了每次建立连接时三次握手等过程。如果有多个URL地址,可以创建多个单例。如果有更多特殊的要求,比如设置超时时间等,可以在这个方法中设置。
具体的网络请求方法这里只封装了一个简单的post方法,如果有需要可以封装别的方法。
调用的时候很简单,在任何一个需要发送post请求的类中:

[[CDMNetworkManager sharedManager] sendPostRequest:@"XXX" parameters:parameter success:^(NSURLSessionTask *task, id responseObject){
        //your code
    } failure:^(NSURLSessionTask *task, NSError *error){
        // your code
    }];

调试工具

曾经我每次网络请求调试的时候只会在回调里写log,然后在控制台里一行一行的仔细查找。如果这个请求返回的内容很多,在Xcode里的显示效果就很差,而且不能直接显示中文。体验很差!

这时候需要神器Charles

上面是Charles的截图,能够监听Mac的所有网络请求并且显示各种格式的内容,非常好用。如果用模拟器的话就可以直接用Charles抓包,如果真机调试的话,需要设置一下iPhone,网上也有很多教程。
虽然是付费软件,但是不买license只是打开时会有10秒延时,每隔30分钟自动关闭。

常见错误

Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html"

出现这个问题的原因有很多,从表面上看是返回数据的格式不支持text/html,但是为什么返回了text/html?原因不唯一。
首先要看请求的response code,如果是200,说明请求已经传到服务器并且成功返回,返回的格式是text/html。AFNetworking的默认response serializer是AFJSONResponseSerializer,不支持text/html。
这时需要在manager的初始化方法中增加一下代码。或者与服务器开发人员沟通,改写服务器端。

manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];

如果response code是400,说明服务器根本没有收到请求。这时为什么返回了一个text/html的数据呢?返回的数据在Xcode控制台上显示为16进制,但是在Charles里我们可以看到结果

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>请求错误</title>
    <style>BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; border-bottom: 2px white solid; background-color: #e5e5cc;}</style>
  </head>
  <body>
    <div id="content">
      <p class="heading1">请求错误</p>
      <p xmlns="">服务器处理请求时遇到错误。有关构造有效服务请求的内容,请参阅<a rel="help-page" href="http://www.zjubiomedit.com:13264/HypertensionService.svc/help">服务帮助页</a>。</p>
    </div>
  </body>
</html>

这是自动返回的一个错误页面,而不是服务器返回的数据格式不对。这时候再去找response serializer的问题就南辕北辙了。

那么为什么服务器没有受到请求?
一种可能是baseURL的问题。AFHTTPSessionManager的初始化中用到了baseURL,与之后的path拼接时可能出错,检查一下。
还有可能是request serializer的问题。AFNetworking默认的是AFHTTPRequestSerializer。如果服务器接受的参数只能是json的话,需要使用AFJSONRequestSerializer。

self.requestSerializer = [AFJSONRequestSerializer serializer];

可能还有其他各种各样奇怪的原因,欢迎大家补充。

作者时间、能力有限,文章难免有不足之处,请大家指正。

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,946评论 4 60
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • Swift版本点击这里欢迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh阅读 25,216评论 7 249
  • 目录|每一刻都是崭新的 上一章 文|于一潇 7、 商业街越来越旺了,辛月的时光咖啡书吧也跟着旺了起来。每到周末,辛...
    于一潇阅读 366评论 12 9
  • 大家好!给大家介绍一下,这是我新出炉的男朋友……@樱空释 其实还有待细化细节……可是画着画着,竟然有初恋的影子重叠...
    笑语浅兮阅读 699评论 0 3