zoukankan      html  css  js  c++  java
  • 浅谈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;
    }
  • 相关阅读:
    OnContextMenu事件
    wireshark教程
    常见的算法题:逆行单一列表
    GPIO
    USB OTG简要
    软测验点---平衡二叉树
    SSL工作原理
    CFileDialog 使用简单介绍
    eclipse在maven项目交付svn忽略简介
    四个漂亮CSS样式表
  • 原文地址:https://www.cnblogs.com/fengmin/p/6185539.html
Copyright © 2011-2022 走看看