【ios】使用Block对POST异步操作的简单封装

以下内容为原创,欢迎转载,转载请注明

来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3409721.html

一般情况下的POST异步操作需要实现以下几步:

1. 在controller.h上实现<NSURLConnectionDataDelegate>协议

2. 实现协议的几个方法,

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

3. 编写执行post请求的代码:

1 NSURL *url = [NSURL URLWithString:urlStr]; // 生成NSURL对象
2     // 生成Request请求对象(并设置它的缓存协议、网络请求超时配置)
3     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
4
5     [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; // 设置请求参数
6
7     // 执行请求连接
8     NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:executorDelegate];

 

如果controller有很多异步操作,处理就会很麻烦,而且,很多时候我们只需要处理完成和异常(比如超时)的时候的反馈即可

所以,我需要编写一个post请求的封装类,只要传入请求的url、请求参数(字符串形式)、完成时的回调block

首先,新建类:HttpPostExecutor,.h如下:

 1 //
 2 //  HttpPostExecutor.h
 3 //  HttpTest
 4 //
 5 //  Created by WANGJIE on 13-11-6.
 6 //  Copyright (c) 2013年 WANGJIE. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 @interface HttpPostExecutor : NSObject<NSURLConnectionDataDelegate>
12 {
13     NSMutableData *resultData; // 存放请求结果
14     void (^finishCallbackBlock)(NSString *); // 执行完成后回调的block
15
16 }
17 @property NSMutableData *resultData;
18 @property(strong) void (^finishCallbackBlock)(NSString *);
19
20 + (void)postExecuteWithUrlStr:(NSString *)urlStr Paramters:(NSString *)params FinishCallbackBlock:(void (^)(NSString *))block;
21
22 @end

 

实现了<NSURLConnectionDataDelegate>协议,因为它要接收post请求的几个回调。

有一个NSMutableData对象,这个对象用于储存请求的结果。

一个finishCallbackBlock的block,这个block用于执行完成后的回调,这个block传入的参数就是返回的结果(这个结果已转成utf-8编码的字符串形式),我们可以在这个block中去处理请求完成后的逻辑

还有一个类方法,这个类方法暴露给外面,让外面进行调用

 

接下来,我们看下实现的方法.m文件:

  1 //
  2 //  POST异步请求的封装
  3 //  使用方法,只需传入url,参数组成的字符串,执行完成后的回调block
  4 //  如下:
  5 //  [HttpPostExecutor postExecuteWithUrlStr:@"http://www.baidu.com"
  6 //                              Paramters:@""
  7 //                    FinishCallbackBlock:^(NSString *result){  // 设置执行完成的回调block
  8 //                        NSLog(@"finish callback block, result: %@", result);
  9 //                    }];
 10 //  post提交的参数,格式如下:
 11 //  参数1名字=参数1数据&参数2名字=参数2数据&参数3名字=参数3数据&...
 12 //
 13 //
 14 //  HttpPostExecutor.m
 15 //  HttpTest
 16 //
 17 //  Created by WANGJIE on 13-11-6.
 18 //  Copyright (c) 2013年 WANGJIE. All rights reserved.
 19 //
 20
 21 #import "HttpPostExecutor.h"
 22
 23 @implementation HttpPostExecutor
 24 @synthesize resultData, finishCallbackBlock;
 25
 26 /**
 27  * 执行POST请求
 28  */
 29 + (void)postExecuteWithUrlStr:(NSString *)urlStr Paramters:(NSString *)params FinishCallbackBlock:(void (^)(NSString *))block
 30 {
 31     // 生成一个post请求回调委托对象(实现了<NSURLConnectionDataDelegate>协议)
 32     HttpPostExecutor *executorDelegate = [[HttpPostExecutor alloc] init];
 33     executorDelegate.finishCallbackBlock = block; // 绑定执行完成时的block
 34
 35
 36     NSURL *url = [NSURL URLWithString:urlStr]; // 生成NSURL对象
 37     // 生成Request请求对象(并设置它的缓存协议、网络请求超时配置)
 38     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
 39
 40     [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; // 设置请求参数
 41
 42     // 执行请求连接
 43     NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:executorDelegate];
 44
 45     NSLog(conn ? @"连接创建成功" : @"连接创建失败");
 46
 47 }
 48
 49
 50 /**
 51  * 接收到服务器回应的时回调
 52  */
 53 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
 54 {
 55     NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
 56     // 初始化NSMutableData对象(用于保存执行结果)
 57     if(!resultData){
 58         resultData = [[NSMutableData alloc] init];
 59     }else{
 60         [resultData setLength:0];
 61     }
 62
 63     if ([response respondsToSelector:@selector(allHeaderFields)]) {
 64
 65         NSDictionary *dictionary = [resp allHeaderFields];
 66
 67         NSLog(@"[network]allHeaderFields:%@",[dictionary description]);
 68     }
 69
 70 }
 71 /**
 72  * 接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次
 73  */
 74 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
 75 {
 76     [resultData appendData:data]; // 追加结果
 77 }
 78 /**
 79  * 数据传完之后调用此方法
 80  */
 81 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
 82 {
 83     // 把请求结果以UTF-8编码转换成字符串
 84     NSString *resultStr = [[NSString alloc] initWithData:[self resultData] encoding:NSUTF8StringEncoding];
 85
 86     if (finishCallbackBlock) { // 如果设置了回调的block,直接调用
 87         finishCallbackBlock(resultStr);
 88     }
 89
 90
 91 }
 92 /**
 93  * 网络请求过程中,出现任何错误(断网,连接超时等)会进入此方法
 94  */
 95 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
 96 {
 97     NSLog(@"network error: %@", [error localizedDescription]);
 98
 99     if (finishCallbackBlock) { // 如果设置了回调的block,直接调用
100         finishCallbackBlock(nil);
101     }
102
103
104 }
105 @end

View Code

在这个实现类中,我们在类方法中,先生成一个HttpPostExecutor对象,这个对象用于post请求的回调(因为实现了<NSURLConnectionDataDelegate>协议),然后去执行post连接。

接下来就等下面实现的回调方法被自动调用了,一旦调用

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

这个方法,就对resultData(用于存储post请求结果)进行初始化或者清空,因为要开始真正存储数据了嘛;

 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

这个方法进行回调的时候,把返回过来的这部分数据存储到resultData中,没什么好说的;

 

一旦回调- (void)connectionDidFinishLoading:(NSURLConnection *)connection这个方法,说明数据传输完毕了,要做的逻辑就是把数据转成utf-8编码的字符串,然后回调我们设置的回调finishCallbackBlock,把转好的结果字符串传进去,这样我们在回调block方法中实现的逻辑就能正常执行了。

 

一旦回调- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error这个方法,说明请求过程中出错了,比如断电、超时等,这时候,也回调我们设置的回调finishCallbackBlock,nil作为结果,这样我们在finishCallbackBlock中就能判断是正常的执行了post还是出了问题。

 

好了,接下来,我们就可以在外面去调用了,如下:

1 [HttpPostExecutor postExecuteWithUrlStr:@"http://www.baidu.com"
2                                   Paramters:@""
3                         FinishCallbackBlock:^(NSString *result){
4                             // 执行post请求完成后的逻辑
5                             NSLog(@"finish callback block, result: %@", result);
6                         }];

这样,以后post请求只需要去调用上面这个方法,在回调block中去处理结果

之后,在我们的代码编写中,就可以只关心业务逻辑,不需要去在意请求协议和回调了

 

测试demo下载

 

时间: 2024-10-01 18:16:26

【ios】使用Block对POST异步操作的简单封装的相关文章

iOS流布局UICollectionView系列一——初识与简单使用UICollectionView

iOS流布局UICollectionView系列一--初识与简单使用UICollectionView 一.简介         UICollectionView是iOS6之后引入的一个新的UI控件,它和UITableView有着诸多的相似之处,其中许多代理方法都十分类似.简单来说,UICollectionView是比UITbleView更加强大的一个UI控件,有如下几个方面: 1.支持水平和垂直两种方向的布局 2.通过layout配置方式进行布局 3.类似于TableView中的cell特性外,

iOS网络编程之二——NSURLSession的简单使用

iOS网络编程之二--NSURLSession的简单使用 一.NSURLSession简介     在iOS7之后,NSURLSession作为系统推荐使用的HTTP请求框架,在进行前台请求的情况下,NSURLSession与NSURLConnection并无太大差异,对于后台的请求,NSURLSession更加灵活的优势就将展现无遗.         1.NSURLSession集合的类型         NSURLSession类提供3中Session类型:         Default类

iOS中Block的回调使用和解析详解_IOS

Block 回调实现 先跟着我实现最简单的 Block 回调传参的使用,如果你能举一反三,基本上可以满足了 OC 中的开发需求.已经实现的同学可以跳到下一节. 首先解释一下我们例子要实现什么功能(其实是烂大街又最形象的例子): 有两个视图控制器 A 和 B,现在点击 A 上的按钮跳转到视图 B ,并在 B 中的textfield 输入字符串,点击 B 中的跳转按钮跳转回 A ,并将之前输入的字符串 显示在 A 中的 label 上.也就是说 A 视图中需要回调 B 视图中的数据. 想不明白的同学

iOS通过block在两个页面间传值的方法_IOS

一.功能需求 在第一个页面中有一个button和一个label,label上默认显示"哈哈",点击button进入第二个页面.在第二个页面有一个UITextField和一个button2,点击button2回到第一个页面,但同时第一个页面的label上显示的文字修改为刚刚在UITextField写进去的文字. 二.先定义block 在要传值得那个页面定义含有block参数的方法,即在第二个页面的.h文件中定义: 重新定义:typedef void (^ReturnTextBlock)(

iOS利用Block逆向传值的方式详解_IOS

前言 在iOS通过代理逆向传值的方式详解一文中,分析了如何利用代理模式来逆向传值,其实还有一些其他的方式,如通知.Block等,相比较代理,我个人认为反而要简单些,但是需要处理好细节问题,如Block循环引用.还是用前文的案例,本次使用Block来实现,Block的基本知识本文不再赘述. 一.书写规范 Block传值,需要注意的是,谁传值就需要定义Block,捕获方仅仅需要传递Block给传值方,并处理捕获的值. 传值方      1.定义Block用于传值      2.声明一个上述Block

iOS中block类型大全

iOS中block类型大全 typedef的block 作为属性的block   作为变量的block   作为方法变量入参的block   作为方法参数的block   无名block   内联函数的block   递归调用的block   作为方法返回值的block   作为函数名的block(太过奇葩,完全不知道怎么用-_-!)

iOS 使用Block

引言: Block是Apple在iOS4.0对Objective-C引入的新特性,通过Block可以增强代码的可读性和耦合性,减少非必要性的代理(Delegate)模式. Block是一个代码块,非常类似JavaScript里面的匿名函数,也可以叫做闭包,所以你也可以用匿名函数的方式来理解Block. 本文Block的运行环境是在ARC模式下进行,非ARC的Block内存管理方面还是较为繁琐.所以,有了ARC,开发者不必过多的去关注Block在内存支配方面的问题. 参考资料:  1:Block使

iOS下拉选择菜单简单封装_IOS

本文实例为大家分享了简单封装的iOS下拉选择菜单代码,供大家参考,具体内容如下 // // OrderListDownMenu.h #import <UIKit/UIKit.h> @protocol OrderListDownMenuDelegate <NSObject> - (void)OrderListDownMenu:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; @end

iOS中视频播放器的简单封装详解_IOS

前言 如果仅仅是播放视频两者的使用都非常简单,但是相比MediaPlayer,AVPlayer对于视频播放的可控制性更强一些,可以通过自定义的一些控件来实现视频的播放暂停等等.因此这里使用AVPlayer的视频播放. 视频播放器布局 首先使用xib创建CLAVPlayerView继承UIView用来承载播放器,这样我们在外部使用的时候,直接在控制器View或者Cell上添加CLAVPlayerView即可,至于播放器播放或者暂停等操作交给CLAVPlayerView来管理.下面来看一下CLAVP