iOS 学习

NSURLConnection通过全局状态来管理cookies、认证信息等公共资源,这样如果遇到两个连接需要使用不同的资源配置情况时就无法解决了,但是这个问题在NSURLSession中得到了解决。NSURLSession同时对应着多个连接,会话通过工厂方法来创建,同一个会话中使用相同的状态信息。NSURLSession支持进程三种会话:

  1. defaultSessionConfiguration:进程内会话(默认会话),用硬盘来缓存数据。
  2. ephemeralSessionConfiguration:临时的进程内会话(内存),不会将cookie、缓存储存到本地,只会放到内存中,当应用程序退出后数据也会消失。
  3. backgroundSessionConfiguration:后台会话,相比默认会话,该会话会在后台开启一个线程进行网络数据处理。

下面将通过一个文件下载功能对两种会话进行演示,在这个过程中也会用到任务的代理方法对上传操作进行更加细致的控制。下面先看一下使用默认会话下载文件,代码中演示了如何通过NSURLSessionConfiguration进行会话配置,如果通过代理方法进行文件下载进度展示(类似于前面中使用NSURLConnection代理方法,其实下载并未分段,如果需要分段需要配合后台进行),同时在这个过程中可以准确控制任务的取消、挂起和恢复。

//
//  ViewController.m
//  NSURLSession会话
//
//  Copyright © 2016年 asamu. All rights reserved.
//

#import "ViewController.h"
@interface ViewController ()<NSURLSessionDownloadDelegate>
{
    NSURLSessionDownloadTask *_downloadTask;
}

@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;

@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIButton *downBtn;

@end

@implementation ViewController
#pragma mark -- UI方法
- (void)viewDidLoad {
    [super viewDidLoad];
    _progressView.progress = 0;
}
#pragma mark 按钮点击事件
- (IBAction)download:(id)sender {

    NSString *filename = _textField.text;
    NSString *urlStr = [NSString stringWithFormat:@"http://mr7.doubanio.com/832d52e9c3df5c13afd7243a770c094f/0/fm/song/p294_128k.mp3",filename];
    NSURL *url = [NSURL URLWithString:urlStr];
    //创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    //创建会话
      //默认会话
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    //请求超过时间
    sessionConfiguration.timeoutIntervalForRequest = 5.0f;
    //是否允许使用蜂窝
    sessionConfiguration.allowsCellularAccess = true;
    //创建会话
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
    _downloadTask = [session downloadTaskWithRequest:request];
    [_downloadTask resume];
}

- (IBAction)cancel:(id)sender {
    [_downloadTask cancel];
    _label.text = @"Cancel";
}

- (IBAction)suspend:(id)sender {
    [_downloadTask suspend];
    _label.text  =@"Suspend";
}
- (IBAction)resume:(id)sender {
    [_downloadTask resume];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
#pragma mark - 设置界面状态
-(void)setUIStatus:(int64_t)totalBytesWritten expectedTowrite:(int64_t)totalBytesExpectedWritten{
    //更新 UI 放到主线程
    dispatch_async(dispatch_get_main_queue(), ^{
    //设置进度条
        _progressView.progress = (float)totalBytesWritten / totalBytesExpectedWritten;
    
        if (totalBytesWritten == totalBytesExpectedWritten) {
        
            _label.text = @"Finish download";
            //关网
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            _downBtn.enabled = YES;
    
        }else{
    
            _label.text = @"Downing...";
            [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    }
    });
}
#pragma mark - 下载任务代理
#pragma mark 下载中(会多次调用,可以记录下载进度)
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    [self setUIStatus:totalBytesWritten expectedTowrite:totalBytesExpectedToWrite];
}
#pragma mark 下载完成
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    NSError *error;
    //注释见上篇,懒得写。。。
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
    NSString *savePath = [cachePath stringByAppendingPathComponent:_textField.text];
    NSLog(@"%@",savePath);
    
    NSURL *url = [NSURL fileURLWithPath:savePath];
    
    [[NSFileManager defaultManager]moveItemAtURL:location toURL:url error:&error];
    if (error) {
        NSLog(@"%@",error.localizedDescription);
    }
}
#pragma mark 任务完成,不管是否下载成功
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    if (error) {
    NSLog(@"%@",error.localizedDescription);
    }
}
@end

Storyboard如右图:

原文地址:https://www.cnblogs.com/asamu/p/5427065.html