确定资源加载请求是否应被转换为下载任务等等;NSURLSession提供了较多的配置选项:
- 支持对特定的单个session进行私有存储,包括缓存,cookies,凭证和协议;
- 将身份认证绑定到特定请求或者一组请求中;
- 通过URL进行文件上传和下载,提议将数据(文件内容)和元数据进行分离;
- 对每一个主机配置最大连接数;
- 如果整个资源在特定的时间内无法下载,则会触发每个资源的超时问题;
- 对TLS最大版本和最小版本的支持;
- 自定义代理(服务器)字段;
- 控制cookie的策略;
- 控制HTTP管道行为;
由于大多数的配置都包含在各个配置对象中,因此我们可以重用常用的配置选项,当我们要实例化一个session对象时,我们需要指定以下内容:
- 使用配置对象来管理session的行为和session中的任务;
- (这一项是可选的)使用代理对象来处理接收到的数据,并处理session的其他事件和session中的任务,比如服务器身份认证,确定资源加载请求是否应被转换为下载任务等等;
如果我们没有提供代理,NSURLSession对象会使用系统提供的代理。即便如此,我们依然可以很容易地使用NSURLSession代替现有sendAsynchronousRequest:queue:completionHandler:方法相关的代码。
🌈🌈🌈 提示
如果想要实现后台传输,那么我们必须要提供自定义的代理。
如果我们已经创建了session对象,那么无法在没有新创建session对象的前提下去修改原session的配置和代理的(⚠️ 这说的是已经创建了的session是无法修改,并不是说不能修改其NSURLSessionConfiguration的对象)。下面展示如何去创建一个默认的(default),短暂的(ephemeral)和后台(background)的session:
/// Objective-C
NSURLSessionConfiguration *default_config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSessionConfiguration *ephemera_config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
NSURLSessionConfiguration *background_config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.urlsession_example.background"];
NSString *cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
NSString *cachePath = [cachesDirectory stringByAppendingPathComponent:@"MyCache"];
#if TARGET_OS_OSX
cachePath = [cachePath stringByStandardizingPath];
#endif
/// bytes
NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:16384 diskCapacity:268435456 diskPath:cachePath];
///ephemera_config 默认是将数据存储在RAM中
/// default,background_config 默认是将数据存储在磁盘中
default_config.URLCache = urlCache;
/// 请求缓存策略
default_config.requestCachePolicy = NSURLRequestUseProtocolCachePolicy;
NSOperationQueue *operation_queue = [NSOperationQueue mainQueue];
/// 该类在“代理类接口样例”一节中
id<NSURLSessionDelegate> delegate = [[CDSessionDelegate alloc] init];
NSURLSession *default_session = [NSURLSession sessionWithConfiguration:default_config delegate:delegate delegateQueue:operation_queue];
NSURLSession *ephemera_session = [NSURLSession sessionWithConfiguration:ephemera_config delegate:delegate delegateQueue:operation_queue];
NSURLSession *background_session = [NSURLSession sessionWithConfiguration:background_config delegate:delegate delegateQueue:operation_queue];
/// Swift
let default_config:URLSessionConfiguration = .`default`
let ephemeral_config:URLSessionConfiguration = .ephemeral
let background_config:URLSessionConfiguration = .background(withIdentifier: "com.urlsession_example.background")
guard let cache_directory_url = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else{
return
}
let cache_url = cache_directory_url.appendingPathComponent("MyCache")
let disk_path = cache_url.path
#if os(OSX)
disk_path = cache_path.absoluteString
#endif
///ephemera_config 默认是将数据存储在RAM中
/// default,background_config 默认是将数据存储在磁盘中
let urlCache = URLCache(memoryCapacity: 16384, diskCapacity: 268435456, diskPath: disk_path)
default_config.urlCache = urlCache
default_config.requestCachePolicy = .useProtocolCachePolicy
let delegate = CDSessionDelegate()
let mainQueus = OperationQueue.main
let default_session = URLSession(configuration: default_config, delegate: delegate, delegateQueue: mainQueus)
let ephemeral_session = URLSession(configuration: ephemeral_config, delegate: delegate, delegateQueue: mainQueus)
let background_session = URLSession(configuration: background_config, delegate: delegate, delegateQueue: mainQueus)
除了“后台配置对象”(上例中的background_config)外,我们可以重用session配置对象来创建其他session。
⚠️⚠️⚠️ 注意
因为两个甚至多个后台session对象共享同一个相同的标识符是未定义的,所以我们不能重复使用后台session配置对象。
我们可以安全地在任何时候去修改配置对象(⚠️ 这里是说的修改配置对象),当我们创建了一个session,该session会执行一个深拷贝这个配置对象,所以在此之后的修改只对新的session有影响。
下面是假想此时我们处于WI-FI连接下创建第二个session来获取内容的例子:
/// Objective-C
/// 不允许使用蜂窝数据
ephemera_config.allowsCellularAccess = NO;
NSURLSession *ephemeralSessionWiFiOnly = [NSURLSession sessionWithConfiguration:ephemera_config delegate:delegate delegateQueue:operation_queue];
/// Swift
ephemeral_config.allowsCellularAccess = false
let ephemeralSessionWiFiOnly = URLSession(configuration: ephemeral_config, delegate: delegate, delegateQueue: mainQueus)