美文网首页超棒文集iOS9开发技术iOS开发技术分享
[iOS]使用iOS8.0框架下URLSession对象实现断点

[iOS]使用iOS8.0框架下URLSession对象实现断点

作者: 郭晓敏啦 | 来源:发表于2015-09-17 20:19 被阅读996次

    VideoDownLoadManager.h

    //
    //  VideoDownLoadManager.h
    //  DowloadBreakPointDemo
    //
    //  Created by 郭晓敏 on 15/8/8.
    //  Copyright (c) 2015年 com.jiaoxuebu.gxm. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    @class VideoModel;
    
    @protocol VideoDownLoadManagerDelegate <NSObject>
    
    -(void)videoDidUpdatedProgressWithVideoModel:(VideoModel *)model;
    
    @end
    
    @interface VideoDownLoadManager : NSObject
    
    @property(nonatomic, weak)id<VideoDownLoadManagerDelegate>delegate;
    
    +(instancetype)sharedInstance;
    
    @property(nonatomic, strong)NSOperationQueue *downLoadQueue;
    
    //  用来保存创建的下载管理类,方面以后的对应管理
    @property(nonatomic, strong)NSMutableDictionary *httpOperationDict;
    
    @property(nonatomic, strong)NSMutableArray *downVideoArray;
    #pragma mark 开始下载
    -(void)startAVideoWithVideoModel:(VideoModel *)downLoadVideo;
    
    #pragma mark 暂停下载
    -(void)downloadPausewithModel:(VideoModel *)pauseModel;
    
    #pragma mark 断点继续下载
    -(void)downloadResumeWithModel:(VideoModel *)resumeModel;
    @end
    

    VideoDownLoadManager.m

    //
    //  VideoDownLoadManager.m
    //  DowloadBreakPointDemo
    //
    //  Created by 郭晓敏 on 15/8/8.
    //  Copyright (c) 2015年 com.jiaoxuebu.gxm. All rights reserved.
    //
    
    #import "VideoDownLoadManager.h"
    #import "VideoModel.h"
    #import "VideoDownLoadOperation.h"
    
    @interface VideoDownLoadOperation ()
    
    @end
    
    static VideoDownLoadManager *manager;
    @implementation VideoDownLoadManager
    +(instancetype)sharedInstance
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (manager == nil) {
                manager = [[VideoDownLoadManager alloc] init];
                manager.httpOperationDict = [NSMutableDictionary dictionary];
                manager.downVideoArray = [NSMutableArray array];
    
            }
        });
    
        return manager;
    }
    /*经过研究,AFN 的继续和暂停下载不是线程安全的,使用会经常出错*/
    #pragma mark 开始下载
    -(void)startAVideoWithVideoModel:(VideoModel *)downLoadVideo
    {
        NSLog(@"........%@", CachesPath);
        if (!self.downLoadQueue) {
            self.downLoadQueue = [[NSOperationQueue alloc] init];
            self.downLoadQueue.maxConcurrentOperationCount = 3;
        }
        VideoDownLoadOperation *ope = [[VideoDownLoadOperation alloc] initWithDownLoadVideoModel:downLoadVideo];
        ope.updateBlock = ^(VideoModel *model){
            if (self.delegate && [self.delegate respondsToSelector:@selector(videoDidUpdatedProgressWithVideoModel:)]) {
                [self.delegate videoDidUpdatedProgressWithVideoModel:model];
            }
        };
    
        [self.httpOperationDict setObject:ope forKey:downLoadVideo.flv];
        [self.downLoadQueue addOperation:ope];
        [self.downVideoArray addObject:downLoadVideo];
        [[NSNotificationCenter defaultCenter] postNotificationName:k_newVideoDidStartDown object:nil];
    }
    
    #pragma mark 暂停下载
    -(void)downloadPausewithModel:(VideoModel *)pauseModel
    {
    
        
        VideoDownLoadOperation *ope = [self.httpOperationDict objectForKey:pauseModel.flv];
        if (!ope.isFinished) {
            [ope downLoadPause];
        }
    
    }
    
    #pragma mark 断点继续下载
    -(void)downloadResumeWithModel:(VideoModel *)resumeModel
    {
        VideoDownLoadOperation *ope = [self.httpOperationDict objectForKey:resumeModel.flv];
        if (!ope.isFinished) {
            [ope downLoadResume];
        }
    }
    
    @end
    

    VideoDownLoadOperation.h

    //
    //  VideoDownLoadOperation.h
    //  DowloadBreakPointDemo
    //
    //  Created by 郭晓敏 on 15/8/9.
    //  Copyright (c) 2015年 com.jiaoxuebu.gxm. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    @class VideoModel;
    typedef void(^VIDEODidUpateBlcok)(VideoModel *);
    
    @interface VideoDownLoadOperation : NSOperation
    -(instancetype)initWithDownLoadVideoModel:(VideoModel *)videoModel;
    
    @property(nonatomic, copy)VIDEODidUpateBlcok updateBlock;
    // 暂停
    -(void)downLoadPause;
    // 恢复
    -(void)downLoadResume;
    @end
    

    VideoDownLoadOperation.m

    //
    //  VideoDownLoadOperation.m
    //  DowloadBreakPointDemo
    //
    //  Created by 郭晓敏 on 15/8/9.
    //  Copyright (c) 2015年 com.jiaoxuebu.gxm. All rights reserved.
    //
    
    #import "VideoDownLoadOperation.h"
    #import "VideoModel.h"
    @interface VideoDownLoadOperation ()<NSURLSessionDelegate,NSURLSessionDownloadDelegate>
    {
        // 用于判断一个任务是否正在下载
        BOOL _isDownLoading;
    
    }
    @property(nonatomic, strong)VideoModel *downLoadVideoModel;
    // 定义 session
    @property(nonatomic, strong)NSURLSession *currentSession;
    // 用于可恢复的下载任务的数据
    @property(nonatomic, strong)NSData *partialData;
    // 可恢复的下载任务
    @property(nonatomic, strong)NSURLSessionDownloadTask *task;
    @end
    
    @implementation VideoDownLoadOperation
    -(instancetype)initWithDownLoadVideoModel:(VideoModel *)videoModel
    {
        self = [super init];
        if (self) {
            self.downLoadVideoModel = videoModel;
        }
        return self;
    }
    
    -(void)main
    {
    
        NSURLSessionConfiguration *configure = [NSURLSessionConfiguration defaultSessionConfiguration];
    
        self.currentSession = [NSURLSession sessionWithConfiguration:configure delegate:self delegateQueue:nil];
        self.currentSession.sessionDescription = self.downLoadVideoModel.flv;
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.downLoadVideoModel.flv]];
        self.task = [self.currentSession downloadTaskWithRequest:request];
        [self.task resume];
        _isDownLoading = YES;
        while (_isDownLoading) {
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
        }
        self.partialData = nil;
    }
    // 暂停
    -(void)downLoadPause
    {
        NSLog(@"暂停");
        [self.task suspend];
    }
    // 恢复
    -(void)downLoadResume
    {
        NSLog(@"恢复下载");
        [self.task resume];
    }
    
    #pragma mark delegate(task)
    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
    {
    
        NSLog(@"path = %@", location.path);
        // 将临时文件剪切或者复制到 caches 文件夹
        NSFileManager *manager = [NSFileManager defaultManager];
    
        NSString *appendPath = [NSString stringWithFormat:@"/%@.mp4",self.downLoadVideoModel.title];
        NSString *file = [CachesPath stringByAppendingString:appendPath];
    
        [manager moveItemAtPath:location.path toPath:file error:nil];
        
        _isDownLoading = NO;
    
        // 下载完成发送通知
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:k_videoDidDownedFinishedSuccess object:self.downLoadVideoModel];
            self.downLoadVideoModel.isDownFinished = YES;
        });
    
    }
    
    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
    {
        NSLog(@"-----%f", bytesWritten  * 1.0 / totalBytesExpectedToWrite);
        self.downLoadVideoModel.progressValue = totalBytesWritten / (double)totalBytesExpectedToWrite;
        dispatch_async(dispatch_get_main_queue(), ^{
            if (self.updateBlock) {
                self.updateBlock(self.downLoadVideoModel);
            }
        });
        
    }
    
    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
    {
        NSLog(@"%.0f", fileOffset /(CGFloat) expectedTotalBytes);
    }
    
    @end
    

    相关文章

      网友评论

      • 奋斗中的Kevin:-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
        这个代理是在下载完成才可执行,也就是说下载完成才可以移动文件,这样程序杀死之后缓存会被清空么? 如果想要再程序开始执行下载就把他移动到自己的文件夹下 让用户进行删除或者断点下载的操作 用session该怎么实现 楼主会吗?
      • efd0507a0501:你好有DEMO吗?能给发一个吗?或者是github地址也行,2625217298@qq.com
      • TsingQue:VideoModel这个是用来做什么的?存储下载的东西么?不大科学啊
      • 257f312dccb8:你好 请问有demo吗? 能给我发一份吗? wb911025@163.com
      • 257f312dccb8:谢谢!

      本文标题:[iOS]使用iOS8.0框架下URLSession对象实现断点

      本文链接:https://www.haomeiwen.com/subject/iiybcttx.html