现在的位置: 首页 > 综合 > 正文

NSURLConnection小解

2017年02月26日 ⁄ 综合 ⁄ 共 4192字 ⁄ 字号 评论关闭

NSURLConnection提供对网络异步加载请求的支持,并且将获取的数据返回给代理。提供了简单的接口去创建和取消连接,同时使用delegate方法去支持连接过程的反馈和控制 。在实际开发中直接用的不多,但是有的第三方库却是用它来封装的。

举例一: 
1、先创建一个NSURL 
2、在通过NSURL创建NSURLRequest,可以指定缓存规则和超时时间 
3、创建NSURLConnection实例,指定NSURLRequest和一个delegate对象 
   如果创建失败,则会返回nil,如果创建成功则创建一个NSMutalbeData的实例用来存储数据 

代码: 
    NSURL *url = [NSURL URLWithString:@"http://192.168.2.128:9090/ssonew/login/UserLogin.action?name=mql&psd=123456"];
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
    self.theConncetion = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];
    
    if (_theConncetion) {
        self.receiveData = [[NSMutableData alloc]init];
    }

NSURLConnection有3个初始化函数,只有第一个初始化函数可以做到创建连接但是并 
不马上开始下载,而是通过start:开始,调用该初始化函数时,startImmediately传NO

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately NS_AVAILABLE(10_5, 2_0);
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;

当收到initWithRequest: delegate:或收到connectionWithRequest: delegate: 消息时,下载会立即开始,在代理(delegate) 
收到connectionDidFinishLoading:或者connection:didFailWithError:消息之前 
可以通过给连接发送一个cancel:消息来中断下载 

connection: willSendRequest: redirectResponse:这个方法在请求将要被发送出去之前会调用
返回值是一个NSURLRequest,就是那个真正将要被发送的请求

第二个参数request就是被重定向处理过后的请求
第三个参数response是触发重定向请求的响应包.默认是支持跳转的。
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{
    NSURLRequest *newRequest = request;
    if (response) {
        NSLog(@"redirect!!!");  //如,请求google的网站时会有跳转发生
        newRequest = nil;       //拒绝跳转
    }
    
    return newRequest;
}

当服务器提供了足够客户程序创建NSURLResponse对象的信息时,代理对象会收到 
一个connection:didReceiveResponse:消息,在消息内可以检查NSURLResponse 
对象和确定数据的预期长途,mime类型,文件名以及其他服务器提供的元信息 

要注意,一个简单的连接也可能会收到多个connection:didReceiveResponse:消息 
当服务器连接重置或者一些罕见的原因(比如多组mime文档),代理都会收到该消息 
这时候应该重置进度指示,丢弃之前接收的数据 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    //注意这里将NSURLResponse对象转换成NSHTTPURLResponse对象才能使用
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
    if ([response respondsToSelector:@selector(allHeaderFields)]) {
        NSDictionary *dictionary = [httpResponse allHeaderFields];
        NSLog(@"%@", dictionary);
    }

    [self.receiveData setLength:0];

}

当下载开始的时候,每当有数据接收,代理会定期收到connection:didReceiveData:消息 
代理应当在实现中储存新接收的数据,下面的例子既是如此 

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

 } 

在上面的方法实现中,可以加入一个进度指示器,提示用户下载进度 

当下载的过程中有错误发生的时候,代理会收到一个connection:didFailWithError消息 
消息参数里面的NSError对象提供了具体的错误细节,它也能提供在用户信息字典里面失败的 
url请求(使用NSErrorFailingURLStringKey) 

当代理接收到连接的connection:didFailWithError消息后,对于该连接不会再收到任何消息 

举例 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{

}

最后,如果连接请求成功的下载,代理会接收connectionDidFinishLoading:消息,代理不会收到其他的消息

举例: 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"总共请求的数据长度 = %d", [self.data length]);


注:从ios5.0开始,苹果为开发者引入block概念,所以使用NSURLConnection发送一个请求可以如下:
    NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
    NSOperationQueue *queue=[[NSOperationQueue alloc]init];
    
    [ NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        
        if (error == nil){
            
            NSLog(@"download success");
            NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
            NSString *str = [[NSString alloc]initWithData:data encoding:enc];
            NSLog(@"%@", str);
            
        }else if(error!=nil){
            
            NSLog(@"error");
            
        }

    }];


以上演示的请求都是GET请求,如果没使用NSMutableURLRequest的实例方法setHTTPMethod进行设置,请求都是GET请求。
如要走POST请求,仅需:
1、将上面的NSURLRequest替换成NSMutableURLRequest
2、[request setHTTPMethod:@“POST”];
3、[request setHTTPBody:postData];//postData一般是JSON格式的字符串转换过来的。

4、使用NSURLConnection启动请求。


有一个很好的Demo 可以去下载

http://code4app.com/ios/采用ARC-Blocks-GCD-封装的网络下载类库/5346c974933bf00b688b6663

抱歉!评论已关闭.