美文网首页
解耦-用RAC处理网络请求

解耦-用RAC处理网络请求

作者: oldSix_Zhu | 来源:发表于2018-04-16 15:42 被阅读28次

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

    相关文章

      网友评论

          本文标题:解耦-用RAC处理网络请求

          本文链接:https://www.haomeiwen.com/subject/ncadvxtx.html