IOS开发入门iOS开发-使用NSURLSession实现文件断点下载,文件离线续传以及图片上传
白羽 2019-05-21 来源 :网络 阅读 486 评论 0

摘要:本文将带你了解IOS开发入门iOS开发-使用NSURLSession实现文件断点下载,文件离线续传以及图片上传,希望本文对大家学IOS有所帮助。

    本文将带你了解IOS开发入门iOS开发-使用NSURLSession实现文件断点下载,文件离线续传以及图片上传,希望本文对大家学IOS有所帮助。


IOS开发入门iOS开发-使用NSURLSession实现文件断点下载,文件离线续传以及图片上传


NSURLSession
   NSURLSession是iOS9.0后苹果推出的网络请求框架,用来代替NSURLConnecttion。使用方法和NSURLConnecttion类似。
   NSURLSession使用方法
   NSURLSession使用简单,只需使用NSURLSession对象创建Task,然后执行Task即可。NSURLSessionTask是抽象类,不能直接拿来使用,它有两个子类,
   NSURLSessionDataTask:用来发起网络请求
   -NSURLSessionDataTask的子类,NSURLSessionUploadTask:用来执行上传任务
   NSURLSessionDownloadTask:用来执行下载任务
   NSURLSession使用范例
   1 GET请求:
  -(void)get{    //1.确定URL    NSURL  *url = [NSURL  URLWithString:@"公司接口"];     //2.创建请求对象    //NSURLRequest  *request =[NSURLRequest  requestWithURL:url];     //3.创建会话对象    NSURLSession  *session = [NSURLSession  sharedSession];     //4.创建Task    /*     第一个参数:请求路径     第二个参数:completionHandler  当请求完成之后调用     data:响应体信息     response:响应头信息     error:错误信息当请求失败的时候  error有值     注意:dataTaskWithURL  内部会自动的将请求路径作为参数创建一个请求对象(GET)     */    NSURLSessionDataTask  *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *  _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable  error)  {         //6.解析数据        NSLog(@"%@",[[NSString  alloc]initWithData:data  encoding:NSUTF8StringEncoding]);    }];     //5.执行Task    [dataTask  resume];}
   2 POST请求:
   -(void)post{    //1.确定URL    NSURL  *url = [NSURL  URLWithString:@"公司接口"];     //2.创建请求对象    NSMutableURLRequest  *request =[NSMutableURLRequest  requestWithURL:url];     //2.1  设置请求方法为post    request.HTTPMethod =  @"POST";     //2.2  设置请求体,POST请求的参数都在这个请求体里,这里只是范例,具体看公司接口文档。    request.HTTPBody  = [@"username=Cehae&pwd=Cehae&type=JSON"  dataUsingEncoding:NSUTF8StringEncoding];     //3.创建会话对象    NSURLSession  *session = [NSURLSession sharedSession];     //4.创建Task    /*     第一个参数:请求对象     第二个参数:completionHandler  当请求完成之后调用 !!!  在子线程中调用     data:响应体信息     response:响应头信息     error:错误信息当请求失败的时候  error有值     */    NSURLSessionDataTask  *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *  _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable  error)  {         NSLog(@"%@",[NSThread  currentThread]);//注意这里是子线程,请求玩数据需要刷新UI请回到主线程操作        //6.解析数据        NSLog(@"%@",[[NSString  alloc]initWithData:data  encoding:NSUTF8StringEncoding]);    }];     //5.执行Task    [dataTask  resume];}
   3 NSURLSession的代理方法:
  @interface  ViewController ()/** 接受响应体信息 */@property  (nonatomic, strong) NSMutableData *fileData;@end @implementation  ViewController -(NSMutableData *)fileData{    if  (_fileData == nil) {        _fileData  = [NSMutableData  data];    }    return  _fileData;}-(void)touchesBegan:(NSSet*)touches  withEvent:(UIEvent  *)event{    //1.url    NSURL *url =  [NSURL URLWithString:@"公司接口"];     //2.创建请求对象    NSURLRequest  *request = [NSURLRequest  requestWithURL:url];     //3.创建会话对象,设置代理    /*     第一个参数:配置信息  [NSURLSessionConfiguration  defaultSessionConfiguration]     第二个参数:代理     第三个参数:设置代理方法在哪个线程中调用     */    NSURLSession  *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration  defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue  mainQueue]];     //4.创建Task    NSURLSessionDataTask  *dataTask = [session dataTaskWithRequest:request];     //5.执行Task    [dataTask  resume];} #pragma mark ----------------------#pragma mark  NSURLSessionDataDelegate/** *  1.注意:当接收到服务器的响应  它默认会取消该请求,需要我们回调任务类型 * *  @param  session            会话对象 *  @param  dataTask           请求任务 *  @param  response          响应头信息 *   @param completionHandler 回调 传给系统 */-(void)URLSession:(NSURLSession  *)session dataTask:(NSURLSessionDataTask *)dataTask  didReceiveResponse:(NSURLResponse *)response completionHandler:(void  (^)(NSURLSessionResponseDisposition))completionHandler{    NSLog(@"%s",__func__);     /*     NSURLSessionResponseCancel  = 0,取消请求 默认     NSURLSessionResponseAllow = 1,  接收数据     NSURLSessionResponseBecomeDownload = 2,  变成下载任务     NSURLSessionResponseBecomeStream         变成流     */     //回调任务类型,默认是取消请求    completionHandler(NSURLSessionResponseAllow);} /** *   接收到服务器返回的数据 就会调用该方法,可以调用多次 * *  @param  session            会话对象 *  @param dataTask           请求任务 *  @param  data               本次下载的数据 */-(void)URLSession:(NSURLSession *)session  dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData  *)data{     NSLog(@"%s",__func__);     //拼接数据    [self.fileData  appendData:data];} /** *  请求结束或者是失败的时候调用 * *   @param session            会话对象 *  @param  dataTask           请求任务 *  @param  error              错误信息 */-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask  *)task didCompleteWithError:(NSError  *)error{     NSLog(@"%s",__func__);     //解析数据    NSLog(@"%@",[[NSString  alloc]initWithData:self.fileData  encoding:NSUTF8StringEncoding]); }
   4 NSURLSession和文件句柄实现断点下载
  #import  "ViewController.h"#define FileName  @"123.mp4" @interface ViewController  ()@property (weak, nonatomic) IBOutlet  UIProgressView *proessView;/** 接受响应体信息 */@property (nonatomic, strong)  NSFileHandle *handle;@property (nonatomic, assign) NSInteger  totalSize;@property (nonatomic, assign) NSInteger currentSize;@property  (nonatomic, strong) NSString *fullPath;@property (nonatomic, strong)   NSURLSessionDataTask *dataTask;@property (nonatomic, strong) NSURLSession  *session; @end @implementation  ViewController -(void)viewDidLoad{    [super  viewDidLoad];     //1.读取保存的文件总大小的数据,0    //2.获得当前已经下载的数据的大小    //3.计算得到进度信息 }-(NSString  *)fullPath{    if (_fullPath == nil)  {         //获得文件全路径        _fullPath  = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,  YES) lastObject]  stringByAppendingPathComponent:FileName];    }    return  _fullPath;} -(NSURLSession *)session{    if  (_session == nil)  {        //3.创建会话对象,设置代理        /*         第一个参数:配置信息  [NSURLSessionConfiguration  defaultSessionConfiguration]         第二个参数:代理         第三个参数:设置代理方法在哪个线程中调用         */        _session  = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration  defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue  mainQueue]];    }    return  _session;}-(NSURLSessionDataTask *)dataTask{    if  (_dataTask == nil)  {        //1.url   小视频url        NSURL *url = [NSURL  URLWithString:@"https://120.25.226.186:32812/resources/videos/minion_01.mp4"];         //2.创建请求对象        NSMutableURLRequest  *request = [NSMutableURLRequest  requestWithURL:url];         //3  设置请求头信息,告诉服务器请求那一部分数据        self.currentSize  = [self getFileSize];        NSString  *range = [NSString  stringWithFormat:@"bytes=%zd-",self.currentSize];        [request  setValue:range  forHTTPHeaderField:@"Range"];         //4.创建Task        _dataTask  = [self.session  dataTaskWithRequest:request];    }    return  _dataTask;} -(NSInteger)getFileSize{    //获得指定文件路径对应文件的数据大小    NSDictionary  *fileInfoDict = [[NSFileManager  defaultManager]attributesOfItemAtPath:self.fullPath  error:nil];    NSLog(@"%@",fileInfoDict);    NSInteger  currentSize = [fileInfoDict[@"NSFileSize"]  integerValue];     return currentSize;}-  (IBAction)startBtnClick:(id)sender{    [self.dataTask  resume];} -  (IBAction)suspendBtnClick:(id)sender{    NSLog(@"_________________________suspend");    [self.dataTask  suspend];} //注意:dataTask的取消是不可以恢复的-  (IBAction)cancelBtnClick:(id)sender{      NSLog(@"_________________________cancel");    [self.dataTask  cancel];    self.dataTask = nil;} -  (IBAction)goOnBtnClick:(id)sender{      NSLog(@"_________________________resume");    [self.dataTask  resume];} #pragma mark ----------------------#pragma mark  NSURLSessionDataDelegate/** *  1.接收到服务器的响应  它默认会取消该请求 * *  @param  session            会话对象 *  @param dataTask           请求任务 *  @param  response           响应头信息 *  @param completionHandler 回调  传给系统 */-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask  *)dataTask didReceiveResponse:(NSURLResponse *)response  completionHandler:(void  (^)(NSURLSessionResponseDisposition))completionHandler{    //获得文件的总大小    //expectedContentLength  本次请求的数据大小    self.totalSize =  response.expectedContentLength +  self.currentSize;     if (self.currentSize == 0)  {        //创建空的文件        [[NSFileManager  defaultManager]createFileAtPath:self.fullPath contents:nil  attributes:nil];     }    //创建文件句柄    self.handle  = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];     //移动指针    [self.handle  seekToEndOfFile];     /*     NSURLSessionResponseCancel  = 0,取消 默认     NSURLSessionResponseAllow = 1,  接收     NSURLSessionResponseBecomeDownload = 2,  变成下载任务     NSURLSessionResponseBecomeStream         变成流     */    completionHandler(NSURLSessionResponseAllow);} /** *   接收到服务器返回的数据 调用多次 * *  @param  session            会话对象 *  @param  dataTask          请求任务 *   @param  data               本次下载的数据 */-(void)URLSession:(NSURLSession *)session  dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData  *)data{     //写入数据到文件    [self.handle  writeData:data];     //计算文件的下载进度    self.currentSize  += data.length;    NSLog(@"%f",1.0 *  self.currentSize / self.totalSize);     self.proessView.progress  = 1.0 * self.currentSize / self.totalSize;} /** *   请求结束或者是失败的时候调用 * *  @param  session            会话对象 *  @param  dataTask           请求任务 *  @param  error              错误信息 */-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask  *)task didCompleteWithError:(NSError  *)error{    NSLog(@"%@",self.fullPath);     //关闭文件句柄    [self.handle  closeFile];    self.handle = nil;} -(void)dealloc{    //清理工作    //finishTasksAndInvalidate    [self.session  invalidateAndCancel];}
   4 NSURLSession实现文件上传
  #import  "ViewController.h"//                   ----WebKitFormBoundaryvMI3CAV0sGUtL8tr#define Kboundary  @"----WebKitFormBoundaryjv0UfA04ED44AhWx" #define KNewLine  [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding] @interface  ViewController ()/** 注释 */@property  (nonatomic, strong) NSURLSession *session;@end @implementation  ViewController -(NSURLSession *)session{    if  (_session == nil)  {        NSURLSessionConfiguration  *config = [NSURLSessionConfiguration defaultSessionConfiguration];         //是否运行蜂窝访问        config.allowsCellularAccess  =  YES;        config.timeoutIntervalForRequest  = 15;         _session =  [NSURLSession sessionWithConfiguration:config delegate:self  delegateQueue:[NSOperationQueue  mainQueue]];    }    return  _session;} -(void)touchesBegan:(NSSet*)touches  withEvent:(UIEvent *)event{    [self  upload2];} -(void)upload{    //1.url    NSURL  *url = [NSURL URLWithString:@"https://120.25.226.186:32812/upload"];     //2.创建请求对象    NSMutableURLRequest  *request = [NSMutableURLRequest  requestWithURL:url];     //2.1  设置请求方法    request.HTTPMethod = @"POST";     //2.2  设请求头信息    [request setValue:[NSString  stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary]  forHTTPHeaderField:@"Content-Type"];     //3.创建会话对象//     NSURLSession *session = [NSURLSession  sharedSession];     //4.创建上传TASK    /*     第一个参数:请求对象     第二个参数:传递是要上传的数据(请求体)     第三个参数:     */   NSURLSessionUploadTask  *uploadTask = [self.session uploadTaskWithRequest:request fromData:[self  getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse *  _Nullable response, NSError * _Nullable error)  {        //6.解析       NSLog(@"%@",[[NSString  alloc]initWithData:data  encoding:NSUTF8StringEncoding]);    }];     //5.执行Task    [uploadTask  resume];} -(void)upload2{    //1.url    NSURL  *url = [NSURL  URLWithString:@"https://120.25.226.186:32812/upload"];     //2.创建请求对象    NSMutableURLRequest  *request = [NSMutableURLRequest  requestWithURL:url];     //2.1  设置请求方法    request.HTTPMethod =  @"POST";     //2.2  设请求头信息    [request setValue:[NSString  stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary]  forHTTPHeaderField:@"Content-Type"];     //3.创建会话对象     //4.创建上传TASK    /*     第一个参数:请求对象     第二个参数:传递是要上传的数据(请求体)     */    NSURLSessionUploadTask  *uploadTask = [self.session uploadTaskWithRequest:request fromData:[self  getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse *  _Nullable response, NSError * _Nullable error)  {         //6.解析        NSLog(@"%@",[[NSString  alloc]initWithData:data  encoding:NSUTF8StringEncoding]);    }];     //5.执行Task    [uploadTask  resume];}//里面大多数是固定写法,需要改的地方看我的注释就好了-(NSData  *)getBodyData{    NSMutableData *fileData =  [NSMutableData data];    //5.1  文件参数    /*     --分隔符     Content-Disposition:  form-data; name="file";  filename="Snip20160225_341.png"     Content-Type:  image/png(MIMEType:大类型/小类型)     空行     文件参数     */    [fileData  appendData:[[NSString stringWithFormat:@"--%@",Kboundary]  dataUsingEncoding:NSUTF8StringEncoding]];    [fileData  appendData:KNewLine];     //name:file  服务器规定的参数    //filename:Snip20160225_341.png  文件保存到服务器上面的名称    //Content-Type:文件的类型    [fileData  appendData:[@"Content-Disposition: form-data; name=\"file\";  filename=\"Sss.png\"" dataUsingEncoding:NSUTF8StringEncoding]];    [fileData  appendData:KNewLine];    [fileData  appendData:[@"Content-Type: image/png"  dataUsingEncoding:NSUTF8StringEncoding]];    [fileData  appendData:KNewLine];    [fileData  appendData:KNewLine];     UIImage *image = [UIImage  imageNamed:@"Snip20160226_90"];    //UIImage  --->NSData    NSData *imageData = UIImagePNGRepresentation(image);    [fileData  appendData:imageData];    [fileData  appendData:KNewLine];     //5.2  非文件参数    /*     --分隔符     Content-Disposition:  form-data;  name="username"     空行     123456     */    [fileData  appendData:[[NSString stringWithFormat:@"--%@",Kboundary]  dataUsingEncoding:NSUTF8StringEncoding]];    [fileData  appendData:KNewLine];    [fileData  appendData:[@"Content-Disposition: form-data;  name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];    [fileData  appendData:KNewLine];    [fileData  appendData:KNewLine];    [fileData  appendData:[@"123456"  dataUsingEncoding:NSUTF8StringEncoding]];    [fileData  appendData:KNewLine];     //5.3  结尾标识    /*     --分隔符--     */    [fileData  appendData:[[NSString stringWithFormat:@"--%@--",Kboundary]  dataUsingEncoding:NSUTF8StringEncoding]];    return  fileData;} #pragma mark ----------------------#pragma mark  NSURLSessionDataDelegate// 使用代理方法来监听上传进度/* *  @param  bytesSent                 本次发送的数据 *  @param  totalBytesSent            上传完成的数据大小 *  @param totalBytesExpectedToSend  文件的总大小 */-(void)URLSession:(NSURLSession *)session  task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent  totalBytesSent:(int64_t)totalBytesSent  totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{    NSLog(@"%f",1.0  *totalBytesSent /  totalBytesExpectedToSend);}  


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程