iOS网络编程(十)

作者: BEYOND黄 | 来源:发表于2017-06-01 21:35 被阅读55次

    NSURLSession

    使用步骤

    使用NSURLSession对象创建Task,然后执行Task

    -(void)get

    {

    //1.确定URL

    NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

    //2.创建请求对象

    NSURLRequest*request =[NSURLRequestrequestWithURL:url];

    //3.创建会话对象

    NSURLSession*session = [NSURLSessionsharedSession];

    //4.创建Task

    /*

    第一个参数:请求对象

    第二个参数:completionHandler当请求完成之后调用

    data:响应体信息

    response:响应头信息

    error:错误信息当请求失败的时候error有值

    */

    NSURLSessionDataTask*dataTask = [sessiondataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {

    //6.解析数据

    NSLog(@"%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);

    }];

    //5.执行Task

    [dataTaskresume];

    }

    -(void)get2

    {

    //1.确定URL

    NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

    //2.创建请求对象

    //NSURLRequest *request =[NSURLRequest requestWithURL:url];

    //3.创建会话对象

    NSURLSession*session = [NSURLSessionsharedSession];

    //4.创建Task

    /*

    第一个参数:请求路径

    第二个参数:completionHandler当请求完成之后调用

    data:响应体信息

    response:响应头信息

    error:错误信息当请求失败的时候error有值

    注意:dataTaskWithURL内部会自动的将请求路径作为参数创建一个请求对象(GET)

    */

    NSURLSessionDataTask*dataTask = [sessiondataTaskWithURL:urlcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {

    //6.解析数据

    NSLog(@"%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);

    }];

    //5.执行Task

    [dataTaskresume];

    }

    -(void)post

    {

    //1.确定URL

    NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login"];

    //2.创建请求对象

    NSMutableURLRequest*request =[NSMutableURLRequestrequestWithURL:url];

    //2.1设置请求方法为post

    request.HTTPMethod=@"POST";

    //2.2设置请求体

    request.HTTPBody= [@"username=520it&pwd=520it&type=JSON"dataUsingEncoding:NSUTF8StringEncoding];

    //3.创建会话对象

    NSURLSession*session = [NSURLSessionsharedSession];

    //4.创建Task

    /*

    第一个参数:请求对象

    第二个参数:completionHandler当请求完成之后调用!!!在子线程中调用

    data:响应体信息

    response:响应头信息

    error:错误信息当请求失败的时候error有值

    */

    NSURLSessionDataTask*dataTask = [sessiondataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {

    NSLog(@"%@",[NSThreadcurrentThread]);

    //6.解析数据

    NSLog(@"%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);

    }];

    //5.执行Task

    [dataTaskresume];

    }

    NSURLSession代理方法

    #import"ViewController.h"

    @interfaceViewController()

    /**接受响应体信息*/

    @property(nonatomic,strong)NSMutableData*fileData;

    @end

    @implementationViewController

    -(NSMutableData*)fileData

    {

    if(_fileData==nil) {

    _fileData= [NSMutableDatadata];

    }

    return_fileData;

    }

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event

    {

    //1.url

    NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=123&type=JSON"];

    //2.创建请求对象

    NSURLRequest*request = [NSURLRequestrequestWithURL:url];

    //3.创建会话对象,设置代理

    /*

    第一个参数:配置信息[NSURLSessionConfiguration defaultSessionConfiguration]

    第二个参数:代理

    第三个参数:设置代理方法在哪个线程中调用

    */

    NSURLSession*session = [NSURLSessionsessionWithConfiguration:[NSURLSessionConfigurationdefaultSessionConfiguration]delegate:selfdelegateQueue:[NSOperationQueuemainQueue]];

    //4.创建Task

    NSURLSessionDataTask*dataTask = [sessiondataTaskWithRequest:request];

    //5.执行Task

    [dataTaskresume];

    }

    #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.fileDataappendData:data];

    }

    /**

    *请求结束或者是失败的时候调用

    *

    *@param session会话对象

    *@param dataTask请求任务

    *@param error错误信息

    */

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

    {

    NSLog(@"%s",__func__);

    //解析数据

    NSLog(@"%@",[[NSStringalloc]initWithData:self.fileDataencoding:NSUTF8StringEncoding]);

    }

    @end

    NSURLSessionDownloadTask大文件下载(block)

    //优点:不需要担心内存

    //缺点:无法监听文件下载进度

    -(void)download

    {

    //1.url

    NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];

    //2.创建请求对象

    NSURLRequest*request = [NSURLRequestrequestWithURL:url];

    //3.创建session

    NSURLSession*session = [NSURLSessionsharedSession];

    //4.创建Task

    /*

    第一个参数:请求对象

    第二个参数:completionHandler回调

    location:

    response:响应头信息

    error:错误信息

    */

    //该方法内部已经实现了边接受数据边写沙盒(tmp)的操作

    NSURLSessionDownloadTask*downloadTask = [sessiondownloadTaskWithRequest:requestcompletionHandler:^(NSURL*_Nullablelocation,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {

    //6.处理数据

    NSLog(@"%@---%@",location,[NSThreadcurrentThread]);

    //6.1拼接文件全路径

    NSString*fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject]stringByAppendingPathComponent:response.suggestedFilename];

    //6.2剪切文件

    [[NSFileManagerdefaultManager]moveItemAtURL:locationtoURL:[NSURLfileURLWithPath:fullPath]error:nil];

    NSLog(@"%@",fullPath);

    }];

    //5.执行Task

    [downloadTaskresume];

    }

    @end

    -(void)delegate

    {

    //1.url

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];

    //2.创建请求对象

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //3.创建session

    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //4.创建Task

    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];

    //5.执行Task

    [downloadTask resume];

    }

    #pragma mark ----------------------

    #pragma mark NSURLSessionDownloadDelegate

    /**

    *  写数据

    *

    *  @param session                  会话对象

    *  @param downloadTask              下载任务

    *  @param bytesWritten              本次写入的数据大小

    *  @param totalBytesWritten        下载的数据总大小

    *  @param totalBytesExpectedToWrite  文件的总大小

    */

    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

    {

    //1. 获得文件的下载进度

    NSLog(@"%f",1.0 * totalBytesWritten/totalBytesExpectedToWrite);

    }

    /**

    *  当恢复下载的时候调用该方法

    *

    *  @param fileOffset        从什么地方下载

    *  @param expectedTotalBytes 文件的总大小

    */

    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes

    {

    NSLog(@"%s",__func__);

    }

    /**

    *  当下载完成的时候调用

    *

    *  @param location    文件的临时存储路径

    */

    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location

    {

    NSLog(@"%@",location);

    //1 拼接文件全路径

    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

    //2 剪切文件

    [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];

    NSLog(@"%@",fullPath);

    }

    /**

    *  请求结束

    */

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

    {

    NSLog(@"didCompleteWithError");

    }

    @end

    NSURLSessionDownloadTask大文件下载(断点下载)

    @interface ViewController ()@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;

    @property (nonatomic, strong) NSData *resumData;

    @property (nonatomic, strong) NSURLSession *session;

    @end

    @implementation ViewController

    - (IBAction)startBtnClick:(id)sender

    {

    //1.url

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

    //2.创建请求对象

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //3.创建session

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

    self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //4.创建Task

    NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];

    //5.执行Task

    [downloadTask resume];

    self.downloadTask = downloadTask;

    }

    //暂停是可以恢复

    - (IBAction)suspendBtnClick:(id)sender

    {

    NSLog(@"+++++++++++++++++++暂停");

    [self.downloadTask suspend];

    }

    //cancel:取消是不能恢复

    //cancelByProducingResumeData:是可以恢复

    - (IBAction)cancelBtnClick:(id)sender

    {

    NSLog(@"+++++++++++++++++++取消");

    //[self.downloadTask cancel];

    //恢复下载的数据!=文件数据

    [self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {

    self.resumData = resumeData;

    }];

    }

    - (IBAction)goOnBtnClick:(id)sender

    {

    NSLog(@"+++++++++++++++++++恢复下载");

    if(self.resumData)

    {

    self.downloadTask = [self.session downloadTaskWithResumeData:self.resumData];

    }

    [self.downloadTask resume];

    }

    //优点:不需要担心内存

    //缺点:无法监听文件下载进度

    -(void)download

    {

    //1.url

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];

    //2.创建请求对象

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //3.创建session

    NSURLSession *session = [NSURLSession sharedSession];

    //4.创建Task

    /*

    第一个参数:请求对象

    第二个参数:completionHandler 回调

    location:

    response:响应头信息

    error:错误信息

    */

    //该方法内部已经实现了边接受数据边写沙盒(tmp)的操作

    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {

    //6.处理数据

    NSLog(@"%@---%@",location,[NSThread currentThread]);

    //6.1 拼接文件全路径

    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];

    //6.2 剪切文件

    [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];

    NSLog(@"%@",fullPath);

    }];

    //5.执行Task

    [downloadTask resume];

    }

    #pragma mark ----------------------

    #pragma mark NSURLSessionDownloadDelegate

    /**

    *  写数据

    *

    *  @param session                  会话对象

    *  @param downloadTask              下载任务

    *  @param bytesWritten              本次写入的数据大小

    *  @param totalBytesWritten        下载的数据总大小

    *  @param totalBytesExpectedToWrite  文件的总大小

    */

    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

    {

    //1. 获得文件的下载进度

    NSLog(@"%f",1.0 * totalBytesWritten/totalBytesExpectedToWrite);

    }

    /**

    *  当恢复下载的时候调用该方法

    *

    *  @param fileOffset        从什么地方下载

    *  @param expectedTotalBytes 文件的总大小

    */

    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes

    {

    NSLog(@"%s",__func__);

    }

    /**

    *  当下载完成的时候调用

    *

    *  @param location    文件的临时存储路径

    */

    -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location

    {

    NSLog(@"%@",location);

    //1 拼接文件全路径

    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

    //2 剪切文件

    [[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];

    NSLog(@"%@",fullPath);

    }

    /**

    *  请求结束

    */

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

    {

    NSLog(@"didCompleteWithError");

    }

    @end

    使用NSURLSessionDataTask实现大文件下载

    #import "ViewController.h"@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;@end@implementation ViewController-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event

    {

    //1.url

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];

    //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

    {

    //获得文件的总大小

    self.totalSize = response.expectedContentLength;

    //获得文件全路径

    self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];

    //创建空的文件

    [[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;

    }

    @end

    NSURLSessionDataTask离线断点下载(断点续传)

    -(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

    NSURL *url = [NSURL URLWithString:@"http://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];

    }

    @end

    (1)关于NSOutputStream的使用

    //1. 创建一个输入流,数据追加到文件的屁股上

    //把数据写入到指定的文件地址,如果当前文件不存在,则会自动创建

    NSOutputStream *stream = [[NSOutputStream alloc]initWithURL:[NSURL fileURLWithPath:[self fullPath]] append:YES];

    //2. 打开流

    [stream open];

    //3. 写入流数据

    [stream write:data.bytes maxLength:data.length];

    //4.当不需要的时候应该关闭流

    [stream close];

    (2)关于网络请求请求头的设置(可以设置请求下载文件的某一部分)

    //1. 设置请求对象

    //1.1 创建请求路径

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

    //1.2 创建可变请求对象

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //1.3 拿到当前文件的残留数据大小

    self.currentContentLength = [self FileSize];

    //1.4 告诉服务器从哪个地方开始下载文件数据

    NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentContentLength];

    NSLog(@"%@",range);

    //1.5 设置请求头

    [request setValue:range forHTTPHeaderField:@"Range"];

    (3)NSURLSession对象的释放

    -(void)dealloc

    {

    //在最后的时候应该把session释放,以免造成内存泄露

    //    NSURLSession设置过代理后,需要在最后(比如控制器销毁的时候)调用session的invalidateAndCancel或者resetWithCompletionHandler,才不会有内存泄露

    //    [self.session invalidateAndCancel];

    [self.session resetWithCompletionHandler:^{

    NSLog(@"释放---");

    }];

    }

    (4)优化部分

    01 关于文件下载进度的实时更新

    02 方法的独立与抽取

    NSURLSession实现文件上传

    (1)实现文件上传的方法

    /*

    第一个参数:请求对象

    第二个参数:请求体(要上传的文件数据)

    block回调:

    NSData:响应体

    NSURLResponse:响应头

    NSError:请求的错误信息

    */

    NSURLSessionUploadTask *uploadTask =  [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)

    (2)设置代理,在代理方法中监听文件上传进度

    /*

    调用该方法上传文件数据

    如果文件数据很大,那么该方法会被调用多次

    参数说明:

    totalBytesSent:已经上传的文件数据的大小

    totalBytesExpectedToSend:文件的总大小

    */

    -(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend

    {

    NSLog(@"%.2f",1.0 * totalBytesSent/totalBytesExpectedToSend);

    }

    (3)关于NSURLSessionConfiguration相关

    01 作用:可以统一配置NSURLSession,如请求超时等

    02 创建的方式和使用

    //创建配置的三种方式

    + (NSURLSessionConfiguration *)defaultSessionConfiguration;

    + (NSURLSessionConfiguration *)ephemeralSessionConfiguration;

    + (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);

    //统一配置NSURLSession

    -(NSURLSession *)session

    {

    if (_session == nil) {

    //创建NSURLSessionConfiguration

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

    //设置请求超时为10秒钟

    config.timeoutIntervalForRequest = 10;

    //在蜂窝网络情况下是否继续请求(上传或下载)

    config.allowsCellularAccess = NO;

    _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    }

    return _session;

    }

    #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:@"http://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:@"http://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);

    }

    @end

    相关文章

      网友评论

        本文标题:iOS网络编程(十)

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