code
准备工作
// 用来装每次请求的数据
@property (nonatomic, retain) NSMutableData *data;
从 iOS9.0之后, 默认是 https请求, 如果想继续使用 http 请求, 需要在 info.plist 中加上一些内容, 内容如下:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
异步 Get block 请求 ※※※※※※※※※※※
- (IBAction)asynGetBlock:(id)sender {
// NSString *strURL = @"http://project.lanou3g.com/teacher/yihuiyun/lanouproject/movielist.php";
NSString *strURL = @"http://mrobot.pconline.com.cn/configs/pconline_v8_cms_android_channel_tree HTTP/1.1";
NSURL *url = [NSURL URLWithString:strURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 创建 session 对象
NSURLSession *session = [NSURLSession sharedSession];
// 创建一个任务对象
NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 把数据从子线程移到主线程
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
// json 解析
id result = [NSJSONSerialization JSONObjectWithData: data options:NSJSONReadingMutableContainers error:nil];
});
}];
// 执行一下任务
[task resume];
PS:
{
...
// get可以用, post 不能用
NSURLSessionTask *task1 = [session dataTaskWithURL: url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"%@", dic);
}];
[task1 resume];
}
异步 Post block 请求
- (IBAction)asynPostBlock:(id)sender {
NSString *str = @"http://api2.pianke.me/pub/today";
NSURL *url = [NSURL URLWithString: str];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url];
// 设置请求方式, 默认是GET
[request setHTTPMethod: @"POST"];
// 附件
NSString *bodyStr = @"start=%ld&client=2&limit=10";
// 需要把附件字符串转换为 NSData
NSData *bodyData = [bodyStr dataUsingEncoding: NSUTF8StringEncoding];
[request setHTTPBody: bodyData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionTask *task = [session dataTaskWithRequest: request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"%@", dic);
}];
[task resume];
}
同步请求
- (IBAction)syn:(id)sender {
NSString *urlStr = @"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg";
// 把网址的字符串, 变成 NSURL
NSURL *url = [NSURL URLWithString:urlStr];
// 把 url 对应的内容变成 NSData 对象
NSData *data = [NSData dataWithContentsOfURL: url];
self.imageView.image = [UIImage imageWithData: data];
}
异步 Get 协议请求
// NSURLSession 和 NBURLConnection 的使用基本相似, Session 是 iOS7.0之后出现的网络请求类, 出现的目的是为了替换 NSURLConnection, 他的出现提高了原本类的性能, 在 iOS9.0之后已经全面替换 Connection
// Session 可以通过协议和 block 两种方式进行网络请求
- (IBAction)asynGetProtocol:(id)sender {
NSString *urlStr = @"http://api.map.baidu.com/place/v2/search?query=银行®ion=大连&output=json&ak=6E823f587c95f0148c19993539b99295";
// 一个 url 由字母大小写, 数字和特殊符号比如/, &, $, ?, =组成, 一般来讲是没有汉字的, 所以当请求里包含汉字的时候, 需要手动的给 url里的汉字进行转码
urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:urlStr]];
NSLog(@"%@", urlStr);
// 需要把 urlstr 转变成 NSURL
NSURL *url = [NSURL URLWithString: urlStr];
// 创建一个请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url];
// 创建 NSURLSession 对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
// 创建一个任务对象
NSURLSessionTask *task = [session dataTaskWithRequest:request];
// 执行任务, 如果不写, 整个任务不会自动执行
[task resume];
}
// 这个方法在694行
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{
NSLog(@"%@", response);
// 这个方法会把服务器相应的信息返回给我们, 也就是 response, 在这里面能查到 http 对象的响应码, status code, 200是请求成功, 404是没有找到制定页面, 500是服务器的问题, 所以根据 response 可以知道请求的相应信息, 便于查找问题
// 当服务器响应之后, 需要允许服务器响应才能继续接受信息, 方法就是调用第四个参数 block, 让它来完成这个功能
completionHandler(NSURLSessionResponseAllow);
// 允许完成之后, 初始化接收数据的容器, data
self.data = [NSMutableData data];
}
// 728行
// 这个方法会持续的从服务器接收返回的数据, 会被多次调用, 在这个方法里可以用 self, data 对数据进行累加, 等到最后一次数据累加完成之后, 就完成了整个请求过程
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data {
[self.data appendData: data];
}
// 675行
// 这个方法一般会在完成请求或请求失败的时候出发, 区分的话就是参数 error, 如果失败, error 就会有值, 如果成功, error 为空
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error{
if ( error == nil) {
// json 解析
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:nil];
NSLog(@"%@", dic);
} else {
NSLog(@"请求失败");
}
}