【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请求的代码:
NSURL *url = [NSURL URLWithString:urlStr]; // 生成NSURL对象
// 生成Request请求对象(并设置它的缓存协议、网络请求超时配置)
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:]; [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; // 设置请求参数 // 执行请求连接
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:executorDelegate];
如果controller有很多异步操作,处理就会很麻烦,而且,很多时候我们只需要处理完成和异常(比如超时)的时候的反馈即可
所以,我需要编写一个post请求的封装类,只要传入请求的url、请求参数(字符串形式)、完成时的回调block
首先,新建类:HttpPostExecutor,.h如下:
//
// HttpPostExecutor.h
// HttpTest
//
// Created by WANGJIE on 13-11-6.
// Copyright (c) 2013年 WANGJIE. All rights reserved.
// #import <Foundation/Foundation.h> @interface HttpPostExecutor : NSObject<NSURLConnectionDataDelegate>
{
NSMutableData *resultData; // 存放请求结果
void (^finishCallbackBlock)(NSString *); // 执行完成后回调的block }
@property NSMutableData *resultData;
@property(strong) void (^finishCallbackBlock)(NSString *); + (void)postExecuteWithUrlStr:(NSString *)urlStr Paramters:(NSString *)params FinishCallbackBlock:(void (^)(NSString *))block; @end
实现了<NSURLConnectionDataDelegate>协议,因为它要接收post请求的几个回调。
有一个NSMutableData对象,这个对象用于储存请求的结果。
一个finishCallbackBlock的block,这个block用于执行完成后的回调,这个block传入的参数就是返回的结果(这个结果已转成utf-8编码的字符串形式),我们可以在这个block中去处理请求完成后的逻辑
还有一个类方法,这个类方法暴露给外面,让外面进行调用
接下来,我们看下实现的方法.m文件:
//
// POST异步请求的封装
// 使用方法,只需传入url,参数组成的字符串,执行完成后的回调block
// 如下:
// [HttpPostExecutor postExecuteWithUrlStr:@"http://www.baidu.com"
// Paramters:@""
// FinishCallbackBlock:^(NSString *result){ // 设置执行完成的回调block
// NSLog(@"finish callback block, result: %@", result);
// }];
// post提交的参数,格式如下:
// 参数1名字=参数1数据&参数2名字=参数2数据&参数3名字=参数3数据&...
//
//
// HttpPostExecutor.m
// HttpTest
//
// Created by WANGJIE on 13-11-6.
// Copyright (c) 2013年 WANGJIE. All rights reserved.
// #import "HttpPostExecutor.h" @implementation HttpPostExecutor
@synthesize resultData, finishCallbackBlock; /**
* 执行POST请求
*/
+ (void)postExecuteWithUrlStr:(NSString *)urlStr Paramters:(NSString *)params FinishCallbackBlock:(void (^)(NSString *))block
{
// 生成一个post请求回调委托对象(实现了<NSURLConnectionDataDelegate>协议)
HttpPostExecutor *executorDelegate = [[HttpPostExecutor alloc] init];
executorDelegate.finishCallbackBlock = block; // 绑定执行完成时的block NSURL *url = [NSURL URLWithString:urlStr]; // 生成NSURL对象
// 生成Request请求对象(并设置它的缓存协议、网络请求超时配置)
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:]; [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; // 设置请求参数 // 执行请求连接
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:executorDelegate]; NSLog(conn ? @"连接创建成功" : @"连接创建失败"); } /**
* 接收到服务器回应的时回调
*/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
// 初始化NSMutableData对象(用于保存执行结果)
if(!resultData){
resultData = [[NSMutableData alloc] init];
}else{
[resultData setLength:];
} if ([response respondsToSelector:@selector(allHeaderFields)]) { NSDictionary *dictionary = [resp allHeaderFields]; NSLog(@"[network]allHeaderFields:%@",[dictionary description]);
} }
/**
* 接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[resultData appendData:data]; // 追加结果
}
/**
* 数据传完之后调用此方法
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 把请求结果以UTF-8编码转换成字符串
NSString *resultStr = [[NSString alloc] initWithData:[self resultData] encoding:NSUTF8StringEncoding]; if (finishCallbackBlock) { // 如果设置了回调的block,直接调用
finishCallbackBlock(resultStr);
} }
/**
* 网络请求过程中,出现任何错误(断网,连接超时等)会进入此方法
*/
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"network error: %@", [error localizedDescription]); if (finishCallbackBlock) { // 如果设置了回调的block,直接调用
finishCallbackBlock(nil);
} }
@end
在这个实现类中,我们在类方法中,先生成一个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还是出了问题。
好了,接下来,我们就可以在外面去调用了,如下:
[HttpPostExecutor postExecuteWithUrlStr:@"http://www.baidu.com"
Paramters:@""
FinishCallbackBlock:^(NSString *result){
// 执行post请求完成后的逻辑
NSLog(@"finish callback block, result: %@", result);
}];
这样,以后post请求只需要去调用上面这个方法,在回调block中去处理结果
之后,在我们的代码编写中,就可以只关心业务逻辑,不需要去在意请求协议和回调了
【ios】使用Block对POST异步操作的简单封装的更多相关文章
- iOS开发——UI篇OC篇&UITableView简单封装
UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...
- iOS之断点下载,使用NSURLSession简单封装
最近公司需要做个文件管理的功能模块,刚交到博主手上时,头都大了.因为没做过这方面的东西,只好咬牙加班,并请教某位大神,指点了一下,清楚研究方向,找了网上大量资料,最后实现简单的封装. 上代码:.h文件 ...
- iOS之block
1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...
- iOS中Block介绍(一)基础
ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发.讨论范围:block的使用,内存管理,内部实现.不包含的内容:gc arc下的block内存,block在c++中 ...
- iOS中Block介绍 基础
ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发.讨论范围:block的使用,内存管理,内部实现.不包含的内容:gc arc下的block内存,block在c++中 ...
- iOS 中Block以及Blocks的使用,闭包方法调用
OC: -(void)dataWithUrl:(NSString*)string AndId:(NSInteger)id returnName:(void(^)(NSString*name))back ...
- iOS中block的用法 以及和函数用法的区别
ios中block的用法和函数的用法大致相同 但是block的用法的灵活性更高: 不带参数的block: void ^(MyBlock)() = ^{}; 调用的时候 MyBlock(); 带参数的 ...
- iOS开发--Block
iOS开发--Block 1.什么是Block,block 的作用 ui开发和网络常见功能实现回调,按钮的事件处理方法是回调方法以及网络下载后的回调处理 (1)按钮 target-action 一 ...
- iOS开发UI篇—UITableview控件简单介绍
iOS开发UI篇—UITableview控件简单介绍 一.基本介绍 在众多移动应⽤用中,能看到各式各样的表格数据 . 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView,UIT ...
随机推荐
- SQL Server 2016的数据库范围内的配置
SQL Server 2016真的让人眼前一亮.几天前微软就提供了RCO(候选发布版)版本的下载.我已经围观了一圈RCO版本,其中一个最拽的功能是数据库范围内的配置(Database Scoped C ...
- 移动端中pagehide、pageshow的应用
闲话少叙,来进入场景:订单提交页面,各种积分礼品卡规则都算好了,用户提交表单开始支付,支付完成进入成功提示页面,这是绝大部分网站的付款体验吧,那么问题来了,web移动端中进入成功提示页后,用户点击浏览 ...
- SQLite中文排序
定义一个类: using System.Data.SQLite; namespace DAL { /// <summary> /// SQLite中文排序 /// </summary ...
- js动态显示表格的汇总信息和详细信息
我在做数据结果展示的时候,想要实现一个如下的功能: 用户可以选择一个时间段,默认显示这个时间段的汇总数据,当鼠标点击这个时间段的时候,将显示每个时间点的详细数据,再次点击的时候,详细数据收起,只 ...
- 最小生成树---Kruskal/Prime算法
1.Kruskal算法 图的存贮采用边集数组或邻接矩阵,权值相等的边在数组中排列次序可任意,边较多的不很实用,浪费时间,适合稀疏图. 方法:将图中边按其权值由小到大的次序顺序选取,若选边后不 ...
- PHP程序员7小时学会Kotlin系列
这是我尝试给自己一个目标去学会一门新语言的方法.正在创作中,敬请期待! 提纲 第一小时 概念 第二小时 基础 第三小时 函数 第四小时 类与对象 第五小时 类与对象二 第六小时 DSL 第七小时 工程 ...
- [转]JavaScript程序编码规范
原文:http://javascript.crockford.com/code.html 作者:Douglas Crockford 译文:http://www.yeeyan.com/articles/ ...
- PHP和Apache的安装
http://jingyan.baidu.com/article/154b46315242b328ca8f4101.html
- EasyUI+MVC-搭建后台框架
一.EasyUI简介: jQuery EasyUI是一组基于jQuery的UI插件集合体,而jQuery EasyUI的目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面. 官方网站:h ...
- VS2010下安装Cocos2dx完整教程(原)
一.本人所使用的Cocos2dx版本(cocos2d-2.1rc0-x-2.1.3),下载地址:http://code.google.com/p/cocos2d-x/downloads/list 当前 ...