在iOS开发中,我们常用第三方—AFNetWorking框架请求网络数据,现在已经更新到了3.0,对NSURLSession的很多方法进行了封装,今天分享的是简单使用NSURLSession来请求数据。
请求数据思路
用户跟服务器请求数据:
1.寻找Server(url)
2.做什么事情 (请求体)
3.Server响应
请求的方式
两种方式:GET 和 POST
简单说明一下他们之间的区别:
GET请求:请求参数放在url后面 格式:url?参数格式 (1024字节)。
POST请求:超文本传输,参数是放在请求体里面。
NSURLSession 默认是做异步请求数据。
GET请求
#import "ViewController.h"
//示例接口
#define URLPath @"http://svr.tuliu.com/center/front/app/util/updateVersions"
//拼接的参数:versions_id & system_type
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self getData];
}
- (void)getData
{
NSString * urlStr = [NSString stringWithFormat:@"%@?versions_id=1&system_type=1",URLPath];
NSLog(@"urlStr:%@",urlStr);
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
[request setHTTPMethod:@"GET"];
[request setHTTPBody:nil];
//block方式
NSURLSession * session = [NSURLSession sharedSession];
NSURLSessionDataTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//json解析
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"dic:%@",dic);
}];
//手动开启
[task resume];
}
@end
运行结果:我们可以看到,拼接的参数是完全裸露的,不安全。接下来看看POST的写法。
Paste_Image.png
POST请求
#import "ViewController.h"
//示例接口
#define URLPath @"http://svr.tuliu.com/center/front/app/util/updateVersions"
//拼接的参数:versions_id & system_type
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self postData];
}
/* post请求 */
- (void)postData
{
NSString * urlStr = [NSString stringWithFormat:@"%@",URLPath];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
[request setHTTPMethod:@"POST"];
//跟GET请求的区别:把参数放到请求体里
NSString * postStr = @"versions_id=1&system_type=1";
[request setHTTPBody:[postStr dataUsingEncoding:NSUTF8StringEncoding]];
//block方式
NSURLSession * session = [NSURLSession sharedSession];
NSURLSessionDataTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//json解析
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"dic:%@",dic);
NSString * str = [NSString stringWithFormat:@"%@",dic[@"data"][@"updateContent"]];
NSLog(@"updateContent:%@",str);
}];
//手动开启
[task resume];
}
@end
运行结果:跟GET请求返回的数据是一样,但拼接的参数放在请求体中,更安全一些。
Paste_Image.png
接下来我们通过使用NSURLSession的代理来请求数据,我们以POST请求为例。
NSURLSessionDelegate && NSURLSessionDataDelegate
我们用代理方法来请求数据的时候,会用到一个方法:
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
我们需要传入三个参数:
Paste_Image.pngNSURLSessionConfiguration 、NSURLSessionDelegate、NSOperationQueue
。
主要说说NSURLSessionConfiguration:
它有3个属性:
1.defaultSessionConfiguration: 放在磁盘中,生命周期跟系统一样,
底层是文件cache 沙盒中的临时文件夹;
2.ephemeralSessionConfiguration:临时缓存 生命周期是跟app生命周期一样的;
3.backgroundSessionConfigurationWithIdentifier:后台模式.
我们可以根据项目的要求来选择它的属性,这里我就选择了临时缓存。
另外,在- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler;
代理方法中,有一个请求头response,一般来说,我们是不需要处理的,如果要进行复杂的网络操作,例如断点续传、图片下载等,就需要来处理请求头。
代码如下:
#import "ViewController.h"
//示例接口
#define URLPath @"http://svr.tuliu.com/center/front/app/util/updateVersions"
//拼接的参数:versions_id & system_type
@interface ViewController ()<NSURLSessionDelegate,NSURLSessionDataDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self delegatePostData];
}
/*
用代理方式请求数据
*/
- (void)delegatePostData
{
NSString * urlStr = [NSString stringWithFormat:@"%@",URLPath];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
[request setHTTPMethod:@"POST"];
//把参数放到请求体里
NSString * postStr = @"versions_id=1&system_type=1";
[request setHTTPBody:[postStr dataUsingEncoding:NSUTF8StringEncoding]];
//代理方法来请求数据
NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:self delegateQueue:nil];
NSURLSessionTask * task = [session dataTaskWithRequest:request];
[task resume];
}
#pragma mark - NSURLSessionDelegate,NSURLSessionDataDelegate
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
//json解析 异步请求数据,主线程刷新UI
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"dic:%@",dic);
}
//网络传输完成
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"网络传输完成");
}
@end
总结
虽然现在开发中,都是用AFN来处理网络请求,但理解苹果一些自带的方法还是很有必要的,可以便于对第三方框架更好的理解,另外再提一点,现在请求数据苹果都是推荐使用NSURLSession,不推荐使用NSURLConnection,开发中还是要用最新的,不然以后一定还需要修改。
网友评论