博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对NSURLConnection的简单封装
阅读量:4081 次
发布时间:2019-05-25

本文共 4435 字,大约阅读时间需要 14 分钟。

#import <Foundation/Foundation.h>
@class YGFileDownloader;
@protocol YGFileDownloaderDelegate <NSObject>
-(void)fileDownloader:(YGFileDownloader *)downloader downloadSize:(unsigned long long)downloadSize totalSize:(unsigned long long)totalSize;
-(void)fileDownloaderDidFinishLoad;
-(void)fileDownloaderFailWithError:(NSError *)error;
@end
@interface YGFileDownloader : NSObject
@property (nonatomic,weak) id<YGFileDownloaderDelegate> delegate;
+(instancetype)sharedInstance;
-(void)start:(NSString *)urlStr;
-(void)stop;
@end

#import "YGFileDownloader.h"

#import "NSString+util.h"
@interface YGFileDownloader () <NSURLConnectionDataDelegate>
@property (nonatomic,strong) NSURLConnection *connection;
@property (nonatomic,copy) NSString *downloadDocPath;//这个路径标识我们下载的文件所存储的那个目录,他是写死的,每次下载东西都能放在目录下面
@property (nonatomic,strong) NSFileHandle *fileHandle;
@property (nonatomic) unsigned long long downloadFileSize;//当前下载了多少(字节)
@property (nonatomic) unsigned long long totalFileSize;//文件总大小
@end
@implementation YGFileDownloader
-(NSString *)downloadDocPath{
    if (_downloadDocPath==nil) {
        //找到沙盒的Document目录
        NSString *documentPath=[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        //上面这句代码和 [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"];一样
        NSString *downloadPath=[documentPath stringByAppendingPathComponent:@"YGFileDownload"];
        BOOL isSuccess=[[NSFileManager defaultManager] createDirectoryAtPath:downloadPath withIntermediateDirectories:YES attributes:nil error:nil];
        if (isSuccess) {
            NSLog(@"创建文件夹成功");
        }
        _downloadDocPath=downloadPath;
    }
    return _downloadDocPath;
}
+(instancetype)sharedInstance{//创建单例对象
    static YGFileDownloader *downloader=nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{//大括号里的代码只会执行一次
        downloader=[[YGFileDownloader alloc] init];
    });
    return downloader;
}
-(void)start:(NSString *)urlStr{
    NSString *fullPath=[self prepareStart:urlStr];
    //获取fullPath标识的文件的大小
    _downloadFileSize=[self readDownloadFileSize:fullPath];
    
    NSMutableURLRequest *request=[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlStr]];
    [request addValue:[NSString stringWithFormat:@"bytes=%llu-",_downloadFileSize] forHTTPHeaderField:@"Range"];//告诉服务器请求_downloadFileSize以后的字节
    self.connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
    
}
-(NSString *)prepareStart:(NSString *)urlStr{//确保urlStr所对应的沙盒的位置上有文件
    NSString *fileName=urlStr.md5;//把url所对应的MD5值作为文件名
    
    //fullPath代表这个文件具体的位置(路径)
    NSString *fullPath=[self.downloadDocPath stringByAppendingString:fileName];
    
    //如果指定的这个路径下面不存在这个文件,我们就把他创建出来
    BOOL fileExists=[[NSFileManager defaultManager] fileExistsAtPath:fullPath];
    if (!fileExists) {
        [[NSFileManager defaultManager] createFileAtPath:fullPath contents:nil attributes:nil];
    }
    
    //打开这个文件准备往里面写数据
    self.fileHandle=[NSFileHandle fileHandleForWritingAtPath:fullPath];
    
    return fullPath;
    //这个函数的功能是在准备下载文件之前做一些准备工作:1.确保文件存在,2.打开文件准备往里面写数据,3.获取这个文件的确切路径,因为我们在往这个路径所标识的这个文件中写数据(我们下载的数据)
}
-(unsigned long long)readDownloadFileSize:(NSString *)filePath{//读取filePath文件的文件大小
    NSDictionary *fileInfo=[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
    return [fileInfo fileSize];
}
-(void)stop{
    [_connection cancel],_connection=nil;
    [_fileHandle closeFile],_fileHandle=nil;
}
#pragma mark - <NSURLConnectionDataDelegate>
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    _totalFileSize=_downloadFileSize+response.expectedContentLength;
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    if ([self.delegate conformsToProtocol:@protocol(YGFileDownloaderDelegate)]&&[self.delegate respondsToSelector:@selector(fileDownloaderFailWithError:)]) {
        [self.delegate fileDownloaderFailWithError:error];
    }
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
    if ([self.delegate respondsToSelector:@selector(fileDownloaderDidFinishLoad)]) {
        [self.delegate fileDownloaderDidFinishLoad];
    }
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [_fileHandle seekToEndOfFile];//设置在末尾追加数据
    [_fileHandle writeData:data];//写入数据
    _downloadFileSize += data.length;
    if ([self.delegate conformsToProtocol:@protocol(YGFileDownloaderDelegate)] && [self.delegate respondsToSelector:@selector(fileDownloader:downloadSize:totalSize:)]) {
        [self.delegate fileDownloader:self downloadSize:_downloadFileSize totalSize:_totalFileSize];
    }
}
@end

转载地址:http://jjsni.baihongyu.com/

你可能感兴趣的文章
大数据入门:Scala函数式编程
查看>>
【数据结构周周练】002顺序表与链表
查看>>
C++报错:C4700:使用了非初始化的局部变量
查看>>
【数据结构周周练】003顺序栈与链栈
查看>>
C++类、结构体、函数、变量等命名规则详解
查看>>
C++ goto语句详解
查看>>
【数据结构周周练】008 二叉树的链式创建及测试
查看>>
《软件体系结构》 第九章 软件体系结构评估
查看>>
《软件体系结构》 第十章 软件产品线体系结构
查看>>
《软件过程管理》 第六章 软件过程的项目管理
查看>>
《软件过程管理》 第九章 软件过程的评估和改进
查看>>
分治法 动态规划法 贪心法 回溯法 小结
查看>>
《软件体系结构》 练习题
查看>>
《数据库系统概论》 第一章 绪论
查看>>
《数据库系统概论》 第二章 关系数据库
查看>>
《数据库系统概论》 第三章 关系数据库标准语言SQL
查看>>
SQL语句(二)查询语句
查看>>
SQL语句(六) 自主存取控制
查看>>
《计算机网络》第五章 运输层 ——TCP和UDP 可靠传输原理 TCP流量控制 拥塞控制 连接管理
查看>>
堆排序完整版,含注释
查看>>