一、回顧
在上一篇中,我們著重介紹了如何將現有的網絡庫進行RAC封裝。這篇將講解具體的使用。先從ViewModelServices說起。
二、DDViewModelServices
目前,app業務層的整體架構如上圖所示。在ViewModel和ViewModel之間傳遞了DDViewModelServicesImpl(實現了DDViewModelServices協議的)對象。如:
STTaskDetailViewModel *viewModel = [[STTaskDetailViewModel alloc] initWithServices:self.services params:@{}];
[self.services pushViewModel:viewModel animated:YES];
由上圖可以看出,所有網絡相關的調用都是在ViewModel中進行的,ViewModel負責數據的獲取以及處理。那么我們給DDViewModelServices增加一個property。
@protocol DDViewModelServices <NSObject, DDNavigationProtocol>
@property (nonatomic, strong) DDNetWorkManger *client;
@end
然后在app打開之后,初始化首頁的時候,給實現了DDViewModelServices協議的DDViewModelServicesImpl對象,初始化網絡管理對象client。這樣,在ViewModel和ViewModel之間push或者present的時候,就可以把對應的client進行傳遞了:
// 初始化client
DDNetWorkManger *client = [DDNetWorkManger defaultManger];
// 這個client通過services在ViewModel之間傳遞。
DDSharedAppDelegate.services.client = client;
OrderListViewModel *viewModel = [[OrderListViewModel alloc] initWithServices:DDSharedAppDelegate.services params:nil];
其中DDSharedAppDelegate是一個宏。
#define DDSharedAppDelegate ((AppDelegate *)([UIApplication sharedApplication].delegate))
AppDelegate保持了一個DDViewModelServicesImpl,所有后續ViewModel的services都是從這里傳遞的。
AppDelegate.h
@interface AppDelegate : DDAppDelegate
@property (nonatomic, strong, readonly) DDViewModelServicesImpl *services;
...
@end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
self.services = [[DDViewModelServicesImpl alloc] init];
...
return YES;
}
到這里,清楚了網絡請求發生的層級,以及client對象是如何傳遞的。那么,我們下一步要結合DDNetWorkManger+RAC
來進行不同業務模塊的網絡請求信號封裝。
三、DDNetWorkManger擴展
其中DDNetWorkManger+RAC
是網絡庫的RAC封裝。DDNetWorkManger+SevenFresh
、DDNetWorkManger+TaskFlow
、DDNetWorkManger+MyTask
都是和具體業務有關的網絡庫擴展,分別為7-fresh、訂單流程、我的任務業務模塊。當然,隨著業務的發展,可以一直增加對應的DDNetWorkManger
業務擴展。每個業務擴展里面只封裝與該業務相關的網絡層請求:
DDNetWorkManger+TaskFlow.h
@interface DDNetWorkManger (TaskFlow)
...
// 根據類型,獲取任務列表。
- (RACSignal *)signal_requestTaskListWithType:(NSNumber *)type;
// 請求派單數據。
- (RACSignal *)signal_requestRecommendTaskWithIdentifier:(NSString *)taskID;
...
@end
DDNetWorkManger+TaskFlow.m
@implementation DDNetWorkManger (TaskFlow)
...
#pragma mark -
- (RACSignal *)signal_requestTaskListWithType:(NSNumber *)type
{
...
DDRequestInfo *request = [DDRequestInfo xxxxxx];
return [[self enqueueRequest:request method:DDHTTPMethodGET resultClass:[DDAPIResult class]] dd_parsedResults];
}
- (RACSignal *)signal_requestRecommendTaskWithIdentifier:(NSString *)taskID
{
...
DDRequestInfo *request = [DDRequestInfo xxxxx];
return [[self enqueueRequest:request method:DDHTTPMethodGET resultClass:[DDAPIResult class]] dd_parsedResults];
}
...
@end
到這里,我們就將不同業務對應的網絡層請求,借助DDNetWorkManger+RAC
封裝成了信號。
四、訂閱網絡層信號
我們給ViewModelServices增加了網絡層DDNetWorkManger
類型的Client
。然后,將實現這個Services協議的DDViewModelServicesImpl類型的對象services在ViewModel之間傳遞。然后通過這個services.client訂閱DDNetWorkManger
對應的業務擴展中的信號。
STTaskFlowViewModel.h
@interface STTaskFlowViewModel : DDTableViewModel
...
// 任務列表
@property (nonatomic, strong, readonly) RACCommand *requestTaskListCommand;
...
@end
STTaskFlowViewModel.m
- (RACCommand *)requestTaskListCommand
{
if (!_requestTaskListCommand)
{
WSELF;
_requestTaskListCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSNumber *type) {
SSELF;
return [self.services.client signal_requestTaskListWithType:type];
}];
}
return _requestTaskListCommand;
}
然后在需要獲取數據的地方如下調用即可:
[[self.requestTaskListCommand.executionSignals.switchToLatest map:^id _Nullable(id _Nullable value) {
...
return value;
}] subscribeNext:^(DDAPIResult *result) {
...
}];
五、總結
首先創建DDNetWorkManger
的相應業務擴展,并將DDNetWorkManger+RAC
包含進來。
然后在擴展中封裝網絡請求的信號。
再在ViewModel中實現對網絡請求信號的訂閱。