iOS NSURLSession 封装下载类

  周六日鼓捣NSURLSession,效率虽然低下,最后仍是有了一点点眉目。昨天和汤老师一块儿测试,又对它加深了一点理解。趁热打铁,先总结一下。数据库

 

  封装的类,对外用的方法,我写的是类方法,因此,在类方法中,就不能调用自己的@property变量了。解决办法是:将自己的类先定义为单例,在利用单例将自己的属性方法调用出来。session

  0.准备工做ide

  工具类必须先遵照DownloadDelegate,同时创建一个session的属性方法工具

@property(nonatomic, strong)NSURLSession * downloadSession;

  1.单例的构造方法:post

+(DownloadTool *)instance{   //DownloadTool是当前封装类的名字
    static DownloadTool * aInstance = nil;
    static dispatch_once_t  once_token;
    dispatch_once(&once_token, ^{
        aInstance = [[DownloadTool alloc]init];
        aInstance.downloadDic = [NSMutableDictionary dictionary]; //这个是自己的一个@property属性变量,放在这个里面进行初始化
    });
    return aInstance;
}

  单例构造完成,在类方法里面,咱们就可使用单例来调出属性变量。测试

  2.单一session的构造方法atom

/**
 *  建立session
 */
- (NSURLSession *)isDownloadSession{
    if (!_downloadSession) {
        NSString * configurationStr = @"DownloadTool";
        NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationStr];
        NSURLSession * downloadSession = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        _downloadSession = downloadSession; //_downloadSession是前面定义的属性方法
    }
    return _downloadSession;
}

  session用configuration来惟一标示,能够用identifier来惟一标识,和其余的不一样的session来区分,若是整个项目的session用的是同一个的话,能够用shareSession单例。代理设置为self,Queue,通常设置为主线程。url

  3.开始下载--这个能够定义类的调用方法里面,本身定义,同时将URL传入进来便可spa

    if ([[DownloadTool instance]isDownloadSession]) {
        NSURLSessionDownloadTask * downloadTask = [[DownloadTool instance].downloadSession downloadTaskWithURL:[NSURL URLWithString:url]];
        downloadTask.taskDescription = @"downloadTask01";
        [downloadTask resume];
    }

  3.1 先创建一个downloadTask,用惟一的session来启动,传入具体的URL。线程

  3.2 taskDescription,能够用来描述下载任务,这个属性是能够修改的,与taskIdentifier不一样,taskIdentifier是由系统返回是,通常用数字来标识,可用性不高,咱们能够把对下载任务的描述,惟一标识符等,放在taskDescription里面,到后面代理方法里面,能够根据downloadTask.taskDescription将这个值取出来

  3.3 resume:启动下载;必须调用这个方法,才会启动下载,不然不会。固然还有其余的方法,好比暂停、取消。

  4.实现代理方法 

  4.1 下载完成

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    //创建一个文件夹
    BOOL isDirectory;
    NSString * folderPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingString:@"/script"];
    BOOL isExistFolderPath = [[NSFileManager defaultManager]fileExistsAtPath:folderPath isDirectory:&isDirectory];
    
    if (!isExistFolderPath) {
        BOOL createFile = [[NSFileManager defaultManager]createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
        
        if (createFile) {
            NSLog(@"建立文件成功");
        }else{
            NSLog(@"建立文件失败");
        }
    }
    
    //改变位置
    NSString * sourcePath = location.path;
    NSString * lastComponent = scScript.url.lastPathComponent;
    NSString * destinationPath = [folderPath stringByAppendingPathComponent:lastComponent];
    [[NSFileManager defaultManager]moveItemAtPath:sourcePath toPath:destinationPath error:nil];
    
    //保存到数据库
    [[DownloadStoreManager sharedInstance]insertScript:scScript];
    
    //发送消息
    NSDictionary * dic = @{@"script":scScript};
    [[NSNotificationCenter defaultCenter]postNotificationName:DownloadNotificationName object:nil userInfo:dic];
    NSLog(@"下载成功------");
}

  这个是下载完成比较早的一个方法,后面还有一个方法。

  在这个方法里面,会将下载到的文件,暂时放置temp文件里面,若是咱们不处理,系统稍后会把这个文件给清除掉,因此,在这个里面,咱们的任务之一,就是把文件移动到目标文件夹里面去。若是目标文件不存在,咱们要建立一个文件夹。后面,有可能要存入到数据库里面,这个依业务来定。最后发送消息:DownloadNotificationName是我定义的消息的名称,这个能够依具体状况而定。

  3.2 数据下载完成的第二个方法

//下载完成
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error{
    
    if (error) {        
        NSDictionary * dic = @{@"error":@"下载失败"};
        [[NSNotificationCenter defaultCenter]postNotificationName:DownloadNotificationName object:nil userInfo:dic];
    }
    
}

  一开始,我被这个方法名字给误导了,觉得只有下载失败的时候才会调用这个方法,其实不是的,这个是在任务完成,无论是成功或者失败,都是要调用的一个方法。若是error为null,则说明下载成功,若是error有值,则下载失败,经过error这个值来判别。

 

当前NSURLSession里面,还有不少其余的方法,好比下载Data、upload上传,原理差很少。

今天先总结到这。昨天晚上太晚了,就没写总结,今天早上补上。

最近来接触新事物时,脑壳刚开始时,老是蒙蒙的,看来得多接受新事物才能调节啊!

相关文章
相关标签/搜索