解耦-用RAC处理网络请求

2018-04-16  本文已影响28人  oldSix_Zhu

最近接手的项目中使用了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调用请求方法,不用再复制粘贴一遍了

上一篇 下一篇

猜你喜欢

热点阅读