做HTTP数据请求的方式有很多,网上有很多的第三方库可以很简单的实现此功能(ASIHTTPRequest, AsyncSocket ... ...)。
其实HTTP请求使用Apple的SDK就很容易实现了:NSURLConnect。
使用NSURLConnect做数据请求,首先要了解
1. NSURL,统一资源定位符对象
使用 + (id)URLWithString:(NSString *)URLString; 创建网络资源的URL。
注意此方法和+ (id)fileURLWithPath:(NSString *)path;(创建本地文件的URL)是不可以互相替换的。
2. NSURLRequest/NSMutableURLRequest
NSURLRequest和NSMutableURLRequest的区别和 NSArray和NSMutableArray类似,在这里就不多说了。
在此对象中完成HTTP请求的相关配置;
例如:
NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:url];
// 开始配置
// 设置缓存策略(可以不配置)
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
NSURLRequestUseProtocolCachePolicy = 0 NSURLRequest默认的cache policy,使用Protocol协议定义。是最能保持一致性的协议;
NSURLRequestReloadIgnoringCacheData = 1 忽略缓存直接从原始地址下载 = NSURLRequestReloadIgnoringCacheData;
NSURLRequestReturnCacheDataElseLoad = 2 只有在cache中不存在data时才从原始地址下载;
NSURLRequestReturnCacheDataDontLoad = 3 只使用cache数据,如果不存在cache,请求失败;用于没有建立网络连接离线模式;
NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, 忽略本地和远程的缓存数据,直接从原始地址下载,与NSURLRequestReloadIgnoringCacheData类似;
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData
NSURLRequestReloadRevalidatingCacheData = 5 验证本地数据与远程数据是否相同,如果不同则下载远程数据,否则使用本地数据。
// 设置HTTP请求类型:"GET" “POST" "PUT" "HEAD" "DELETE" "OPTION" "TRACE" ... ...
[request setHTTPMethod:@"POST"];
// 设置请求数据的头部参数,头部有很多可以配置的信息,可参考 http://wenku.baidu.com/link?url=M7FZFbf2lvsQvWMb0SaEz5YL66j8DvHwbO0m-SWIKWkOxzK2b8m7BeZbBWAsB-1oU-NABQvSmTgO3P1ip09BcQ_DgcrF9qy0gPG3p7jWqKu
// 设置请求数据的内容的类型 可参考 http://tool.oschina.net/commons
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// 设置HTTP请求的Body,这里测试的body为 @{@"param1":@"value1"} 的JSon字符串,
[request setHTTPBody:[bodydataUsingEncoding:NSUTF8StringEncoding]];
// 设置超时时间
[request setTimeoutInterval:self.timeOutSeconds];
3. NSURLConnect
给配置好的Request请求数据,创建NSURLConnect对象进行HTTP请求。
// 创建
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
// 请求
- (void)start NS_AVAILABLE(10_5, 2_0);
// 手动取消请求
- (void)cancel;
// 生产一个NSURLCOnnection对象,并开始链接
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
// 其他还有几个辅助的方法,可控制请求和回掉的处理线程。
// 下面是回掉方法
@protocol NSURLConnectionDelegate <NSObject>
// 请求失败
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
// 是否可以使用已经存储的凭证
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
// 给将要发送的请求提供认证信息时被调用,即使上面的方法返回NO,这个回掉方法也可能被调用
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
@end
@protocol NSURLConnectionDataDelegate <NSURLConnectionDelegate>
@optional
// 将要发送Request的时候的回掉
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response;
// 收到请求返回信息的回掉
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
// 收到请求返回的数据部分完成的回掉
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
// 这个是 NSInputStream 数据请求相关
- (NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request;
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
// 将要给返回信息缓存处理前的回掉
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse;
// 请求完成的回掉
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
@end
也可以使用下面两个静态方法进行请求,可以省很多代码,但是在过程控制上不如上面的方法(例如不能中途取消)。
// 简单的同步数据请求静态方法
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
// 简单的异步数据请求静态方法
// queue是指completionHandler的执行线程,如果想在新线程中执行completionHandler,传入[[[NSOperationQueue alloc] init] autorelease]即可,如果想在主线程([NSOperationQueue mainQueue]) 或者当前执行的线程([NSOperationQueue currentQueue]) 都可以,按需填写即可。
+ (void)sendAsynchronousRequest:(NSURLRequest*) request
queue:(NSOperationQueue*) queue
completionHandler:(void (^)(NSURLResponse* response,NSData* data, NSError* connectionError)) handlerNS_AVAILABLE(10_7, 5_0);
如果是HTTP请求, response = (NSHTTPURLResponse *)response,内有返回的头部信息等返回信息。