首页 > 代码库 > 浅谈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转化之后的数据itemviewModel保存,与数据相关的处理都将在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的架构设计