最近接手的项目中使用了RAC,也研究学习了下,发现使用RAC确实清晰便利了许多,下面记录一下用RAC处理网络请求实现解耦
首先看一下项目层次,除了MVC之外,每个小模块都有一个Manager层来管理所有的网络请求,当然,如果你的项目是MVVM的话,可以直接放到ViewModel层里面.
比如说我们有一个"我"这个模块,里面有一个TableView,是我的朋友的列表,对应朋友信息Model,然后我们在进入这个页面的时候请求一次服务器,拿到所有朋友信息.
在请求的时候,我们一般会调用自己二次封装AFHTTPSessionManager的AFN请求管理类,里面有我们的一些基本配置之类的,然后拼接URL,加上参数就调用了.
但是这里面有一个问题,当你的项目越来越大,你请求的URL会遍布整个项目,每个Controller中都会有好几个URL,好几个参数,当这些东西在后面维护中要变化的时候,维护起来就乱了很多.
所以我们给每个模块都设置一个网络管理层,是NetworkManager也好,是ViewModel也好,都是这个作用.
下面看两种请求的例子:
#import <Foundation/Foundation.h>
#import <ReactiveObjC/ReactiveObjC.h>
#import "NetworkTool.h"
#import "FriendModel.h"
@interface MeNetworkManager : NSObject
/// 获取所有朋友列表
+ (RACSignal *)getAllFriends;
/// 添加朋友
+ (RACSignal *)addFriendWithPersonID:(NSInteger)personID;
@end
#import "MeNetworkManager.h"
@implementation MeNetworkManager
/// 获取所有朋友列表
+ (RACSignal *)getAllFriends {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[[NetworkTool sharedInstance] requestWithPath:@"url" requestType:@"get" requestParamter:nil responseObjctClass:[FriendModel class] completionBlock:^(BOOL isSuccess, id object, NSError *error) {
if (isSuccess) {
[subscriber sendNext:object];
[subscriber sendCompleted];
} else {
[subscriber sendError:error];
}
}];
return nil;
}];
}
/// 添加朋友
+ (RACSignal *)addFriendWithPersonID:(NSInteger)personID {
NSMutableDictionary *paramter = [NSMutableDictionary dictionary];
[paramter setObject:@(personID) forKey:@"personID"];
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[[NetworkTool sharedInstance] requestWithPath:@"url" requestType:@"post" requestParamter:paramter responseObjctClass:nil completionBlock:^(BOOL isSuccess, id object, NSError *error) {
if (isSuccess) {
[subscriber sendNext:nil];
[subscriber sendCompleted];
} else {
[subscriber sendError:error];
}
}];
return nil;
}];
}
@end
其中,NetworkTool是二次封装AFN网络请求类,其中方法每个人都有不同写法.总之最后把请求成功接收到的数据转Model后把对象sendNext出去就好;如果没有数据返回,就判断是否成功,然后sendNext个nil就好
在Controller里面,我们引用这个模块的网络管理者,然后调用即可
#import "MeViewController.h"
#import "MeNetworkManager.h"
@interface MeViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic, strong) UITableView *friendsTableView; /**< 朋友列表 */
@property (nonatomic, strong) NSArray *friends; /**< 数据源 */
@end
@implementation MeViewController
- (void)viewDidLoad {
[super viewDidLoad];
//加载动画 loading...
[self getData];
}
- (void)getData {
@weakify(self)
[[MeNetworkManager getAllFriends] subscribeNext:^(id _Nullable x) {
@strongify(self)
//加载动画loading...消失
//拿到数据,更新数据源,刷新tableView(可调用MJRefresh等...)
FriendModel *friendModel = (FriendModel *)x;
if (friendModel.friends.count > 0) {
self.friends = friendModel.friends;
[self.friendsTableView reloadData];
}
} error:^(NSError * _Nullable error) {
//失败处理
}];
}
@end
多了一层的好处是每层的职责单一,相互直接依赖降低了(就是解耦),容易拓展功能和后期的维护,如果更改了接口的话,可以直接去NetworkManager中更改,不用再去Controller中全局搜索更改了,更加清晰,达到集中管理请求的目的;
而且当业务需求增加了,其他Controller也需要调用这个接口的时候,可以直接引用这个NetworkManager调用请求方法,不用再复制粘贴一遍了
网友评论