首页 > 代码库 > 浅谈iOS中MVVM的架构设计
浅谈iOS中MVVM的架构设计
MVVM
就是在MVC
的基础上分离出业务处理的逻辑到viewModel
层。
M: Model层是API请求的原始数据,充当DTO(数据传输对象),当然,用字典也是可以的,编程么,要灵活一些。Model层是比较薄的一层。
V: View层,视图展示,由viewController
来控制,他的任务就是从ViewModel层获取数据,然后显示。
VM: ViewModel层负责业务处理和数据转化,就是View和Model层的粘合剂,他是一个放置用户输入验证逻辑,视图显示逻辑,发起网络请求和其他各种各样的代码的极好的地方。说白了,就是把原来ViewController层的业务逻辑和页面逻辑等剥离出来放到ViewModel层。
简单来说,就是API请求完数据,解析成model
,之后在viewModel
中转化成能够直接被视图层使用的数据,交付给前端。
model层
我们先从model层开始,在这里我们用JSONModel来解析,比如一个商品列表的model长这样:
这是我们的数据原型,API返回的数据通过JSONModel解析完成后的原始数据存在这里。
#import <JSONModel/JSONModel.h> @protocol LVMProductListModel <NSObject> @end // productList @interface LVMProductListModel : JSONModel @property (nonatomic, copy) NSString *imgUrl; @property (nonatomic, copy) NSString *productId; @property (nonatomic, copy) NSString *productName; @property (nonatomic, copy) NSString *refPrice; @end
viewModel 层
viewModel层是我们处理业务逻辑的核心层,在这里我们需要发起网络请求(如果网络请求较多,可以抽出来,只在ViewModel里调用)、解析数据、转换数据给前端。
#pragma mark - Public Methods - (void)lvm_startLoadProductListWithPage:(NSInteger)page { __weak typeof(self) weakSelf = self; [NetWorkManager GET:self.lvm_baseURL parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { __strong typeof(weakSelf) strongSelf = weakSelf; ... NSDictionary *resultDic = responseObject[@"rp_result"]; NSError *error = nil; LVMProductListModel *model = [[LVMProductListModel alloc] initWithDictionary:resultDic error:&error]; if (error) { ... } [strongSelf _lvm_calProductLists:model.productlist]; if (strangles.delegate ...) { ... } } failure:^(NSURLSessionDataTask *task, NSError *error) { ... }]; } - (void)_lvm_calProductLists:(NSArray *)productLists{ for (NSInteger i = 0; i < productLists.count; ++i) { LVMProductListModel *model = productLists[i]; LVMProductListItem *item = [[LVMProductListItem alloc] init]; item.lvm_productId = model.productId; item.lvm_productName = model.productName; item.lvm_productPrice = [NSString stringWithFormat:@"¥ %@", model.refPrice]; item.lvm_productImgURL = [Utils convertToRealUrl:model.imgUrl ofsize:300]; [self.lvm_productLists addObject:item]; } }
在viewModel
中将API返回的数据解析成model
,并将model
转化成可供view
层直接使用的item
,将item
交付给前端使用。
经过viewModel
转化之后的数据item
由viewModel
保存,与数据相关的处理都将在viewModel
中处理。viewModel
返回给view
层的接口长这样:
@interface LVMProductListViewModel (CollectionViewDataSource) - (NSInteger)lvm_numberOfItemsInSection:(NSInteger)section; - (LVMProductListItem *)lvm_itemForIndexPath:(NSIndexPath *)indexPath; @end
view层
view
层是由viewController
控制的。view
层只做展示,不做业务处理。view
层的数据由viewModel
提供。view
层看起来是这样的:
@implementation LVMProductListViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; [self _lvm_initial]; [self _lvm_setupViewModel]; [self _lvm_setupSubViews]; [self.lvm_viewModel lvm_startLoadProductListWithPage:_lvm_currentPage]; } - (void)_lvm_initial { ... self.lvm_currentPage = 1; } - (void)_lvm_setupViewModel { self.lvm_viewModel = [[LVMProductListViewModel alloc] init]; _lvm_viewModel.lvm_delegate = self; } #pragma mark - Subviews - - (void)_lvm_setupSubViews { ... [self _lvm_setupCollectionView]; ... } - (void)_lvm_setupCollectionView { ... } #pragma mark - UICollectionView Delegate & Datosource - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return [self.lvm_viewModel lvm_numberOfItemsInSection:section]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { LVMProductListItem *item = [self.lvm_viewModel lvm_itemForIndexPath:indexPath]; LVMProductListCollectionViewCell *cell = (LVMProductListCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kLVMProductListCollectionViewCellId forIndexPath:indexPath]; [cell lvm_setupWithItem:item]; return cell; }
浅谈iOS中MVVM的架构设计