使用RAC也有一段時間了,由于此前的項目都是使用的MVC模式媳瞪,網(wǎng)絡(luò)請求都封裝在固定的模塊中抑片,抽取出來十分不方便,所以到目前為止并沒有涉及到使用RAC去做獲取網(wǎng)絡(luò)請求的情景硫惕。
近期茧痕,著手重構(gòu)目前手上的項目,準備給臃腫的Controller瘦身恼除,MVVM貌似是一個不錯的選擇(既然使用了RAC踪旷,那為什么不使用MVVM呢?)。于是豁辉,開始上手體驗MVVM模式和RAC的結(jié)合使用(RAC的基礎(chǔ)知識在這就不介紹了令野,百度一下,一大推老司機都有分享)徽级。不用不知道气破,一用才發(fā)現(xiàn)RAC和MVVM簡直是絕配啊,那體驗真是改變了我對編程的傳統(tǒng)觀念(函數(shù)響應(yīng)式編程真心好用)餐抢。
這里用一個小demo來舉例:
進入頁面加載數(shù)據(jù)顯示现使。這里使用我當前項目中的一個接口來模擬數(shù)據(jù)。既然是MVVM旷痕,那Model和ViewModel肯定是少不了的碳锈。如下:我們新建一個ViewModel叫LoadStoreViewModel(因為這里是加載商店數(shù)據(jù)),傳統(tǒng)的MVC模式中,網(wǎng)絡(luò)請求都是在ViewController中完成的欺抗,這里我們把網(wǎng)絡(luò)請求封裝到對應(yīng)的ViewModel中去殴胧,能夠有效的減少ViewController的負擔,降低耦合性。
LoadStoreViewModel主要有三個屬性:statues(網(wǎng)絡(luò)加載狀態(tài))团滥,code1(編號)竿屹,以及保存數(shù)據(jù)的數(shù)組dataArry,還有一個加載數(shù)據(jù)信號loadDataSignal灸姊;
初始化loadDataSignal:(主要進行網(wǎng)絡(luò)請求)
//
- (RACSignal *)loadDataSignal{
if (_loadDataSignal==nil) {
AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManager manager];
manager.requestSerializer=[[AFJSONRequestSerializer alloc]init];
NSDictionary *params=@{@"code1":@"MWG08A09"};
_loadDataSignal=[manager rac_GET:kLoadURL parameters:params];
}
return _loadDataSignal;
}
調(diào)用loadDataSignal處理網(wǎng)絡(luò)請求結(jié)果:
-(void)initWithSubscrible{
[[self.loadDataSignal deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(RACTuple *jsonDataResult) {
//請求成功拱燃,加載數(shù)據(jù)
NSDictionary *tuple=[jsonDataResult objectAtIndex:0];
NSArray *resultList=tuple[@"resultList"];
if (resultList.count>0) {
self.dataArray=[[[resultList.rac_sequence
map:^id(NSDictionary *dataSource) {
NSDictionary *dic=[(NSDictionary *)dataSource mutableCopy];
WGStoreModel *model=[WGStoreModel mj_objectWithKeyValues:dic];
return model;
}] array] mutableCopy];
}
}];
//請求失敗
[self.loadDataSignal subscribeError:^(NSError *error) {
self.statues=@"沒有網(wǎng)絡(luò),哈哈";
}];
}
ViewModel的操作完成力惯,接下來要在Controller中綁定ViewModel
綁定ViewModel碗誉,初始化,然后監(jiān)聽ViewModel中的網(wǎng)絡(luò)請求狀態(tài)父晶,獲得ViewMode中網(wǎng)絡(luò)請求結(jié)果哮缺,在Controller中給出相應(yīng)的提示,數(shù)據(jù)加載成功甲喝,顯示數(shù)據(jù)刷新控件:
-(void)bindViewModel{
@weakify(self);
self.storeViewModel=[[LoadStoreViewModel alloc]init];
self.isLoading=YES;
self.code1=kCode1;
RAC(self.storeViewModel,code1)=RACObserve(self, code1);
//加載狀態(tài)
[RACObserve(self, isLoading) subscribeNext:^(id x) {
UIApplication.sharedApplication.networkActivityIndicatorVisible = [x boolValue];
}];
//加載網(wǎng)絡(luò)數(shù)據(jù)成功
[[[RACObserve(self.storeViewModel, dataArray) ignore:nil] doNext:^(id x) {
self.isLoading=YES;
}] subscribeNext:^(id x) {
@strongify(self);
self.isLoading=NO;
//刷新控件--
[self.tableView reloadData];
}];
//加載網(wǎng)絡(luò)數(shù)據(jù)失敗
[[RACObserve(self.storeViewModel, statues) filter:^BOOL(id value) {
//filter是過濾
return value !=nil;
}] subscribeNext:^(NSString *str) {
UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"提示" message:str delegate:self cancelButtonTitle:@"confirm" otherButtonTitles:nil, nil];
[alertView show];
}];
}
ViewController中初始化TableView尝苇;
- (UITableView *)tableView{
if (!_tableView) {
_tableView=[[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain];
_tableView.delegate=self;
_tableView.dataSource=self;
_tableView.showsVerticalScrollIndicator=NO;
_tableView.rowHeight=49;
}
return _tableView;
}
tableView的數(shù)據(jù)源和協(xié)議方法實現(xiàn)
#pragma mark -tableView DataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.storeViewModel.dataArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *indefier=@"CELL";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:indefier];
if (!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indefier];;
}
WGStoreModel *model=self.storeViewModel.dataArray[indexPath.row];
cell.textLabel.text=model.shopName;
return cell;
}
無demo不文章,為了更好的理解本篇文章埠胖,請到我的github下載對應(yīng)的demo糠溜,一運行探究竟(https://github.com/voidxin/ReactiveCocoaRequestData)
謝謝。