iOS学习
- 前言
- 原生网络请求
- 使用AFNetworking库进行网络请求
- 具体使用
- 单例创建的原因
- 单例使用
- 总结
前言
我们之前学习了通过OC原生内容进行网络申请,AFNetworkikng第三方库的使用,可以极大地简化网络申请的代码量。
原生网络请求
网络请求主要分为上面五个步骤,下面直接给出代码:
- 创建请求地址
- 创建请求类
- 创建会话
- 根据会话创建任务
- 启动任务
-(void)creatURL
{
//创建请求地址
NSString *urlString1 = [NSString stringWithFormat:@"https://devapi.qweather.com/v7/weather/3d?location=%@&key=你的key",self.array_city[self.flag]];
urlString1 = [urlString1 stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *url1 = [NSURL URLWithString:urlString1];
//创建请求类
NSURLRequest *request1 = [NSURLRequest requestWithURL:url1];
NSURLSessionConfiguration *config1 = [NSURLSessionConfiguration defaultSessionConfiguration];
//创建会话
NSURLSession *session1 = [NSURLSession sessionWithConfiguration:config1 delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//根据会话创建任务
NSURLSessionTask *task1 = [session1 dataTaskWithRequest:request1];
self.datatask01 = task1;
//启动任务
[task1 resume];
}
//接受服务器响应
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
NSLog(@"didReceiveResponse");
if(dataTask == self.datatask01) {
if (self.data1 == nil) {
self.data1 = [[NSMutableData alloc] init];
} else {
self.data1.length = 0;
}
}
//允许数据接受
completionHandler(NSURLSessionResponseAllow);
}
//接收到数据,该方法会被调用多次
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
NSLog(@"didReceiveData");
if (dataTask == self.datatask01) {
[self.data1 appendData:data];
}
}
//数据请求完成或者请求出现错误调用的方法
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"didCompleteWithError");
// 在 URLSession:task:didCompleteWithError: 方法中
if (task == self.datatask01) {
if (error == nil) {
NSMutableDictionary *dictBianYi = [NSJSONSerialization JSONObjectWithData:self.data1 options:kNilOptions error:nil];
NSMutableArray *arrValue = [[NSMutableArray alloc] init];
arrValue = dictBianYi[@"daily"];
[self.arrWeNeed addObjectsFromArray:arrValue];
} else {
NSLog(@"errol = %@",error);
}
}
}
使用AFNetworking库进行网络请求
相比于我们自己实现网络请求,使用AFNetworking让网络请求更简便
我们并不需要自己操作NSURL
、NSURLRequest
、NSURLSession
,也不需要实现Task
回调、调用resume
我们只需要实现下面一段代码即可:
- 第一个参数是存放我们的URL,也就是网络请求的地址。
- 第二个参数则是我们要发送的请求的查询数据,在get请求中我们一般放在URL中间,这里注意下在POST请求,我们需要使用一个字典来进行一个请求。
- 第三个参数则是header,在大部分请求中我们是不需要的,但是在部分要求比较严格的API中,可能就需要运用到这个参数
- 第四个参数是一个可以选择的块,一般用于大文件的下载中
- success则是请求成功后回调块,failure则是请求失败后的回调块
具体使用
GET请求为例:
- (void)dataLoader {
[[AFHTTPSessionManager manager] GET:@"https:/news-at.zhihu.com/api/4/story-extra/9776246" parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {
//
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error:%@",error);
}];
}
单例创建的原因
通常在一个项目中,我们需要多次进行网络申请。当我们在不同页面都创建对象时,会额外耗费很多内存。因此通过一个单例统一实现网络申请,可以节省内存空间,减少代码量便于维护。
单例使用
@implementation Manger
static Manger *mangerSington = nil;
+ (instancetype)sharedSingleton {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mangerSington = [[super allocWithZone:NULL] init];
});
return mangerSington;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [Manger sharedSingleton];
}
- (id)copyWithZone:(NSZone *)zone {
return [Manger sharedSingleton];
}
- (void)NetWorkWithData:(void(^)(Model *testModel))success andError:(void(^)(NSError *error))failure {
AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
NSString* str = @"https:/news-at.zhihu.com/api/4/story-extra/9776246";
[manager GET:str parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
Model* model = [Model yy_modelWithJSON:responseObject];
success(model);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error);
}];
}
使用GCD加锁保证线程安全。
在ViewController中,我们调用该单例模式
#import "ViewController.h"
#import "Manger.h"
#import "Model.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
id manger = [Manger sharedSingleton];
[manger NetWorkWithData:^(Model *testModel) {
NSLog(@"%@", [Model yy_modelToJSONString]);
} andError:^(NSError *error) {
NSLog(@"error:%@", error);
}];
}
@end
打印结果:
总结
AFNetworking作为一个高效的第三方库,简化了网络申请的代码量。使用起来十分便捷。