AFNetworking POST操作

AFNetworking POST操作

网络请求部分,我们上一片分析了GET请求源码部分,通过这篇我们来了解关于POST请求的源码部分,其实POST和GET实现过程是一样的就是中间处理部分会出现略微差异。

POST操作

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters headers:(nullable NSDictionary <NSString *, NSString *> *)headers progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters headers:headers uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
    
    [dataTask resume];
    
    return dataTask;
}

传入的参数和GET方法相同:

  1. 请求的URL网址;
  2. 请求头(字典);
  3. 上传进度;
  4. 成功回调;
  5. 失败回调;

同样,返回的是一个NSURLSessionDataTask对象,并且实现了启动任务[dataTask resume];。

进入POST源码我们可以看到,实际上操作是和GET方法调用了一个方法。在这里我们就能清楚的意识到,从这里开始整个流程是一样的,不过对于POST和GET方法是通过之前对Method来区分对待的。
在GET中method传入的是@"GET",而在POST中传入的是@"POST"。

  1. GET
[self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters headers:headers uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure];
  1. POST
[self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters headers:headers uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];

保存方法

最后到达方法内部,进行保存了HTTP请求方式为POST,此时的method为POST。

mutableRequest.HTTPMethod = method;

AFNetworking应该注意的好的编程方法

这样部分摘自GET和POST共同方法中,我们知道做网络编程中,会出现错误问题,AFNetworking为我们做出了很好的典范,当我们设置了NSError *error后,需要判断如果error出现了错误的情况,如果出现了错误,我们则需要开辟一条新的线程来做错误处理。

if (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }
         
        return nil;
}

网络编程遇到线程错误问题是非常常见的,因此,对于错误处理AFNetworking做的非常完善。

反向思考

看到这里,GET和POST的处理方式,是大抵相同的。我们反着梳理一遍思路。首先,要做GET和POST请求,我们需要知道请求网址,因为POST需要的内容比GET多请求头,因此,设计方法时候,将方法安装POST方法设计,当GET调用时候,不需要的地方传入nil即可,此时要能请求POST和GET方法,还需要生成NSURLSessionDataTask,要DataTask就需要NSURLRequest。所以,我们就专门对Request进行一次封装,从用户传入的请求头和请求方法获得信息给Request。这样,Request是带着信息传给NSURLSessionDataTask,这样,就可以生成一个具有这些信息的DataTask。然后,启动任务即可。
或许,你看到这里有疑惑,那成功做的事情和失败做的事情以及进度条是怎么做的呢,的确,设计方法时候,AFNetworking将这三个板块设计成为Block回调,这样就可以等请求完成后,继续运行用户传入的东西。

这些回调原来系统需要使用协议来使用,AFNetworking自然会遵循这一个操作,因此,我们来看看AFNetworking封装的协议。

AFNetworking封装协议

- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask
                uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
              downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
             completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
    /* 通过dataTask实例化一个delegate对象 */
    AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];
    
    /* 将自身传给delegate对象的管理者 */
    delegate.manager = self;
    
    delegate.completionHandler = completionHandler;

    /* 任务描述 */
    dataTask.taskDescription = self.taskDescriptionForSessionTasks;
    [self setDelegate:delegate forTask:dataTask];

    /* 传入更新Block和下载Block块 */
    delegate.uploadProgressBlock = uploadProgressBlock;
    delegate.downloadProgressBlock = downloadProgressBlock;
}

@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>

AFNetworking创建一个AFURLSessionManagerTaskDelegate来管理协议,这个协议继承了NSURLSessionTaskDelegate,NSURLSessionDataDelegate,NSURLSessionDownloadDelegate这三个我们经常使用的三个协议。

@property (nonatomic, weak) AFURLSessionManager *manager; //url话语管理者
@property (nonatomic, strong) NSMutableData *mutableData; //数据
@property (nonatomic, strong) NSProgress *uploadProgress; //更新进度
@property (nonatomic, strong) NSProgress *downloadProgress; //下载进度
@property (nonatomic, copy) NSURL *downloadFileURL; //下载文件的路径

AFURLSessionManagerTaskDelegate将存储每一个协议内容,包括上传进度,下载进度,下载文件路径等。

在设置协议中,有趣的是,AFNetworking向我们展示了区别于RAC锁住线程的方法。

- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
            forTask:(NSURLSessionTask *)task
{
    NSParameterAssert(task);
    NSParameterAssert(delegate);

    [self.lock lock];
    self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
    [self addNotificationObserverForTask:task];
    
    [self.lock unlock];
}

利用NSLock来锁住线程和释放线程操作。通过字典存储任务标识。为每个任务添加了通知。

@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier;

在这一步里面也进行了计算进度的操作。

AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];

至此,我们已经分析了大部分源码了,如果有兴趣的话,可以放下在AFNetworking中有对Delete实现的大量封装,这一个封装操作,下一篇会做详细介绍,来帮助梳理如何学习AFNetworking一样封装Delegate。

中文源码下载

AFNetworking中文源码: GitHub

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

推荐阅读更多精彩内容