• ios专题


    【罗国强原创】

    今天被刺激了,愤概地要写下这边博文。

    说到http异步下载,首先要知道其中的关键类。

    关键类是NSURLConnection  NSURLRequest NSMutableURLRequest

    委托是 NSURLConnectionDownloadDelegate NSURLConnectionDataDelegate NSURLConnectionDelegate

    首先,我们要实现最基本的下载功能。

    LQAsynDownload.h

    //
    //  LQAsynDownload.h
    //  lgTest
    //
    //  Created by yons on 14-2-14.
    //  Copyright (c) 2014年 GQ. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface LQAsynDownload : NSObject<NSURLConnectionDataDelegate>
    
    @property (strong) NSURL *httpURL;
    
    + (LQAsynDownload *) initWithURL:(NSURL *) url;
    
    - (void) startAsyn;
    
    @end

    LQAsynDownload.m

    //
    //  LQAsynDownload.m
    //  lgTest
    //
    //  Created by yons on 14-2-14.
    //  Copyright (c) 2014年 GQ. All rights reserved.
    //
    
    #import "LQAsynDownload.h"
    
    @interface LQAsynDownload()
    
    @property (assign) long long contentLength;
    
    @property (assign) long long receiveLength;
    
    @property (strong) NSMutableData *receiveData;
    
    @property (strong) NSString *fileName;
    
    @property (strong) NSURLConnection *theConnection;
    
    @property (strong) NSURLRequest *theRequest;
    
    @end
    
    @implementation LQAsynDownload
    
    @synthesize receiveData = _receiveData, fileName = _fileName,
                theConnection=_theConnection, theRequest=_theRequest;
    
    + (LQAsynDownload *) initWithURL:(NSURL *) url{
        LQAsynDownload *asynDownload = [[LQAsynDownload alloc] init];
        asynDownload.theRequest=[NSURLRequest requestWithURL:url
                  cachePolicy:NSURLRequestUseProtocolCachePolicy
                         timeoutInterval:60.0];
        // create the connection with the request
        // and start loading the data
        return asynDownload;
    }
    
    - (void) startAsyn{
        _contentLength=0;
        _receiveLength=0;
        self.receiveData = [[NSMutableData alloc] init];
        self.theConnection = [[NSURLConnection alloc] initWithRequest:self.theRequest delegate:self];
    }
    
    //接收到http响应
    - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
        _contentLength = [response expectedContentLength];
        _fileName = [response suggestedFilename];
        NSLog(@"data length is %lli", _contentLength);
    }
    
    //传输数据
    -(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        _receiveLength += data.length;
        [_receiveData appendData:data];
        NSLog(@"data recvive is %lli", _receiveLength);
    }
    
    //错误
    - (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
        [self releaseObjs];
        NSLog(@"%@",error.description);
    }
    
    - (void) releaseObjs{
        self.receiveData = nil;
        self.fileName = nil;
        self.theRequest = nil;
        self.theConnection = nil;
    }
    
    //成功下载完毕
    - (void) connectionDidFinishLoading:(NSURLConnection *)connection{
        //数据写入doument
        //获取完整目录名字
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *savePath = [NSString stringWithFormat:@"%@/%@",documentsDirectory, _fileName];
        //创建文件
        [_receiveData writeToFile:savePath atomically:YES];
        [self releaseObjs];
    }
    
    
    @end

    最简单的功能调用代码:

    LQAsynDownload *dwn = [LQAsynDownload initWithURL:[[NSURL alloc] initWithString:@"http://t2.baidu.com/it/u=0,3067863433&fm=19&gp=0.jpg"]];
    [dwn startAsyn];

    查查模拟器,神啊,MM靓图出现了

    情人节努力的补充礼物,哈哈。

     

    关键点分析:

    其实就是实现NSURLConnectionData委托的几个方法:

    这个方法是客户端接收到回应后的调用方法,算是下载的开始。

    - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

    跟着就是接收数据的方法

    -(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

    还有一个遇到错误时的处理方法

    - (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

    最后是下载成功调用的方法

    - (void) connectionDidFinishLoading:(NSURLConnection *)connection

    接着实现,下载进度查看。

    在原代码基础上增加2个block 属性。

    LQAsynDownload.h

     1 //
     2 //  LQAsynDownload.h
     3 //  lgTest
     4 //
     5 //  Created by yons on 14-2-14.
     6 //  Copyright (c) 2014年 GQ. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 typedef void (^initProgress)(long long initValue);
    12 
    13 typedef void (^loadedData)(long long loadedLength);
    14 
    15 @interface LQAsynDownload : NSObject<NSURLConnectionDataDelegate>
    16 
    17 @property (strong) NSURL *httpURL;
    18 
    19 @property (copy) void (^initProgress)(long long initValue);
    20 
    21 @property (copy) void (^loadedData)(long long loadedLength);
    22 
    23 + (LQAsynDownload *) initWithURL:(NSURL *) url;
    24 
    25 - (void) startAsyn;
    26 
    27 @end

    LQAsynDownload.m

     1 //
     2 //  LQAsynDownload.m
     3 //  lgTest
     4 //
     5 //  Created by yons on 14-2-14.
     6 //  Copyright (c) 2014年 GQ. All rights reserved.
     7 //
     8 
     9 #import "LQAsynDownload.h"
    10 
    11 @interface LQAsynDownload()
    12 
    13 @property (assign) long long contentLength;
    14 
    15 @property (assign) long long receiveLength;
    16 
    17 @property (strong) NSMutableData *receiveData;
    18 
    19 @property (strong) NSString *fileName;
    20 
    21 @property (strong) NSURLConnection *theConnection;
    22 
    23 @property (strong) NSURLRequest *theRequest;
    24 
    25 @end
    26 
    27 @implementation LQAsynDownload
    28 
    29 @synthesize receiveData = _receiveData, fileName = _fileName,
    30             theConnection=_theConnection, theRequest=_theRequest;
    31 
    32 + (LQAsynDownload *) initWithURL:(NSURL *) url{
    33     LQAsynDownload *asynDownload = [[LQAsynDownload alloc] init];
    34     asynDownload.theRequest=[NSURLRequest requestWithURL:url
    35               cachePolicy:NSURLRequestUseProtocolCachePolicy
    36                      timeoutInterval:60.0];
    37     // create the connection with the request
    38     // and start loading the data
    39     return asynDownload;
    40 }
    41 
    42 - (void) startAsyn{
    43     _contentLength=0;
    44     _receiveLength=0;
    45     self.receiveData = [[NSMutableData alloc] init];
    46     self.theConnection = [[NSURLConnection alloc] initWithRequest:self.theRequest delegate:self];
    47 }
    48 
    49 //接收到http响应
    50 - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    51     _contentLength = [response expectedContentLength];
    52     _fileName = [response suggestedFilename];
    53     if (self.initProgress != nil) {
    54         self.initProgress(_contentLength);
    55     }
    56     NSLog(@"data length is %lli", _contentLength);
    57 }
    58 
    59 //传输数据
    60 -(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    61     _receiveLength += data.length;
    62     [_receiveData appendData:data];
    63     if (self.loadedData != nil) {
    64         self.loadedData(data.length);
    65     }
    66     NSLog(@"data recvive is %lli", _receiveLength);
    67 }
    68 
    69 //错误
    70 - (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    71     [self releaseObjs];
    72     NSLog(@"%@",error.description);
    73 }
    74 
    75 - (void) releaseObjs{
    76     self.receiveData = nil;
    77     self.fileName = nil;
    78     self.theRequest = nil;
    79     self.theConnection = nil;
    80 }
    81 
    82 //成功下载完毕
    83 - (void) connectionDidFinishLoading:(NSURLConnection *)connection{
    84     //数据写入doument
    85     //获取完整目录名字
    86     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    87     NSString *documentsDirectory = [paths objectAtIndex:0];
    88     NSString *savePath = [NSString stringWithFormat:@"%@/%@",documentsDirectory, _fileName];
    89     //创建文件
    90     [_receiveData writeToFile:savePath atomically:YES];
    91     [self releaseObjs];
    92 }
    93 
    94 
    95 @end

    调用代码:

     1 LQAsynDownload *dwn = [LQAsynDownload initWithURL:[[NSURL alloc] initWithString:@"http://a.hiphotos.baidu.com/image/w%3D2048/sign=fae75ab5d63f8794d3ff4f2ee6230ff4/faedab64034f78f09f9423fe7b310a55b3191c1b.jpg"]];
     2     
     3     dwn.initProgress = ^(long long initValue){
     4         _sum = initValue;
     5         NSLog(@"%lli",initValue);
     6         _rcv = 0;
     7         dispatch_async(dispatch_get_main_queue(), ^{
     8             self.pv.progress = 0.0;
     9             self.pv.hidden = NO;
    10         });
    11     };
    12     
    13     dwn.loadedData = ^(long long loadedLength){
    14         dispatch_async(dispatch_get_main_queue(), ^{
    15             if (_rcv == _sum) {
    16                 self.pv.hidden = YES;
    17             } else {
    18                 _rcv += loadedLength;
    19                 self.pv.progress = _rcv/_sum;
    20             }
    21         });
    22     };
    23     
    24     [dwn startAsyn];

    真相:

    情人节第二个礼物:

    以前觉得很神奇的野,用心去试试,会觉得很简单,不是吗?

  • 相关阅读:
    Html5 Canvas一个简单的画笔例子
    DrawTool画笔之图形笔
    DrawTool画笔之纹理笔
    DrawTool多重笔之前奏 => 通过InkAnalyzer实现图形识别
    分布式系统阅读清单
    多点触摸画板(MultiTouchCanvas)
    基于 abp vNext 微服务开发的敏捷应用构建平台
    基于 abp vNext 微服务开发的敏捷应用构建平台
    基于 abp vNext 微服务开发的敏捷应用构建平台
    基于 abp vNext 微服务开发的敏捷应用构建平台
  • 原文地址:https://www.cnblogs.com/luoguoqiang1985/p/3550004.html
Copyright © 2020-2023  润新知