OC的NSURLSession

  上一次的WWCD大会发布,说明了要废弃NSURLConnection,估计不少人蛋疼了。在Xcode7中已经不能使用NSURLConnection了,这样也致使了不少第三方框架不能在Xcode7中使用。NSURLSession的崛起已成为了必然!php

  为了适应IT这个行业必须不断更新知识,不断充实本身,因此我认真的学习了一下NSURLSession。程序员

  NSURLSession的简介(IOS 7.0之后出现):NSURLSession是一组相互依赖的类,它的大部分组件和NSURLConnection中的组件相同如NSURLRequest,NSURLCache等。而NSURLSession的不一样之处在于,它将NSURLConnection替换为NSURLSession和NSURLSessionConfiguration,以及3个NSURLSessionTask的子类:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。

1.支持后台运行网络任务json

2.暂停、中止、重启网络任务,再也不须要 NSOperation 封装缓存

3.请求可使用一样的配置容器服务器

4.不一样的 session 可使用不一样的私有存储cookie

5.block 和代理能够同时起做用网络

6.直接从文件系统上传、下载session

注意:为了方便程序员使用,苹果提供了一个全局 session并发

全部的 任务(Task) 都是由 Session 发起的app

全部的任务默认是挂起的,须要 Resume,不少时候不少人在使用的时候都会忘记写resume。

session 的回调是异步的

  NSURLSession的成员变量NSURLSessionConfiguration:

NSURLSessionConfiguration 用于设置全局的网络会话属性,包括:身份验证,超时时长,缓存策略,Cookie 等,能够代替NSURLRequest。

NSURLSessionConfiguration 有三个类构造方法是为不一样的用例设计的

1.+ (NSURLSessionConfiguration *)defaultSessionConfiguration- 返回标准配置,具备共享 NSHTTPCookieStorage(cookie仓库)NSURLCache(路径缓存) 和 NSURLCredentialStorage(证书仓库)。

2.+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration- 返回一个预设配置,没有持久性存储的缓存,Cookie或证书。这对于实现像秘密浏览功能的功能来讲,是很理想的

3.+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0)-独特之处在于,会建立一个后台会话。后台会话不一样于常规的,普通的会话,它甚至能够在应用程序挂起,退出,崩溃的状况下运行上传和下载任务。初始化时指定的标识符,被用于向任何可能在进程外恢复后台传输的守护进程提供上下文

NSURLSessionConfiguration的经常使用属性

//Hosts是一个系统文件,记录了一些网站的IP地址和域名的对应关系

//Cookie就是服务器暂存放在你计算机上的一笔资料,好让服务器用来辨认你的计算机\

NSURLSessionConfiguration-->HTTPShouldSetCookies是否应该设置cookie HTTPCookieAcceptPolicy设置cookie的选择

属性 描述
HTTPAdditionalHeaders HTTP 头字段
timeoutIntervalForRequest 超时时长
timeoutIntervalForResource 整个资源请求时长
requestCachePolicy 缓存策略
allowsCellularAccess 容许蜂窝访问
HTTPMaximumConnectionsPerHost 对于一个host的最大并发链接数,默认数值是 4,MAC 下的默认数值是 6

NSURLSession注意事项

一旦指定了 session 的代理,session会对代理进行强引用,若是不主动取消 session,会形成内存泄漏!

解决方案

解决方法1:在任务完成后取消 session

缺点:session一旦被取消就没法再次使用

解决方法2:在视图将要消失的时候取消 session

优势:只须要一个全局的session统一管理

 

  NSURLSession支持的三种任务:

 

NSURLSession类支持三种类型的任务:加载数据(NSURLSessionDataTask),下载(NSURLSessionDownloadTask)和上传(NSURLSessionUploadTask)。

 

  加载数据代码演示:

- (void)sessionDemo1 {
    // 1. url
    NSURL *url = [NSURL URLWithString:@"http://localhost/demo.json"];

    // 2. session
    NSURLSession *session = [NSURLSession sharedSession];

    // 3. 数据任务
    NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        NSLog(@"%@ %@ %@", result, response, [NSThread currentThread]);
    }];

    // 4. 继续任务
    [task resume];
}

  

    下载文件数据代码简单演示:

注意:块代码回调结束后,下载的文件会被删除

- (void)download {

    NSLog(@"开始");

    // 1. url
    NSURL *url = [NSURL URLWithString:@"http://localhost/321.zip"];

    // 2. 下载
    [[[NSURLSession sharedSession] downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        NSLog(@"%@ %@", location, [NSThread currentThread]);
    }] resume];
}

 

 

    上传文件数据代码演示:

上传文件

#define boundary @"itcast-upload"

- (void)uploadFile:(NSString *)fieldName dataDict:(NSDictionary *)dataDict params:(NSDictionary *)params {
    // 1. url - 负责上传文件的脚本
    NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload-m.php"];

    // 2. request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";

    NSString *typeValue = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:typeValue forHTTPHeaderField:@"Content-Type"];

    NSData *data = [self formData:fieldName dataDict:dataDict params:params];

    // 3. 上传
    [[[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        NSLog(@"%@ %@", response, [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]);
    }] resume];
}

拼接数据体

///  生成 formData 二进制数据
///
///  @param fieldName 服务器字段名
///  @param dataDict  上传文件数据字典 "保存在服务器文件名": 二进制数据
///  @param params    提交参数字典
///
///  @return formData 二进制数据
- (NSData *)formData:(NSString *)fieldName dataDict:(NSDictionary *)dataDict params:(NSDictionary *)params {

    NSMutableData *dataM = [NSMutableData data];

    // 1. 生成文件数据
    [dataDict enumerateKeysAndObjectsUsingBlock:^(NSString *fileName, NSData *fileData, BOOL *stop) {
        NSMutableString *strM = [NSMutableString string];

        [strM appendFormat:@"--%@\r\n", boundary];
        [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, fileName];
        [strM appendString:@"Content-Type: application/octet-stream\r\n\r\n"];

        [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]];
        [dataM appendData:fileData];

        [dataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }];

    // 2. 生成参数数据
    [params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {

        NSMutableString *strM = [NSMutableString string];

        [strM appendFormat:@"--%@\r\n", boundary];
        [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
        [strM appendString:value];
        [strM appendString:@"\r\n"];

        [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]];
    }];

    // 3. 结尾字符串
    NSString *tail = [NSString stringWithFormat:@"--%@--", boundary];
    [dataM appendData:[tail dataUsingEncoding:NSUTF8StringEncoding]];

    return dataM.copy;
}

 

开始上传

- (void)uploadFileDemo {
    // 1. 上传文件数据
    NSURL *fileURL1 = [[NSBundle mainBundle] URLForResource:@"001.png" withExtension:nil];
    NSData *data1 = [NSData dataWithContentsOfURL:fileURL1];

    NSURL *fileURL2 = [[NSBundle mainBundle] URLForResource:@"demo.jpg" withExtension:nil];
    NSData *data2 = [NSData dataWithContentsOfURL:fileURL2];

    // 如何传递参数 - 用字典传递参数
    NSDictionary *dataDict = @{@"001.png": data1, @"002.jpg": data2};

    // 2. 字符串参数
    NSDictionary *params = @{@"status": @"how are you"};

    // 3. 上传文件而且提交参数
    [self uploadFile:@"userfile[]" dataDict:dataDict params:params];
}
相关文章
相关标签/搜索