2014-01-11 14:37:37 u011872945 阅读数 1356

上一讲介绍了iOS中的异步请求,这讲来看看IOS同步请求。

1、IOS网络请求,同步GET请求,代码如下:

 //请求地址
    NSString *urlString=@"http://192.168.18.66/webios/login.aspx?username=zhangsan&pwd=321654";
    
    NSURL *url=[NSURL URLWithString:urlString];
    //初始化请求
    NSURLRequest *request=[NSURLRequest requestWithURL:url];
    //发送数据,返回结果
    NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    //解析成字符串
    NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSLog(@"result:%@",str);

2、IOS网络请求,同步POST请求,代码如下:

//请求地址
    NSString *urlString=@"http://192.168.18.66/webios/login.aspx";
    NSURL *url=[NSURL URLWithString:urlString];
    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
    
    //设置请求方式
    request.HTTPMethod=@"POST";
    
    NSString *params=@"username=zhangsan&pwd=321654";
    
    NSData *data=[params dataUsingEncoding:NSUTF8StringEncoding];
    //设置请求内容
    request.HTTPBody=data;
    //发送请求,返回结果
    NSData *received=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
    NSString *result=[[NSString alloc] initWithData:received encoding:NSUTF8StringEncoding];
    
    NSLog(@"result:%@",result);




2014-11-05 01:31:43 DavyJonesWang 阅读数 541

IOS网络请求


IOS网络请求操作流程

1. 构造NSUSL对象
2. 构造NSURLRequest请
3. 调用NSURLConnection发送请求
4. 返回NSURLRespond响应对象和NSError实例对象
5. 通过NSURLRespond得到数据

//同步请求
NSURL *url = [NSURL URLWithString:  @"http://www.baidu.com/s?tn=baiduhome_pg&bs=NSRUL&f=8&rsv_bp=1&rsv_spt=1&wd=NSurl&inputT=2709"];     
NSLog(@"Scheme: %@", [url scheme]);    
NSLog(@"Host: %@", [url host]);    
NSLog(@"Port: %@", [url port]);        
NSLog(@"Path: %@", [url path]);        
NSLog(@"Relative path: %@", [url relativePath]);   
NSLog(@"Path components as array: %@", [url pathComponents]);           
NSLog(@"Parameter string: %@", [url parameterString]);      
NSLog(@"Query: %@", [url query]);          
NSLog(@"Fragment: %@", [url fragment]);  
NSLog(@"User: %@", [url user]);  
NSLog(@"Password: %@", [url password]); 

NSURLRequest * urlRequest = [NSURLRequest requestWithURL:url];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
                                          returningResponse:&response
                                                      error:&error];
//或者
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:@"GET"];
[request setURL:url];
[request setTimeoutInterval:60];
    
NSURLResponse *response;
//发送同步请求
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

<pre name="code" class="plain">if (error == nil)
{
        // 处理数据
}

//异步请求
NSURLConnection connectionWithRequest:request delegate:self];
#pragma mark - NSURLConnection delegate
//数据加载过程中调用
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
}
//数据加载完成后调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
}
//数据加载失败后调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
//或者
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse* respone, NSData* data, NSError* error){}];

[
2016-03-15 09:14:42 ccflying88 阅读数 7523

URL:统一资源定位符,用来唯一表示一个资源地址;

基本格式:协议://主机地址/资源路径
协议:不同的协议,代表不同的资源查找方式,资源传递方式
主机地址:存放资源的主机的IP地址(域名)
路径:资源在主机中的具体位置
网络资源:http://www.xxx
本地资源:file:///users/apple/desktop/xxx

HTTP协议
超文本传输协议,规定客户端和服务器之间的数据传输方式,让客户端和服务器能有效地进行数据沟通;

NSURL:根据地址封装地址对象

NSURL * url = [NSURL URIWithString:@"http://..."];
NSData *data = [NSData dataWithContentsOfURL:url];  // 获取数据流

NSURLRequest:一个NSURLRequest对象就代表一个请求,它包含的信息有

一个NSURL对象
请求方法,请求头,请求体
请求超时(timeoutInterval)等等…

NSMutableURLRequest:NSURLRequest的子类,可以添加更改请求头

[request setValue:@"bytes=500-999" forHTTPHeaderField:@"Range"]; // 断点下载;

NSURLResponse:请求响应对象

response.allHeaderFields;  // 获取http请求响应头信息;
response.expectedContentLength;  // 获取文件长度;

NSURLConnection

负责发送请求,建立客户端服务器的连接;
发送NSURLRequest的数据给服务器,并收集来自服务器的响应数据;

网络请求步骤:
1. 创建一个NSURL对象,设置请求路径;
2. 根据NSURL对象创建一个NSURLRequest对象,设置请求头和请求体,默认就是GET请求;
3. 使用NSURLConnection发送NSURLRequest;

发送网络请求有同步和异步两种方式

同步请求:

[conn sendSynchronousRequest:request returningResponse:nil error:ni]; // 同步请求,一直在等待服务器返回数据;

异步请求
<1>.直接发送请求

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[conn sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response,NSData *data, NSError *error){ // 当请求成功或者遇到请求错误时调用;
}];

第二个参数queue表示请求完成之后的代码块需要放置到哪个队列执行,如果手动新建一个queue,则会放到自己创建的queue中执行,如果想要更新ui,则需要传主线程的队列,通过[NSOperationQueue mainQueue]获取主队列;

<2>.通过代理来发送请求

+   NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
-   (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)immediately;
// 如果immediately为NO,则需要再调用[conn start];  // 异步执行;
// 实现代理对象4个常用方法
-(void)connection: didFailWithError:  // 请求错误(失败)时调用(超时,断网,客户端错误);
-(void)connection: didReceiveResponse:  // 当接收到服务器的响应就会被调用;
-(void)connection: didReceiveData:  // 当接收到服务器的数据时调用(可能会多次调用);
-(void)connectionDidFinishLoading:  // 服务器的数据接收完毕;

路径编码及请求参数设置

NSURL *url = [NSURL URLWithString:@"xxx"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 创建请求对象
request.timeoutInterval = 5;  // 设置请求超时;
request.HTTPMethod = @"POST";  // 设置POST请求;
// equest.HTTPMethod = @"HEAD";  // 获取http请求头信息(发送同步或者异步请求都行,但最好是异步请求);
[request setValue:@"ios" forHTTPHeaderField:@"User-Agent"];  // 设置请求头;
// 设置请求体;
NSString *param;
request.HTTPBody=[param dataUsingEncoding:NSUTF8StringEncoding];

NSURL里面不能包含中文,需要进行转码;

NSString *urlstr;
urlstr = [urlstr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSURLCache

硬盘缓存的位置:沙盒/Library/Caches

NSURLCache *cache = [NSURLCache sharedURLCache];  // 获取全局缓存对象
-(void)setMemoryCapacity:(NSUInteger)memoryCapacity;  // 设置内存缓存最大容量(默认为512kb)
-(void)setDiskCapacity:(NSUInteger)diskCapacity;  // 设置硬盘缓存最大空间(默认10M)

缓存策略:

NSURLRequestUseProtocolCachePolicy // 默认的缓存策略(取决于协议,也就是需要设置request的cookie等请求头)
NSURLRequestReturnCacheDataElseLoad //先加载缓存,如果没有则再去请求
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // 设置request的缓存策略

缓存操作:

-(NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; // 获取某个请求的缓存
-(void)removeCachedResponseForRequest:(NSURLRequest *)request; // 清除某个请求的缓存
-(void)removeAllCachedResponses; // 清除所有缓存

数据解析

Json解析(Json的MIMETYPE为application/json)

NSString *path = [[NSBundle mainBundle] pathForResource:@"data.json" ofType:nil];
NSData *data = [NSData dataWithContentsOfFile:path]; // 根据文件路径加载json文件到NSData中;
// 将加载进来的NSData数据转换为OC中的对象;
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:NULL];
[self setValueForKeysWithDictionary:dict];

NSJSONSerialization 常用方法:

JSON数据->OC对象

+(id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error

OC对象->JSON数据

+(NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error

XML解析
DOM:一次性将整个xml文档加载进内存,比较适合解析小文件;
SAX:从根开始,按顺序一个元素一个元素向下解析,比较适合解析大文件;

SAX解析

NSData *data;
NSXMLParser * parser = [[NSXMLParse alloc] initWithData:data];
parser.delegate = self;
[parser parse]; // 开始解析,解析过程是同步的,解析完成后再执行之后的方法;

DOM解析

GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil]; // 加载文档
CDataXMLElement *root = doc.rootElement; // 获取根元素
NSArray *arr = [root elementsForName:@"videos"]; // 获取元素集合
for(CDataXMLElement *ele in arr){ // 解析元素
    [ele attributeForName:@"id"].stringValue; // 获取节点属性值;
}

iOS9 新特性

The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
Google后查证,iOS9引入了新特性App Transport Security (ATS)。详情:App Transport Security (ATS)

新特性要求App内访问的网络必须使用HTTPS协议。
但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输。
解决办法:

在Info.plist中添加NSAppTransportSecurity类型Dictionary。
在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES。

第三方框架

ASI
依赖于三个框架

libz.1.2.5.dylib
MobileCoreServices.framework
SystemConfiguration.framework

ASIHTTPRequest
继承自NSOperation,所以也就可以将多个ASIHTTPRequest添加到NSOperationQueue中,同时管理多个请求,也可以设置请求之间的依赖;

[request clearDelegatesAndCancel];  // 当控制器被销毁的时候,取消请求;
[request setSceondsToCache:60 * 60 * 24 * 7];  // 缓存7天;
[request didUseCachedResponse];  // 判断数据是否从缓存读取;

​1.GET请求

ASIHTTPRequest *reqeust = [ASIHTTPRequest requestWithURL:url];

2.POST请求

ASIFormDataRequest *reqeust = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"key1" forKey:@"value1"]; // 非文件参数

3.文件下载

request.downloadDestinationPaht = filePath; // 文件下载路径
request.downloadProgreddDelegate = progressView; // 下载代理,监听下载进度
request.allowResumeForFileDownloads = YES; // 支持断点下载

4.文件上传

[request setFile:file forKey:@"file"]; // 添加文件参数(file:要上传的文件的路径)
[request setFile:file withFileName:@"xx.txt" andContentType:@"text/plain"]; // xx.png image/png
request.uploadProgressDelegate = progressView; // 上传代理(监听上传进度)

5.监听请求的过程
<1>. 代理方法

request.delegate = self;  // 遵守协议ASIHTTPRequestDelegate
// 实现代理方法
-(void)requestStarted:(ASIHTTPRequest *)request;
-(void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data;
-(void)requestFinished(ASIHTTPRequest *)request;
-(void)requestFailed:(ASIHTTPRequest *)request;

<2>. SEL

request.delegate = self;  // 设置代理
[request setDidStartSelector:@selector(start)];  // 开始发送请求的时候调用start方法

<3>. block

[request setStartedBlock:^{}];
[request setDataReceivedBlock:^(NSData *data){}];
[request setCompletionBlock:^{}];
[request setFailedBlock:^{}];

6.通过requst对象获取服务器的响应
<1>. 获取响应头信息

@property (atomic, retain) NSDictionary *responseHeaders;

2> 获取响应体

-(NSData *)responseData;  // 直接返回服务器的二进制数据
-(NSString *)responseString;  // 将二进制数据转换成字符串(debug)

7.缓存

// 1.获取全局缓存对象(缓存的存储路径)
ASIDownloadCache *cache = [ASIDownloadCache sharedCache];
// 1.1设置默认折缓存加载策略
cache.defaultCachePolicy = ASIDoNotReadFromCacheCachePolicy;

// 2.设置请求对象的缓存对象
request.downloadCache = cache;
// 3.设置请求对象的缓存加载策略
request.cachePolicy = ASIOnlyLoadIfNotCachedCachePolicy;
// 4.设置请求对象的缓存存储策略
request.cacheStoragePolicy = ASICachePermanentlyCacheStoragePolicy;
// 5.优先级
request.cachePolicy > cache.defaultCachePolicy;

AFN
1.GET/POST

// 1.获取请求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager]; 
// 2.封装请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"key1"] = @"value1";
// 3.发送GET请求
[mgr GET:@"http://..." parameters:params success:^(AFHTTPRequestOperation *operation ,id responseObject){
} failure:^(AFHTTPRequestOperation *operation, NSError *error){}];
// 4.发送POST请求,只需要把3中的GET换成POST即可

2.文件上传

// 1.获取请求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
// 2.封装请求参数#只能放非文件参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"key1"] = @"value1";
// 3.上传文件
[mgr POST:@"http://..." parameters:params
 constructingBodyWithBlock:^(id<AFMultipartFormData> formData){
 // 在block方法中添加文件参数 
 NSData *data = [NSData dataWithContentsOfFile:file];
 [formData appendPartWithFileData:data name:@"file" fileName:@"12.txt" mimeType:@"text/plain"];
 }
 success:^(AFHTTPRequestOperation *operation ,id responseObject){}
 failure:^(AFHTTPRequestOperation *operation, NSError *error){}];

3.网络监控

AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
[mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status){
}];
[mgr startMonitorint];  // 开始监控

ASI和AFN区别
1.性能

ASI基于底层CFNetwork
AFN基于NSURLConnection
运行性能:ASI > AFN

2.处理服务器数据

<1>. AFN:根据服务器返回的数据,自动解析
JSON数据自动转换为NSDictionary或者NSArray
XML数据自动转换为NSXMLParser
<2>. ASI:直接返回NSData二进制数据

3.处理请求的过程

AFN:success和failure两个block
ASI:有三种方法处理请求过程(代理方法\SEL\block)

4.特点
ASI:

缓存
下载和上传
* 监听请求进度
* 实现断点下载(ASI没有断点上传功能,断点上传需要使用socket)
提供了扩展接口(比如数据压缩)
ASIDataCompressor.h
ASIDataDecompressor.h
ASIHttpRequest继承自NSOperation
* 能用队列统一管理所有请求
* 请求之间能够依赖
ASINetworkQueue
* 统一管理所有请求
* 多个下载\上传 –> ASINetworkQueue
* 监听多个请求的总进度(开始/失败/完毕)
* shouldCancelAllRequestOnFailure // 返回YES: 队列中的某个请求失败后,其它所有请求都取消;

AFN默认的数据解析器是JSON数据解析器,而默认的json数据解析器只支持三种服务器返回的数据类型(Content-type);
分别是:application/json,text/json,text/javascript,我们可以自己在集合中再添加一种数据类型;

AFHTTPRequestOperationManager *mgr;
mgr.responseSerializer.acceptableContentTypes;  // 解析器支持的数据集合;
2016-05-07 15:46:09 ohyeahhhh 阅读数 1720

有关网络请求的类(该图片来自:developer.apple.com)

加载url的类总汇

一、url请求

网络请求的组成部分有服务器地址、请求参数,以及请求方式。在iOS中,一个网络请求用NSURLRequest(或者其子类NSMutableURLRequest)来表示。

NSURLRequest适合于get请求,NSMutableURLRequest可以是post请求。

get方式下,服务器地址和请求参数都可以明文包含在url中,可以直接使用这个url来创建NSURLRequest(或者NSMutableURLRequest)。

post方式下,服务器地址用NSURL来表示,请求参数可以封装到NSData中(也可以以文件或者流的形式保存)。由于需要将服务器地址和请求参数分开,所以需要用到NSMutableURLRequest类。用服务器地址的url创建NSMutableURLRequest对象,然后将封装了请求参数的NSData对象添加到这个NSMutableURLRequest对象中。示例如下:

NSURL *url=[NSURL URLWithString:@“http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx"];
NSData *data=[@"date=20151101&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" dataUsingEncoding:NSUTF8StringEncoding];

然后将服务器地址与请求参数加入到NSMutableURLRequest对象中:

NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:60];
request.HTTPMethod=@"post";//指明请求方式为post,默认为get
request.HTTPBody=data;

这样就准备好了一个网络请求,接下来就是如何去执行这个网络请求的问题。

二、执行url请求

执行url请求可以使用iOS原生API也可以使用第三方库。

执行url请求的两个原生方法:
(1)NSURLSession
(2)NSURLConnection
iOS 7.0 以后推荐使用NSURLSession,以前使用NSURLConnection。
NSURLSession、NSURLConnection都可以发送和接收以NSData或者文件的形式保存的数据.

实现url请求的第三方库有afNetworking、sdWebImage等。

1.两个原生方法的基本使用思路

(1)每个项目都有一个NSURLSession对象,可以通过[NSURLSession sharedSession]方法来获取它,然后就可以用它来新建请求任务。该任务调用resume方法后开始执行。请求任务有三种,上传、下载、数据。通过NSURLSession来执行url请求是异步的。

(2)NSURLConnection直接执行send方法(类方法)发送请求,可以选择同步也可以选择异步。异步发送请求接收数据的话可以使用block接收,也可以使用代理。注意如果使用代理来接收数据,数据会是断续接收的。通常使用block比较方便。

同步和异步的区别就是,同步就是执行完网络请求方法后,要等到网络请求得到响应并完成数据传输之后才返回,异步就是发送完请求之后马上返回。

2. NSURLSession详解

获取session可以通过初始化方法,也可以直接使用项目默认的session对象,通过sharedSession方法获取。初始化session对象需要指定代理,如果指定为nil,就是使用系统默认的代理。

(1)session的分类

session分为3种:

  • 默认的(default session):会将存储数据存到硬盘上。
  • 短暂的(ephemeral session):不会存储任何数据到硬盘上,只会占用内存,当session释放了,所有的数据也就没有了。
  • 后台的(background session):和默认的session的区别在于会用独立的过程来处理数据传输。

初始化session的时候需要指定一个NSURLSessionConfiguration对象,session的类型就由这个对象的类型来确定。

(2)任务task的分类

任务分为3种,数据、下载、上传:

  • data task数据任务:发送和接收NSData形式的数据
  • download task下载任务:解析文件形式的数据,支持app没有运行的时候在后台执行。
  • upload task上传任务:发送文件形式的数据,也支持后台执行。

(3)任务task和session的关系

  • 任务的初始化和任务的管理都由session来完成。

  • 每个session对象管理着它自己创建的任务。

  • 任务创建后需要执行resume方法,session才会处理它。

  • 任务处理的具体操作是由session的代理来完成的,也就是说具体的处理会写在代理方法中。

(4)利用session完成后台传输

需要注意的问题:

  • 只有后台类型的session才可以新建支持后台传输的任务(下载任务或上传任务)。而且后台上传只支持文件上传,如果上传的是NSData对象或者数据流,在app退出后就会断掉。
  • 后台任务只支持http和https协议,不支持自定义协议。
  • 如果后台传输的任务是在app已经进入了后台之后才初始化的,那么session的NSURLSessionConfiguration对象的discretionary属性值为true。
  • 由于网络错误导致的后台上传或后台下载任务失败,系统会自动重新尝试执行这些任务,所以不需要自己写代码来重新执行失败的后台任务。

后台任务与app的交互:

后台任务的特点就是运行在后台,当app不在运行的时候后台任务仍然可以运行。

上面说过,任务的处理是由session的代理方法来完成的,但是当app没有运行的时候,session已经被释放,这时候后台任务怎么和创建这个任务的session重新关联起来呢?

这个问题iOS系统已经有一套完整的机制去处理它。是这样的:当后台任务完成或者需要认证的时候,如果app没有在运行,系统就会唤醒app,并调用app delegate的(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler方法。这个方法就是特地写来处理后台任务的,下面所描述的内容都围绕这个方法来展开。

需要重写在这个方法,在这个方法中让后台任务和session重新关联起来。由于创建它的session已经释放,要找回它不可能,实际的做法是创建一个和它一样的session,然后让任务与这个session关联起来。具体就是用这个方法的参数identifier来新建一个NSURLSessionConfiguration对象,并且用这个NSURLSessionConfiguration对象新建一个session,这个session就可以当成是原来的session了。神奇的是,只要这样创建了session,正在运行的任务就会自动和它关联起来,至于是怎么做到了,不需要操心,系统已经解决了。

留意到这个方法有一个block类型的参数completionHandler,它的意义在于,一旦它被执行就表明后台任务处理完成,因此系统自唤醒app之后就会一直等待completionHandler的执行,以便让app重新停止运行。因此,要记得把completionHandler传给session的代理,并且在session的代理方法URLSessionDidFinishEventsForBackgroundURLSession:中调用它,这样就实现了在最后一个任务处理完毕以后让app再次进入后台。

在正在运行的任务已经和session重新取得联系之后就会调用其代理的相关方法,如果是后台任务完成,就会调用URLSession:downloadTask:didFinishDownloadingToURL:方法。如果是需要认证,就会调用URLSession:task:didReceiveChallenge:completionHandler:方法或者URLSession:didReceiveChallenge:completionHandler:方法。

官网例子:https://developer.apple.com/library/ios/samplecode/SimpleBackgroundTransfer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40013416

(4)下载文件

与文件下载有关的协议方法:

  • URLSession:downloadTask:didFinishDownloadingToURL:
    文件下载完成后调用,可以获取下载好的文件的url
  • URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
    下载过程中调用
  • URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:
    该方法在开始恢复一个失败的下载任务之后调用
  • URLSession:task:didCompleteWithError:
    下载任务完成或终止后调用,如果任务出错,可以获取到NSError对象
  • 终止下载任务
    可以调用NSURLSessionDownloadTask对象的方法:cancelByProducingResumeData:
  • 恢复下载任务
    可以调用sessiondownloadTaskWithResumeData:downloadTaskWithResumeData:completionHandler:
    这里的resumeData从协议方法URLSession:task:didCompleteWithError:中的NSError对象的userInfo字典中会有,对应key为NSURLSessionDownloadTaskResumeData

(5)重定向

相关协议方法:

- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
        newRequest:(NSURLRequest *)request
 completionHandler:(void (^)(NSURLRequest *))completionHandler

对于默认的session和暂时的session管理的url请求任务发生重定向时就会调用这个方法,而后台任务发生重定向会直接服从重定向。

在这个方法里面,可以获取到新的url请求,调用completionHandler(request);就会允许重定向。如果调用completionHandler(nil);就相当于拒绝重定向。当然也可以调用completionHandler(otherRequest);实现自定义重定向。

2013-09-11 18:17:11 kaven_lv 阅读数 689

在项目中我封装了个http请求的工具类,因为项目中只用到post请求,所以get请求的方法只是刚开始试了下,行得通,不知到有没有错误,代码如下:
h文件:
[cpp]
#import <Foundation/Foundation.h> 
 
/*
 *自定义http代理
 */ 
@protocol MyhttpUitlDelegate <NSObject> 
-(void) setServicereturnData:(NSString*)servicedata; 
@end 
 
@interface MyHTTPUtil : NSObject<NSXMLParserDelegate> { 
    NSMutableData *webData;//异步请求返回回来的数据 
     
    id<MyhttpUitlDelegate> myhttputildelegate; 
    NSString *dialogcanshow;//防止快速两次请求以上弹出多个等待对话筐 
     
    //等待对话筐 
    UIAlertView *mt; 

 
@property(nonatomic,retain)id<MyhttpUitlDelegate> myhttputildelegate; 
@property(nonatomic,retain)UIAlertView *mt; 
@property(nonatomic,retain) NSString *dialogcanshow;//防止快速两次请求以上弹出多个等待对话筐 
 
+(NSString *)httpForTongbuGET:(NSString *)urlstring; 
+(NSString *)httpForTongbuPOST:(NSString *)urlstring addParms:(NSData *)urlparms; 
//-(void)httpForYibuPOST:(NSString *)urlstring addParms:(NSString *)urlparms; 
-(void)httpForYibuPOSTForData:(NSString *)urlstring addParms:(NSData *)urlparms; 
-(void)httpForYibuGET:(NSString *)urlstring addParms:(NSString *)urlparms; 
-(void)httpForYibuPOSTPageparms:(NSString *)urlstring addParms:(NSData *)pageparms; 
-(void)showwaitalertview; 
 
@end 

m文件
[cpp]
#import "MyHTTPUtil.h" 
#import "FileUtils.h" 
 
@implementation MyHTTPUtil 
//url公用部分 
//NSString *baseurl = @"http://192.168.0.63:8080/mbtravel/"; 
//NSString *baseurl = @"http://192.168.0.63:8081/mbtr/"; 
NSString *baseurl = @"http://192.168.128.1:8080/mbtravel/"; 
NSInteger PagingRows = 5;//每页的行数 
@synthesize myhttputildelegate; 
@synthesize dialogcanshow; 
@synthesize mt; 
 
-(void)dealloc{ 
    [myhttputildelegate release]; 
    [dialogcanshow release]; 
    [mt release]; 
    [super dealloc]; 

 
-(id)init{ 
    self.dialogcanshow = @"false"; 
   return  [super init]; 

 
//http的同步get请求,返回服务器返回的数据 
+(NSString *)httpForTongbuGET:(NSString *)urlstring{ 
    NSString *allurl = [NSString stringWithFormat:@"%@%@",baseurl,urlstring]; 
    NSURL* url = [NSURL URLWithString:allurl];   
     
    NSMutableURLRequest* request = [[[NSMutableURLRequest alloc]init]autorelease];  
    [request setURL:url];   
    [request setHTTPMethod:@"GET"];  
    NSString *contentType = [NSString stringWithFormat:@"text/xml"];//@"application/json"  
    [request addValue:contentType forHTTPHeaderField:@"Content-Type"]; 
    NSHTTPURLResponse *urlResponese = nil; 
    NSError *error = [[NSError alloc]init]; 
    NSData* data = [NSURLConnection sendSynchronousRequest:request   returningResponse:&urlResponese error:&error];  
    NSString* result= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    if([urlResponese statusCode] >=200&&[urlResponese statusCode]<300){ 
         
        return result; 
    } 
    return nil; 
    [error release]; 
    [result release]; 

 
 
//异步get请求 
-(void)httpForYibuGET:(NSString *)urlstring addParms:(NSString *)urlparms{ 
    //    if ([ValueUtils caseEquals:self.dialogcanshow to:@"true"]){ 
    //        [self showwaitalertview];//弹出等待对话筐 
    //    } 
    //     
    NSString *allurl = [NSString stringWithFormat:@"%@%@%@",baseurl,urlstring,urlparms]; 
    NSLog(@"%@",allurl); 
    NSURL *url = [NSURL URLWithString:allurl];                            
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15];   
     
    [theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
    //[theRequest setTimeoutInterval:15];//设置了也是无效 
    [theRequest setHTTPMethod:@"GET"];  
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES]; 
     
    if(theConnection) { 
        webData = [[NSMutableData data] retain]; 
         
    } 

// 
////异步post请求,带参数 
// 
//-(void)httpForYibuPOST:(NSString *)urlstring addParms:(NSString *)urlparms{ 
////    if ([ValueUtils caseEquals:self.dialogcanshow to:@"true"]) { 
////        [self showwaitalertview];//弹出等待对话筐 
////    } 
//     
//    NSString *allurl = [NSString stringWithFormat:@"%@%@%@",baseurl,urlstring,urlparms]; 
//          //NSStringEncoding  enc=CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);   //转换编码,包括中文 
//   // NSString *allurl2=[allurl stringByAddingPercentEscapesUsingEncoding:enc]; 
//   NSString *allurl2= [allurl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
//    NSLog(@"url===%@",allurl2); 
//    NSURL *url = [NSURL URLWithString:allurl2];    
//    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15];   
//    [theRequest  setValue:@"zh-cn" forHTTPHeaderField:@"Accept-Language"]; 
//      [theRequest  setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"]; 
//    [theRequest addValue: @"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; 
//    //[theRequest setTimeoutInterval:15];//设置了也是无效 
//    [theRequest setHTTPMethod:@"POST"];  
//    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES]; 
//     
//     
//    if(theConnection) { 
//        webData = [[NSMutableData data] retain]; 
//         
//    } 
//} 
 
 
 
//基本上只用下面这三个方法 
 
 
//http的同步post请求,返回服务器返回的数据 
+(NSString *)httpForTongbuPOST:(NSString *)urlstring addParms:(NSData *)urlparms{ 
    NSString *allurl = [NSString stringWithFormat:@"%@%@",baseurl,urlstring]; 
    NSURL* url = [NSURL URLWithString:allurl];   
    NSMutableURLRequest* request = [[[NSMutableURLRequest alloc]init]autorelease];  
    [request setURL:url];   
    [request setHTTPMethod:@"POST"];  
    [request  setValue:@"zh-cn" forHTTPHeaderField:@"Accept-Language"]; 
    [request  setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"]; 
    [request addValue: @"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; 
   // [request addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];//写这句而不是上面那句,就会出错 
     [request setHTTPBody:urlparms];   
    NSHTTPURLResponse *urlResponese = nil; 
    NSError *error = [[NSError alloc]init]; 
    NSData* data = [NSURLConnection sendSynchronousRequest:request   returningResponse:&urlResponese error:&error];  
    NSString* result= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    if([urlResponese statusCode] >=200&&[urlResponese statusCode]<300){ 
         
        return result; 
    } 
    return nil; 
    [error release]; 
    [result release]; 

 
 
//异步post请求,后面参数是nsdata类型,主要针对参数提交 
-(void)httpForYibuPOSTForData:(NSString *)urlstring addParms:(NSData *)urlparms{ 
    NSString *allurl = [NSString stringWithFormat:@"%@%@",baseurl,urlstring]; 
    NSString *allurl2= [allurl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
    NSURL *url = [NSURL URLWithString:allurl2];    
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15];   
    [theRequest  setValue:@"zh-cn" forHTTPHeaderField:@"Accept-Language"]; 
    [theRequest  setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"]; 
    [theRequest addValue: @"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; 
    [theRequest setHTTPMethod:@"POST"];  
    [theRequest  setValue:[NSString stringWithFormat:@"%d",PagingRows] forHTTPHeaderField:@"PagingRows"]; 
    [theRequest setHTTPBody:urlparms]; 
     
    if ([ValueUtils caseEquals:self.dialogcanshow to:@"true"]){ 
        [self showwaitalertview];//弹出等待对话筐 
    } 
     
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES]; 
     
    if(theConnection) { 
        webData = [[NSMutableData data] retain]; 
         
    } 
 

 
//异步post请求,主要针对分页查询 
-(void)httpForYibuPOSTPageparms:(NSString *)urlstring addParms:(NSData *)pageparms{ 
    //    if ([ValueUtils caseEquals:self.dialogcanshow to:@"true"]) { 
    //        [self showwaitalertview];//弹出等待对话筐 
    //    } 
     
    NSString *allurl = [NSString stringWithFormat:@"%@%@",baseurl,urlstring]; 
    NSString *allurl2= [allurl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
    NSURL *url = [NSURL URLWithString:allurl2];    
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15];   
    [theRequest  setValue:@"zh-cn" forHTTPHeaderField:@"Accept-Language"]; 
    [theRequest  setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"]; 
    [theRequest addValue: @"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; 
    [theRequest setHTTPMethod:@"POST"];  
    [theRequest  setValue:[NSString stringWithFormat:@"%d",PagingRows] forHTTPHeaderField:@"PagingRows"]; 
    [theRequest setHTTPBody:pageparms]; 
     
    if ([ValueUtils caseEquals:self.dialogcanshow to:@"true"]){ 
        [self showwaitalertview];//弹出等待对话筐 
    } 
     
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES]; 
     
     
    if(theConnection) { 
        webData = [[NSMutableData data] retain]; 
         
    } 

 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    [webData setLength:0]; 
//    if ([ValueUtils caseEquals:self.dialogcanshow to:@"true"]){ 
//        [self showwaitalertview];//弹出等待对话筐 
//    } 
     

 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [webData appendData:data]; 

 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    if (mt!=nil) { 
      [mt dismissWithClickedButtonIndex:1 animated:YES]; 
    } 
    [self performSelectorInBackground:@selector(showerroralertview) withObject:nil];  
    //[mt dismissWithClickedButtonIndex:1 animated:YES]; 

 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    if (mt!=nil) { 
        [mt dismissWithClickedButtonIndex:1 animated:YES]; 
    } 
    [connection release]; 
     
    NSString* result= [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding]; 
    [self.myhttputildelegate setServicereturnData:result];//为页面设值 
    [webData release]; 
    [result release]; 

//弹出error对话筐 
-(void)showerroralertview{ 
    UIAlertView *erroralert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"请求数据失败" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil]; 
    [erroralert show]; 
    [erroralert release]; 
     

 
//弹出等待对话筐 
-(void)showwaitalertview{ 
    mt = [[UIAlertView alloc]initWithTitle:nil message:@"正在加载......" delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil]; 
    [mt show]; 
    
 

 
 
 
@end 


iOS 网络请求框架比较

博文 来自: u010123208

ios 添加 http 请求

阅读数 331

没有更多推荐了,返回首页