zoukankan      html  css  js  c++  java
  • iOS开发--网络下载

    这里使用的是NSURLConnection的代理请求下载,并且是具有进度,UI能实时刷新,至于NSURLConnection如何请求、并且有几种请求方法请看NSURLConnection请求简介,在这里的话我们以下载一本书籍为例,下面为它的地址(这是在百度云里面弄的,链接是别人加密了,所有比较长)

    http://d.pcs.baidu.com/file/2b66fa1c93d8322d5299a1befc59b16c?fid=204559171-250528-1042286675318370&time=1453435914&rt=sh&sign=FDTAERV-DCb740ccc5511e5e8fedcff06b081203-X%2Bcz8N4IQb25c4wIKAyYl1HHW2M%3D&expires=8h&chkv=1&chkbd=0&chkpc=&dp-logid=498837374116132296&dp-callid=0&r=107651804

    代码:

    1、首先在storyboard里面拖入一个Progress View(进度条)控件
    2、在控制器中拖入Progress View属性,并且另外添加三个属性,如下:
        @interface ViewController ()<NSURLConnectionDelegate>
        /** 进度条属性*/
        @property (weak, nonatomic) IBOutlet UIProgressView *progressView;
        /** 文件总大小 */
        @property (nonatomic, assign) NSUInteger totalLength;
        /** 文件当前大小 */
        @property (nonatomic, assign) NSUInteger currentLength;
        /** 文件路径 */
        @property (nonatomic, copy) NSString *path;
        @end
    
    3、确定它的URL,以及请求,并且设置它的代理,然后发送所谓的代理请求
        - (void)viewDidLoad {
            [super viewDidLoad];
            //1、确定URL
            NSURL *url = [NSURL URLWithString:@"http://d.pcs.baidu.com/file/2b66fa1c93d8322d5299a1befc59b16c?fid=204559171-250528-1042286675318370&time=1453435914&rt=sh&sign=FDTAERV-DCb740ccc5511e5e8fedcff06b081203-X%2Bcz8N4IQb25c4wIKAyYl1HHW2M%3D&expires=8h&chkv=1&chkbd=0&chkpc=&dp-logid=498837374116132296&dp-callid=0&r=107651804"];
            //2、创建请求对象
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            //3、代理请求
            /*
             第一个参数:请求对象
             第二个参数:谁成为代理
             第三个参数:startImmediately :是否立即开始发送网络请求
             */
            NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
            [connection start];
        }
    4、在这个Demo中,代理有两个方法是很重要的
        4.1、第一个就是刚开始响应的时候,在响应头中,我可以获取文件的预估大小和文件名后缀,用来创建文件夹和记录文件的总大小,用于后面的计算
        4.2、第二个就是每次接受到服务器数据的时候,我可以往某个文件写数据,以及计算每次占比例的多少
        //1.当接受到服务器响应的时候会调用:response(响应头)
        -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
        {
            NSLog(@"接受到响应");
            //1、在响应头中有一个预估的文件大小expectedContentLength
            self.totalLength = response.expectedContentLength;
            //这里你们可以打印看看   然后在网页的请求头也可以去对比一下,看是否为一样
            //    NSLog(@"totalLength = %lld", response.expectedContentLength);
            //2、这里的话为了让性能好一点,我直接在沙盒的Caches中创建一个文件夹直接写的硬盘上,而不是内存中
            //2.1、这里是地址为   在沙盒路径的Caches中  添加一个文件名为suggestedFilename的文件,suggestedFilename是响应头中的,也是百度云弄的名字你们也可以打印看看
            //    NSLog(@"%@",response.suggestedFilename);
            NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingString:response.suggestedFilename];
            //2.2、拿到地址那我们开始创建一个空得文件夹,并且路径给外面的path属性,用于后面拿到位置下载
            NSFileManager *manager = [NSFileManager defaultManager];
            [manager createFileAtPath:path contents:nil attributes:nil];
            self.path = path;
        }
        //2.当接受到服务器返回数据的时候调用(会调用多次)
        -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
        {
            // 1、创建一个操作文件的句柄,并且给予上次的创建文件夹的地址。
            NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.path];
            //设置写入方式,自上次后面写入
            [handle seekToEndOfFile];
            // 2、利用句柄往文件中写入数据
            [handle writeData:data];
            // 3、计算当前接收到得数据的总数  这里就是记录每一次写入数据的多少
            self.currentLength += data.length;
            // 4、计算下载比例
            self.progressView.progress = 1.0 * self.currentLength/self.totalLength;
        }
        //3.当请求失败的时候调用
        -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
        {
            NSLog(@"请求失败");
        }
        //4.当请求结束(成功|失败)的时候调用
        -(void)connectionDidFinishLoading:(NSURLConnection *)connection
        {
            NSLog(@"请求结束");
        }

    补充

    在这个Demo中唯一的优点就是节约了内存,因为每一次写都写到了硬盘中去,而不是内存中,现在你们可以打开你们自己的沙盒里面应该会有一个PDF的文件也就是刚刚下载的,这个Demo中最重要的方法为:

    //1.当接受到服务器响应的时候会调用:response(响应头)
    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
    }
     //2.当接受到服务器返回数据的时候调用(会调用多次)
    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
    }

    结束

  • 相关阅读:
    linux网络编程 inet_aton(); inet_aton; inet_addr;
    linux网络编程 ntohs, ntohl, htons,htonl inet_aton等详解
    linux C++ scandir 的使用
    linux 多线程编程-读写者问题
    为什么修改头文件make不重新编译
    syslog(),closelog()与openlog()--日志操作函数
    VC:CString用法整理(转载)
    VC6.0实用小技巧
    HTml js 生成图片
    C++中两个类相互包含引用问题
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/5349064.html
Copyright © 2011-2022 走看看