iOS 封装下载网络文件工具

版权声明:禁止转载、复制 https://blog.csdn.net/qq_37191821/article/details/84586305

一、首先封装一个下载工具类:

#import <UIKit/UIKit.h>

/** 下载回调信息,下载进度Block

 *  @param alreadySize   已接收大小

 *  @param contentLength 文件总大小

 */

typedef void(^ZJDownloaderProgressBlock)(CGFloat alreadySize,CGFloat contentLength);

/**下载回调信息,完成下载Block

 *  @param data     data

 *  @param error    错误信息

 */

typedef void(^ZJDownloaderCompletedBlock)(NSData *data,NSString *urlStr,NSError *error);

@interface ZJDownloader : NSObject

-(void)downloderWithUrlStr:(NSString *)urlStr ProgressBlock:(ZJDownloaderProgressBlock)progressBlock CompletedBlock:(ZJDownloaderCompletedBlock)completedBlock;

@end

#import "ZJDownloader.h"

@interface ZJDownloader()<NSURLSessionDataDelegate>

@property(strong,nonatomic) NSMutableData * data;

@property(strong,nonatomic) NSString * urlStr;

@property(assign,nonatomic) CGFloat  totalSize;

@property (copy, nonatomic) ZJDownloaderProgressBlock progressBlock;

@property (copy, nonatomic) ZJDownloaderCompletedBlock completedBlock;

@end

@implementation ZJDownloader

+(instancetype)share{

    static ZJDownloader * downloder;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        downloder = [[ZJDownloader alloc] init];

    });

    return downloder;

}

-(void)downloderWithUrlStr:(NSString *)urlStr ProgressBlock:(ZJDownloaderProgressBlock)progressBlock CompletedBlock:(ZJDownloaderCompletedBlock)completedBlock{

    [self setProgressBlock:progressBlock];

    [self setCompletedBlock:completedBlock];

    [self setUrlStr:urlStr];

    [self startDowloderWithUrlStr:urlStr];

    //NSLog(@" === 开始下载 === %@",urlStr);

}

#pragma mark -

-(void)startDowloderWithUrlStr:(NSString *)urlStr{

    NSURLSessionConfiguration *configura = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession *session = [NSURLSession sessionWithConfiguration:configura delegate:self delegateQueue:nil];

    NSURL * url = [NSURL URLWithString:urlStr];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:MAXFLOAT];

    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];

    [dataTask resume];

    [session finishTasksAndInvalidate];

}

#pragma mark - NSURLSessionDataDelegate

//最先调用,在这里做一些数据的初始化。

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{

    self.data = [[NSMutableData alloc] init];

    // 文件总大小

    long totalLength = response.expectedContentLength;

    [self setTotalSize:totalLength];

    completionHandler(NSURLSessionResponseAllow);

}

//下载响应

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask

    didReceiveData:(NSData *)data{

    [self.data appendData:data];

    // 已经下载的大小

    long length = self.data.length;

    if(self.progressBlock){

        self.progressBlock(length,self.totalSize);

    }

}

//下载完成后调用

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{

    if (!error) {

        if(self.completedBlock){

            self.completedBlock(self.data, self.urlStr, nil);

        }

    }else{

        if(self.completedBlock){

            self.completedBlock(nil,self.urlStr, error);

        }

    }

}

@end

二、对下载工具类二次封装:

#import <Foundation/Foundation.h>

#import "ZJDownloader.h"

@interface ZJDownloaderManager : NSObject

+(instancetype)share;

-(void)downloderWithUrlStr:(NSString *)urlStr ProgressBlock:(ZJDownloaderProgressBlock)progressBlock CompletedBlock:(ZJDownloaderCompletedBlock)completedBlock;

@end

#import "ZJDownloaderManager.h"

@interface ZJDownloaderManager()

@property(strong,nonatomic) dispatch_queue_t concurrentQueue;//  GCD队列

@property(nonatomic,strong) NSMutableDictionary * operations;//

@end

static ZJDownloaderManager * manager = nil;

@implementation ZJDownloaderManager

+(instancetype)share{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        manager = [[self alloc] init];

    });

    return manager;

}

-(dispatch_queue_t)concurrentQueue{

    if(_concurrentQueue==nil){

        /** 创建唯一表示为“downloderImageQueue”的并发队列

         *  DISPATCH_QUEUE_CONCURRENT 指定并发队列

         */

        _concurrentQueue = dispatch_queue_create("ZJDownloderQueue", DISPATCH_QUEUE_CONCURRENT);

    }

    return _concurrentQueue;

}

-(NSMutableDictionary *)operations{

    if(_operations==nil){

        _operations = [NSMutableDictionary dictionary];

    }

    return _operations;

}

-(void)downloderWithUrlStr:(NSString *)urlStr ProgressBlock:(ZJDownloaderProgressBlock)progressBlock CompletedBlock:(ZJDownloaderCompletedBlock)completedBlock{

    [self methodOneloderWithUrlStr:urlStr

                  ProgressBlock:progressBlock

                 CompletedBlock:completedBlock];

}

/** 同步并行

 */

-(void)methodThreeloderWithUrlStr:(NSString *)urlStr ProgressBlock:(ZJDownloaderProgressBlock)progressBlock CompletedBlock:(ZJDownloaderCompletedBlock)completedBlock{

    if([self.operations objectForKey:urlStr]){ return;}

    __weak typeof(self) weakSelf = self;

    dispatch_sync([self concurrentQueue], ^{ // 同步并行

        ZJDownloader * downloader = [ZJDownloader new];

        [downloader downloderWithUrlStr:urlStr ProgressBlock:^(CGFloat alreadySize, CGFloat contentLength) {

            dispatch_sync(dispatch_get_main_queue(), ^{

                progressBlock(alreadySize,contentLength);

            });

        } CompletedBlock:^(NSData *data, NSString *urlStr,  NSError *error) {

            dispatch_sync(dispatch_get_main_queue(), ^{

                completedBlock(data, urlStr, error);

                [weakSelf.operations removeObjectForKey:urlStr];

            });

        }];

        [weakSelf.operations setObject:downloader forKey:urlStr];

    });

}

/** 同步 dispatch_barrier_sync

 */

-(void)methodFourloderWithUrlStr:(NSString *)urlStr ProgressBlock:(ZJDownloaderProgressBlock)progressBlock CompletedBlock:(ZJDownloaderCompletedBlock)completedBlock{

    if([self.operations objectForKey:urlStr]){ return;}

    __weak typeof(self) weakSelf = self;

    dispatch_barrier_sync([self concurrentQueue], ^{

        ZJDownloader * downloader = [ZJDownloader new];

        [downloader downloderWithUrlStr:urlStr ProgressBlock:^(CGFloat alreadySize, CGFloat contentLength) {

            dispatch_async([self concurrentQueue], ^{

                dispatch_sync(dispatch_get_main_queue(), ^{

                    progressBlock(alreadySize,contentLength);

                });

            });

        } CompletedBlock:^(NSData *data, NSString *urlStr,  NSError *error) {

            dispatch_sync([self concurrentQueue], ^{

                dispatch_sync(dispatch_get_main_queue(), ^{

                    completedBlock(data, urlStr, error);

                    [weakSelf.operations removeObjectForKey:urlStr];

                });

            });

        }];

        [weakSelf.operations setObject:downloader forKey:urlStr];

    });

}

猜你喜欢

转载自blog.csdn.net/qq_37191821/article/details/84586305