NSURLSession 使用
1. 使用NSURLSession对象创建Task,然后执行Task
Task类型:
注意:
NSURLSessionTask 是一个抽象类,本身不可使用. 只能使用它的子类.
2. 创建NSURLSession对象.
获得共享的Session
+ (NSURLSession *)sharedSession;
自定义Session
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id )delegate delegateQueue:(NSOperationQueue *)queue;
3. NSURLSessionTask常见属性和方法.
- (void)suspend; // 暂停
- (void)resume; // 恢复
- (void)cancel; // 取消
@property (readonly, copy) NSError *error; // 错误
@property (readonly, copy) NSURLResponse *response; // 响应
NSURLSessionDataTask发送GET,POST请求.
注意点:
1. NSURLSessionTask中的任务,都是在子线程中执行的. ( NSURLConnection中可以设置主/非主线程 )
2. 当发送GET请求时,使用dataTaskWithURL: completionHandel 创建NSURLSessionDataTask 时,方法内部会自动创建一个请求对象,并把URL传给请求对象. 因此不需要创建请求对象. ( POST 请求没有)
代码如下:// Created by 朝阳 on 2017/12/13.
// Copyright © 2017年 sunny. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self get2];
}
- (void)get
{
//1. 确定URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login?username=123&pwd=123&method=get&type=JSON"];
//2. 创建请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3. 创建会话对象(单例)
NSURLSession *session = [NSURLSession sharedSession];
//4. 创建Task任务
/*
第一个参数:请求对象
第二个参数:completionHandler 当请求完成之后调用 !!!!!! 在子线程中调用(NSURLConnection 中可以设置主/子线程). 在NSURLSessionTask中任务 都是在子线程中执行的
data:响应体信息
response:响应头信息
error:错误信息当请求失败的时候 error有值
*/
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//6. 解析数据
NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
//7. 执行Task
[dataTask resume];
}
- (void)get2
{
//1. 确定URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login?username=123&pwd=123&method=get&type=JSON"];
//2.创建会话对象
NSURLSession *session = [NSURLSession sharedSession];
/*
第一个参数:请求路径
第二个参数:completionHandler 当请求完成之后调用
data:响应体信息
response:响应头信息
error:错误信息当请求失败的时候 error有值
注意:dataTaskWithURL 内部会自动的将请求路径作为参数创建一个请求对象(GET)
*/
// dataTaskWithURL : 方法内部会自动创建一个请求对象,并把URL传给请求对象
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@",[NSThread currentThread]);
//4. 解析数据(反序列化) JSON --> OC对象
id obj = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"%@",obj);
}];
//5. 执行Task
[dataTask resume];
}
- (void)post
{
// 注意: POST请求不可以 省略创建请求的部分
//1. 确定URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login"];
//2. 创建可变请求
NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
//2.1 设置请求方法
requestM.HTTPMethod = @"POST";
//2.2 设置请求体
requestM.HTTPBody = [@"username=123&pwd=123&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
//3. 创建会话对象
NSURLSession *session = [NSURLSession sharedSession];
//4. 创建Task任务
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:requestM completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//5. 解析
NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
// 子线程
NSLog(@"%@",[NSThread currentThread]);
}];
//6. 执行Task
[dataTask resume];
}
@end
NSURLDataSession相关代理方法.
// Created by 朝阳 on 2017/12/13.
// Copyright © 2017年 sunny. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
/** 接受响应体信息 */
@property (nonatomic, strong) NSMutableData *fileData;
@end
@implementation ViewController
- (NSMutableData *)fileData
{
if (!_fileData) {
_fileData = [NSMutableData data];
}
return _fileData;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1. url
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login?username=123&pwd=123&method=get&type=JSON"];
//2. 创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3. 创建会话对象,并设置代理
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//4. 创建Task任务
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
// 如果设置代理,并且使用block的方式, 代理方法不会被调用
// NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
// }];
//5. 执行Task
[dataTask resume];
}
#pragma -mark NSURLSessionDataDelegate
/**
接收到服务器的响应 它默认会取消该请求
@param session 会话对象
@param dataTask 请求任务
@param response 响应头信息
@param completionHandler 回调 传给系统
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);
/*
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, line = %d", __FUNCTION__, __LINE__);
//拼接数据
[self.fileData appendData:data];
}
/**
请求结束或失败的时候调用
@param session 会话对象
@param task 请求任务
@param error 错误信息
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);
// 解析数据
NSLog(@"%@",[[NSString alloc] initWithData:self.fileData encoding:NSUTF8StringEncoding]);
}
@end