zoukankan      html  css  js  c++  java
  • iOS 下载功能:断点下载(暂停和开始)(NSURLConnectionDataDelegate方法)

    1,model文件代码

    文件名称:HMFileDownloader.h

    #import <Foundation/Foundation.h>

    @interface HMFileDownloader : NSObject

    /**

     * 所需要下载文件的远程URL(连接服务器的路径)

     */

    @property (nonatomic, copy) NSString *url;

    /**

     * 文件的存储路径(文件下载到什么地方)

     */

    @property (nonatomic, copy) NSString *destPath;

    /**

     * 是否正在下载(有没有在下载, 只有下载器内部才知道)

     */

    @property (nonatomic, readonly, getter = isDownloading) BOOL downloading;

    /**

     * 用来监听下载进度

     */

    @property (nonatomic, copy) void (^progressHandler)(double progress);

    /**

     * 用来监听下载完毕

     */

    @property (nonatomic, copy) void (^completionHandler)();

    /**

     * 用来监听下载失败

     */

    @property (nonatomic, copy) void (^failureHandler)(NSError *error);

    /**

     * 开始(恢复)下载

     */

    - (void)start;

    /**

     * 暂停下载

     */

    - (void)pause;

    @end

    文件名称:HMFileDownloader.m

    #import "HMFileDownloader.h"

    @interface HMFileDownloader() <NSURLConnectionDataDelegate>

    /**

     * 连接对象

     */

    @property (nonatomic, strong) NSURLConnection *conn;

    /**

     *  写数据的文件句柄

     */

    @property (nonatomic, strong) NSFileHandle *writeHandle;

    /**

     *  当前已下载数据的长度

     */

    @property (nonatomic, assign) long long currentLength;

    /**

     *  完整文件的总长度

     */

    @property (nonatomic, assign) long long totalLength;

    @end

    @implementation HMFileDownloader

    /**

     * 开始(恢复)下载

     */

    - (void)start

    {

        NSURL *url = [NSURL URLWithString:self.url];

        // 默认就是GET请求

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        // 设置请求头信息

        NSString *value = [NSString stringWithFormat:@"bytes=%lld-", self.currentLength];

        [request setValue:value forHTTPHeaderField:@"Range"];

        self.conn = [NSURLConnection connectionWithRequest:request delegate:self];

        

        _downloading = YES;

    }

    /**

     * 暂停下载

     */

    - (void)pause

    {

        [self.conn cancel];

        self.conn = nil;

        

        _downloading = NO;

    }

    #pragma mark - NSURLConnectionDataDelegate 代理方法

    /**

     *  1. 当接受到服务器的响应(连通了服务器)就会调用

     */

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

    {

    #warning 一定要判断

        if (self.totalLength) return;

        

        // 1.创建一个空的文件到沙盒中

        NSFileManager *mgr = [NSFileManager defaultManager];

        // 刚创建完毕的大小是0字节

        [mgr createFileAtPath:self.destPath contents:nil attributes:nil];

        

        // 2.创建写数据的文件句柄

        self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:self.destPath];

        

        // 3.获得完整文件的长度

        self.totalLength = response.expectedContentLength;

    }

    /**

     *  2. 当接受到服务器的数据就会调用(可能会被调用多次, 每次调用只会传递部分数据)

     */

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

    {

        // 累加长度

        self.currentLength += data.length;

        NSLog(@"=%lld==",self.currentLength);

        // 显示进度

        double progress = (double)self.currentLength / self.totalLength;

        if (self.progressHandler) { // 传递进度值给block

            self.progressHandler(progress);

        }

        

        // 移动到文件的尾部

        [self.writeHandle seekToEndOfFile];

        // 从当前移动的位置(文件尾部)开始写入数据

        [self.writeHandle writeData:data];

    }

    /**

     *  3. 当服务器的数据接受完毕后就会调用

     */

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection

    {

        // 清空属性值

        self.currentLength = 0;

        self.totalLength = 0;

        

        if (self.currentLength == self.totalLength) {

            // 关闭连接(不再输入数据到文件中)

            [self.writeHandle closeFile];

            self.writeHandle = nil;

        }

        

        if (self.completionHandler) {

            self.completionHandler();

        }

    }

    /**

     *  请求错误(失败)的时候调用(请求超时断网没有网, 一般指客户端错误)

     */

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

    {

        if (self.failureHandler) {

            self.failureHandler(error);

        }

    }

    @end

    2、将上述两个文件拖到工程中

    3、在控制器文件中导入

    #import "HMFileDownloader.h"

    声明

    @property (nonatomic, strong)NSString  *url;

    @property (retain, nonatomic)  UIProgressView *progressView;

    @property (nonatomic, strong) HMFileDownloader *fileDownloader;

    - (void)viewDidLoad

    {

     _progressView=[[UIProgressView alloc]init];

        _progressView.frame=CGRectMake(10, 150, 170, 20);

        

        [self.view addSubview:_progressView];

    [self fileDownloader];

    }

    - (void)fileDownloader

    {

        if (!_ViewCont.fileDownloader) {

            _fileDownloader = [[HMFileDownloader alloc] init];

            // 需要下载的文件远程URL

            _fileDownloader.url = @"http://192.168.1.9:8080/wyhouAppServices/upload/app_user/iOS%207%20Cookbook.pdf";

            // 文件保存到什么地方1

            NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

            NSString *filepath = [caches stringByAppendingPathComponent:@"20Cookbook.pdf"];

            

            

            // 文件保存到什么地方2

            NSURL *targetURL = [NSURL URLWithString:_ViewCont.fileDownloader.url];

            NSString *docPath = [self documentsDirectoryPath];

            // Combine the filename and the path to the documents dir into the full path

            NSString *pathToDownloadTo = [NSString stringWithFormat:@"%@/%@", docPath, [targetURL lastPathComponent]];

            

            

            

            _fileDownloader.destPath = pathToDownloadTo;

            //        typeof(10) a = 20; // int a = 20;

            

            __weak typeof(self) vc = self;

            _fileDownloader.progressHandler = ^(double progress) {

                vc.progressView.progress=progress;

    //            _progressView.progress = progress;

            };

            

            _fileDownloader.completionHandler = ^{

                NSLog(@"------下载完毕");

            };

            

            _fileDownloader.failureHandler = ^(NSError *error){

                

            };

        }else{

           _progressView.progress= _ViewCont.progressView.progress;

             __weak typeof(self) vc = self;

            _fileDownloader.progressHandler = ^(double progress) {

                vc.progressView.progress=progress;

                //

                

            

            };

        NSLog(@"------");

        

        }

    //    return _fileDownloader;

    }

    -(void)dealloc{

        _progressView.progress=_progressView.progress;

    }

    // 按钮文字: "开始", "暂停"

    - (void)start { // self.currentLength == 200

        if (_fileDownloader.isDownloading) { // 暂停下载

            [_fileDownloader pause];

            

            [_testBtn setTitle:@"恢复" forState:UIControlStateNormal];

        } else { // 开始下载

            [_fileDownloader start];

            

            [_testBtn setTitle:@"暂停" forState:UIControlStateNormal];

        }

    }

  • 相关阅读:
    在Salesforce中创建Approval Process
    用C#基于WCF创建TCP的Service供Client端调用
    用 C# 实现一个简单的 Rest Service 供外部调用
    在Salesforce中将 Decimal 数据转换成美元格式
    在Asp.Net MVC中PartialView与EditorFor和DisplayFor的区别
    在Salesforce中对某一个Object添加自定义的Button和Link
    【LeetCode】227. Basic Calculator II
    【LeetCode】226. Invert Binary Tree
    【LeetCode】225. Implement Stack using Queues
    【LeetCode】224. Basic Calculator
  • 原文地址:https://www.cnblogs.com/niexiaobo/p/4642558.html
Copyright © 2011-2022 走看看