App架構升級之網絡層優化(二)

一、回顧

在上一篇中,我們著重介紹了如何將現有的網絡庫進行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+SevenFreshDDNetWorkManger+TaskFlowDDNetWorkManger+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中實現對網絡請求信號的訂閱。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容