好久没写,写点新东西
网络这块可以说是一个app核心的东西,重点照顾。
基本组成:
1.NSURL (不解释)
2.NSURLRequest (多用NSMutableURLRequest,因为可以设置属性)
3.NSURLConnection (创建链接)
4.NSHTTPURLResponse (响应)
5.NSError (错误信息)
先上简单的吧
第一种方式:同步加载
NSURL *url = [NSURL URLWithString:urlstr];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]init];
[req setURL:url];
[req setHTTPMethod:@"GET"];
[req setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[req addValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
NSHTTPURLResponse *response;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
if (response.statusCode != 200)
{
NSLog(@"错误");
return;
}
if (error) {
NSLog(@"%@",error.domain);
return;
}
//把data转换成dictionary
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",dic);
第二种方式:异步队列,感觉和第一种差不多用的也不多
NSURL *url = [NSURL URLWithString:urlstr];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]init];
[req setURL:url];
// NSLog(@"%@",req.URL);
[req setHTTPMethod:@"GET"];
[req setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[req addValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
NSHTTPURLResponse *response;
NSError *error = nil;
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//把data转换成dictionary
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",dic);
}];
现在来看第三种也是最常用的一种:异步代理模式。
首先要实现两个协议:NSURLConnectionDelegate和NSURLConnectionDataDelegate。
我们先看一下这两个协议里面的方法。
NSURLConnectionDelegate协议:
(void)connection:(NSURLConnection )connection didFailWithError:(NSError )error;
这个方法是报错方法,在连接出错的时候调用此方法,然后终止链接。
(BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
这个方法是是否启用证书存储功能的,暂时没用上。
以下几个方法都与认证和挑战有关,暂时没用上,先不管。
(void)connection:(NSURLConnection*)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge;
(void)connection:(NSURLConnection*)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
(void)connection:(NSURLConnection*)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
NSURLConnectionDataDelegate协议:
(NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(nullable NSURLResponse*)response;
这个方法是从定向方法,一般会在链接的时候第一个被调用,在这个方法里面可以修改链接。
(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response;
每个数据包中都会有response,所有这个方法会被重复调用多次,这个方法总是和didReceiveData方法成对出现。在此方法中可以做一些相关操作,比如验证响应数据,以及为随后而来的数据指定存储位置。
(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data;
总是在didReceiveResponse后面调用,在这个方法里面进行数据包数据部分的接收。
(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;
当数据接收完毕后调用该方法。
示例代码:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *url = [NSURL URLWithString:urlstr];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]init];
[req setURL:url];
[req setHTTPMethod:@"GET"];
[req setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[req addValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
[[NSURLConnection connectionWithRequest:req delegate:self] start];
}
//以下为代理方法的执行顺序
//这个方法会在链接出错的时候调用(多次调用)
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"error=%@",error.description);
}
//这个方法是在connection构建时调用的,不需要的话返回NO
-(BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
{ NSLog(@"connectionShouldUseCredentialStorage=%@",connection.description);
return YES;
}
//1.首先会调用这个方法,进行重定向。
-(NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{
NSLog(@"source=%@",urlstr);
NSLog(@"fistrequest=%@",request.description);
NSLog(@"fistreponse=%@",[(NSHTTPURLResponse *)response allHeaderFields]);
return request;
}
//2.在客户端接到响应调用这个方法。
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"response=%@",response.description);
UrlData = [[NSMutableData alloc] init];
}
//3.接收数据。(多次调用)
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[UrlData appendData:data];
}
//4.对每个response都可以在这个方法里面设置缓存策略。
-(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{ NSLog(@"cachedresponse=%@",cachedResponse.description);
return cachedResponse;
}
//5.数据接收完成后调用.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"Finish=%@",connection.description);
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:UrlData options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",dic);
}
iOS的三种基本形式,有时间了再补。