HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作。
//请求 URL
NSString* urlStr = [NSString stringWithFormat:@"https://news-at.zhihu.com/api/4/version/ios/2.3.0"];
//封装成 NSURL
NSURL *url = [NSURL URLWithString:urlStr];
//初始化 请求对象
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
//也可以这样初始化对象
//NSURLRequest* request = [NSURLRequest requestWithURL:url];
//或者写为如下形式
//NSMutableURLRequest *requestSecond = [NSMutableURLRequest initWithURL:url];
//[requestSecond setHTTPMethod:@"GET"];
//发送请求 默认为 GET 请求
//1 、获得会话对象
NSURLSession *session = [NSURLSession sharedSession];
// 2、创建请求任务
// 第一个参数:请求对象
// 第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
// data:响应体信息(期望的数据)
// response:响应头信息,主要是对服务器端的描述
// error:错误信息,如果请求失败,则error有值
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if(!error){
NSLog(@"请求加载成功。。。");
//说明:(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理)
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
} else {
NSLog(@"网络请求失败!");
}
}];
//执行任务
[dataTask resume];
//1.创建URL对象
NSURL *url = [NSURL URLWithString:@"你要获取的地址"];
//2.创建请求对象
//第一个参数是你的URL
//第二个参数是请求的缓存策略
//第三个参数是设置请求超时时间
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
//3.设置请求方法为post
[request setHTTPMethod:@"POST"];
//4.设置请求头信息
//key(头字段名(不区分大小写)):Content-Type,
//Value(头字段值)为下面三种:(还是得根据后台给的来设置)
//application/x-www-form-urlencoded(后台接收为分开的参数时,如?name=liyu&password=123)
//application/json(后台接收为json对象时)
//multipart/form-data(上传文件时)
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//5.设置请求体
NSString *param = [NSString stringWithFormat:@"username = %@ & pwd = %@", self.username.text, self.pwd.text];
//把拼接后的字符串转换为data,设置请求体(这个data就是请求体)
request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
//6.建立会话 session支持三种类型的任务
// NSURLSessionDataTask //加载数据
// NSURLSessionDownloadTask //下载
// NSURLSessionUploadTask //上传
NSURLSession *session = [NSURLSession sharedSession];
//7.创建请求任务
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//data就是你获取到的数据,你可以自行对其进行解析
//error就是获取失败时出现的问题
}];
//8.启动任务
[dataTask resume];
AFNetworking作为第三方库添加方式和之前博客中提到的Masonry,JSONModel等相似。
AFNetworking是一个功能非常强大的框架,主要是用于网络请求,把复杂的原生代码封装好,我们只需要简单的几步就可以完成网络请求。
#import "AFNetworking.h"//主要用于网络请求方法
#import "UIKit+AFNetworking.h"//里面有异步加载图片的方法
第一个参数:NSString类型的请求路径,AFNetworking内部会自动将该路径包装为 一个url并创建请求对象
第二个参数:请求参数,此处为nil
第三个参数:进度回调,此处为nil
第四个参数:请求成功之后回调Block
第五个参数:请求失败回调Block
[manager GET:@"https://news-at.zhihu.com/api/4/news/before/20221023" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"GET 请求成功, %@", responseObject[@"date"]);
self.AFNetWorkTestGETDictionary = responseObject;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"GET 失败");
}];
[manager POST:(nonnull NSString *) parameters:(nullable id) progress:^(NSProgress * _Nonnull uploadProgress) {
;
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
;
}]
第一个参数:NSString类型的请求路径,AFN内部会自动将该路径包装为一个url并创建请求对象
第二个参数:请求参数,以字典的方式传递,AFN内部会判断当前是POST请求还是GET请求,以选择直接拼接还是转换为NSData放到请求体中传递
第三个参数:进度回调 此处为nil
第四个参数:请求成功之后回调Block
第五个参数:请求失败回调Block
[manager POST:(nonnull NSString *) parameters:(nullable id) constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
;
} progress:^(NSProgress * _Nonnull uploadProgress) {
;
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
;
}]
对参数的理解
第一个参数:请求路径(NSString类型)
第二个参数:非文件参数,以字典的方式传递
第三个参数:constructingBodyWithBlock 在该回调中拼接文件参数
第四个参数:progress 进度回调
uploadProgress.completedUnitCount:已经上传的数据大小
uploadProgress.totalUnitCount:数据的总大小
第五个参数:success 请求成功的回调
task:上传Task
responseObject:服务器返回的响应体信息
第六个参数:failure 请求失败的回调
task:上传Task
error:错误信息
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//创建参数
[self.AFNetWorkTestPOSTDictionary setObject:@"Viper" forKey:@"userName"];
[self.AFNetWorkTestPOSTDictionary setObject:@"Viper333" forKey:@"passWord"];
//发送POST请求
[manager POST:@"要上传的URL" parameters:self.AFNetWorkTestPOSTDictionary progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//responseObject是请求成功返回的相应结果,在AFN内部已经把相应结果转换为OC对象,通常是字典或者数组
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"POST Failed");
}];
//创建会话管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//处理非文件的参数,模拟上传账号密码
self.AFNetWorkTestPOSTDictionary = [[NSMutableDictionary alloc] init];
[self.AFNetWorkTestPOSTDictionary setObject:@"Viper" forKey:@"userName"];
[self.AFNetWorkTestPOSTDictionary setObject:@"Viper333" forKey:@"passWord"];
//发送POST请求上传文件
[manager POST:@"https://news-at.zhihu.com/api/4/news/before/20221023" parameters:self.AFNetWorkTestPOSTDictionary constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// 混合的数据为头像
// 获取头像
// 把头像转化为Data
UIImage *image = [UIImage imageNamed:@"1.png"];
NSData *imageData = UIImagePNGRepresentation(image);
//在BLOCK进行参数拼接
//ImageUp.png是上传到服务器知乎以什么方式保存
// 什么是MIME Type : 参考博客:https://www.cnblogs.com/jsean/articles/1610265.html
[formData appendPartWithFileData:imageData name:@"file" fileName:@"1.png" mimeType:@"image/png"];
//[formData appendPartWithFileURL:fileUrl name:@"file"fileName:@"Image7.png" mimeType:@"image/png" error:nil];
//[formData appendPartWithFileURL:fileUrl name:@"file" error:nil];
} progress:^(NSProgress * _Nonnull uploadProgress) {
// progress 进度回调;
//uploadProgress.completedUnitCount:已经上传的数据大小
//uploadProgress.totalUnitCount:数据的总大小
NSLog(@"%f", 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"POST UP Succeed!");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"POST UP Failed");
}];
在其中用到了将图片转化为NSData类型并拼接上去,关于转化的方法:
UIImage *image = [UIImage imageNamed:@"IMAGE.png"];
NSData *imageData = UIImagePNGRepresentation(image);
将数据拼接的方法:
第一个参数:要上传的文件二进制数据
第二个参数:文件参数对应的参数名称,此处为file是该台服务器规定的
第三个参数:该文件上传到服务后以什么名称保存
第四个参数:该文件的MIMeType类型
[formData appendPartWithFileData:data name:@"file" fileName:@"Image.png" mimeType:@"application/octet-stream"];
第一个参数:要上传的文件的URL路径
第二个参数:文件参数对应的参数名称,此处为file是该台服务器规定的
第三个参数:该文件上传到服务后以什么名称保存
第四个参数:该文件的MIMeType类型
第五个参数:错误信息,传地址
[formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"Image.png" mimeType:@"application/octet-stream" error:nil];
第一个参数:要上传的文件的URL路径
第二个参数:文件参数对应的参数名称,此处为file
第三个参数:错误信息
[formData appendPartWithFileURL:fileUrl name:@"file" error:nil];