【iOS】使用一个单例通过AFNetworking来实现网络请求
文章目录
前言
笔者这周主要学习了第三方库AFNetworking的使用,这里笔者简单介绍一下有关于AFNetworking这个第三方库的使用,在这之前我们先重新复习一下有关OC网络请求的内容。
OC网络请求的流程
在暑假的天气预报项目中笔者简单使用了有关网络请求的内容:
- 创建请求地址
- 创建请求类
- 创建会话
- 根据会话创建任务
- 启动任务
网络请求主要分为上面五个步骤,下面笔者就直接给出代码:
objc
//创建请求地址,笔者这里是传入了一个城市的一个strId,这样才可以构成一个完整的请求地址。
NSString* urlString = [NSString stringWithFormat: @"https://geoapi.qweather.com/v2/city/lookup?location=%@&key=2211750bdc834763ba3c5f57ce98c307", self.search.text];
NSURL *url = [NSURL URLWithString:urlString];
//创建请求类
NSURLRequest* request = [NSURLRequest requestWithURL:url];//通过URL创建一个网络请求类
//创建会话
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//根据会话创建任务。
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"error = %@", error.localizedDescription);
} else {
[self.locationArray removeAllObjects];
NSDictionary* second = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSMutableArray* timeAry = [[NSMutableArray alloc] init];
timeAry = second[@"location"];
//NSLog(@"%@", timeAry);
NSLog(@"geo");
for (NSDictionary* current in timeAry) {
[self.locationArray addObject:current];
}
}
}];
//启动任务
[dataTask resume];
详情可以看笔者的这篇博客暑假第三周任务------天气预报,在本篇博客中笔者主要介绍一下有关于我们第三方库的使用,以及采用单例来实现网络请求。
使用单例的原因
在暑假的天气预报项目中间,每个页面都要去实现网络请求,所以我们会在每个页面都创建对象,这里在实际开发中浪费了很多内存,假设我们采用一个单例来统一申请网络请求,就可以节省内存,这就是在申请网络请求的时候采用单例模式的原因之一。其次,我们完成一个项目,而我们将网络请求的内容全部放在单例这个类中,可以让这个项目更加利于我们维护,提高代码的可维护性。
创建一个单例
在之前的学习中,我们学习过单例模式的创建,这里我们就需要用到这部分知识。
objc
static Manger *mangerSington = nil;
@implementation Manger
+ (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];
}
这里采用的单例创建,是我们之前学习的内容,这里就不多赘述了,主要就是static dispatch_once_t onceToken;:
这是用于确保代码块只执行一次的GCD的dispatch_once_t
变量。从而保证在多线程情况下保证了创建只会执行一次。
采用AFNetworking的网络申请
一般我们的项目采用MVC架构,所以我们申请一个对应的网络请求,需要返回一个model,也就是我们从网络上获取到的JSON数据,我们一般获取到的数据存储在model层,然后这里我们需要一个block,将我们通过网络请求获取到的JSON数据传输给页面用于加载数据。
objc
//在.h文件中,定义给block命名:typedef void(^successBlock)(testModel* testModel);
- (void) NetWorkWithData:(successBlock)success andError:(errorBlock)myerror {
AFHTTPSessionManager* manger = [AFHTTPSessionManager manager];
NSString* str = @"https://news-at.zhihu.com/api/4/version/ios/2.3.0";
[manger GET:str parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
testModel* model = [testModel yy_modelWithJSON:responseObject];
success(model);//给页面部分返回该页面需要的model。
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
myerror(error);
}];
}
这里是我们首先我们这里先解释一下有关GET方法请求数据的几个参数:
- 第一个参数是存放我们的URL,也就是我们的网络请求的地址。
- 第二个参数则是我们要发送的请求的查询数据,在get请求中我们一般放在URL中间,这里注意下在POST请求,我们需要使用一个字典来进行一个请求。
- 第三个参数则是header,在大部分请求中我们是不需要的,但是在部分要求比较严格的API中,可能就需要运用到这个参数
- 第四个参数是一个可以选择的块,一般用于大文件的下载中
- success则是请求成功后回调块,failure则是请求失败后的回调块
这里的responseObject一般情况下是responseObject
将是一个 Objective-C 对象,通常是一个 NSDictionary
或 NSArray
,取决于 JSON 的结构。
这里我们定义两个我们通过网络请求申请到的数据放在block中,将里面的内容传递到对应的页面。
objc
typedef void(^successBlock)(NSDictionary* tokenModel);
typedef void(^myError)(NSError* error);
在viewController中进行网络请求,这样就可以获得我们所需要的内容。
objc
- (void)viewDidLoad {
[super viewDidLoad];
id manger = [Manger sharedSingleton];
[manger NetWorkWithData:^(testModel * _Nonnull testModel) {
NSLog(@"%@", [testModel yy_modelToJSONString]);
} andError:^(NSError * _Nonnull error) {
NSLog(@"error:%@", error);
}];
// Do any additional setup after loading the view.
}
打印结果:
objc
{"msg":"【更新内容】\r\n\r\n★ 多图有标记 流量壕忽略\r\n★ 出门前离线 没网也能看\r\n★ 喜欢请好评 不喜快吐槽\r\n★ 萌妹工程师 邮箱在下面\r\nmua@zhihu.com\r\n(一般人我们不告诉他)","stauts":0,"latest":"2.5"}
Type: Notice | Timestamp: 2024-10-19 23:00:47.244886+08:00 | Process: test2 | Library: test2 | TID: 0x147365d
小结
这里笔者简单的介绍了有关AFN这个第三方库的使用,以及使用一个单例来封装网络请求,从而提高代码的内聚性,便于后期的代码维护。