MVVM + RxSwift

. MVVM + RxSwift + CTMediatror + MJRefresh + DZNEmptyDataSet

基于 MVVM + RxSwift架构图怎么画建响应式数据绑定基础架构

CatHome

  • 资源模块,主要处理架构图片资源和文本资源读取

    • 读取图片资源:R.image("base_black_back")
    • 读取文本资源:R.t架构图怎么画ext("base_empty_timvvm数据双向绑定原理tle")
    • 读取颜色资源:R.color("background")

    MVVM响应式基础架构送给你,要不要?

BeeBox

  • 主要收集RxSwift相关好用方法类等

Adapter

  • 该模块主要就是封装基类
    • BaseViewController: 支持oc基类swift是什么组织缩写,公共部分
    • VMTableViewController: 列表基类, 内部采用响应式处理
    • VMViewController: 该基类继承时需指定ViewModel或其子类作为架构师证书泛型,该类会自动懒加载指定类型的VM对象。
    • ViewModel: 基础模型,子类必须继承枸杞使用
      • 关于子类,这边目前都采用协议的方式去设计修改,需要什么就导入什么协议即可。

例如:

  • 引入上拉和下拉刷新功能
只需要遵循这两个协议即可 - ViewModelHeaderable, ViewModelFooterable
  • 引入空数据展示功能
只需要遵循空数据协议 - ViewModelEmptiable

CTMediatror

  • 该模块主要解决Swift采用该组件化方案Cocswift翻译oaPods问题
extension CTMediator {
    /// Swift调度者
  func Second_viewController(title: String) -> (UIViewController?) {
        let params = [
      "title": title,
      kCTMediatorParamsKeySwiftTargetModuleName: "Rickenbacker_Example"
    ] as [AnyHashable : Any]
    let viewController = self.performTarget(String(describing: SecondViewController.self),
                        action: "Extension_ViewController",
                        params: params,
                        shouldCacheTarget: false) as? UIViewController
    return (viewController)
  }
}
class Target_SecondViewController: NSObject {
  /// 备注提示,这里必须加上`@objc`
  /// 否则会出现找不到该方法从而导致控制器为`nil`问题
  @objc func Action_Extension_ViewController(_ params: NSDictionary) -> UIViewController? {
    guard let title = params["title"] as? String else { return nil }
    let vc = SecondViewController.init()
    vc.viewModel = SecondViewModel.init(title: title)
    return vc
  }
}

HBswift系统DNavigationBar

  • 该模块是基于HBDNavigationBar二次封装底层基础导航栏

MJRefresh

该模块是基于MJRefresh封装列表刷新功能

  • 注入下拉刷新功能,只需要简单的swift代码实现Vimvvm和mvc的区别ewModelHeaderable协议即可
  • 注入上拉加载更多功能,只需要简单的实现ViewModelFoot前端mvvmerable协议即可

测试用例:

extension MJRefreshViewModel: ViewModelHeaderable, ViewModelFooterable {
  var enterBeginRefresh: Bool {
    return false
  }
  // 自动无感上拉刷新功能
  var footer: MJRefreshFooter {
    let footer = MJRefreshAutoFooter()
    footer.triggerAutomaticallyRefreshPercent = -5
    return footer
  }
}

备注提示:当然这边你也可以根据你的需求来自定义headerfooter

final class MJRefreshViewModel: ViewModel {
  struct Input {
    let headerRefresh: Observable<Void>
    let footerRefresh: Observable<Void>
  }
  struct Output {
    let items: Driver<[String]>
  }
}
extension MJRefreshViewModel: ViewModelType {
  func transform(input: Input) -> Output {
    var objects: [String] = []
    var page: Int = 1
   
    /// 下拉刷新
    let refresh = input.headerRefresh.then(page = 1)
      .flatMapLatest {
        MJRefreshAPI.refresh(page).request()
      }.map { [unowned self] (items) -> [String] in
        refreshSubject.onNext(.endHeaderRefresh)
        objects = items
        return objects
      }.asDriver(onErrorJustReturn: [])
   
    /// 上拉加载更多
    let more = input.footerRefresh.then(page += 1)
      .flatMapLatest {
        MJRefreshAPI.refresh(page).request()
      }.map { [unowned self] (items) -> [String] in
        if items.isEmpty {
                   refreshSubject.onNext(.endFooterRefreshWithNoData)
        } else {
          refreshSubject.onNext(.endFooterRefresh)
        }
        objects += items
        return objects
      }.asDriver(onErrorJustReturn: [])
        /// 数据响应    
    let items = Driver.of(refresh, more).merge()
    /// 空数据绑定
    items.map { $0.isEmpty }.asObservable().bind(to: isEmptyData).disposed(by: disposeBag)
    return Output(items: items)
  }
}

DZNEmmvvm框架ptyDataSetSwift

该模块是基于EmptyDataSet-Swswifterift封装列表空数据展示功能

  • 注入空数据展示功能,只需要简单的实mvvm的理解Vi工资超过5000怎么扣税ewModelEmpt架构师证书iable协议

测试用例:

class EmptyViewModel: ViewModel, ViewModelEmptiable, ViewModelHeaderable {
  let dataSource: BehaviorRelay<[String]> = BehaviorRelay(value: [])
  func loadData() {
    let driver = NetworkService().randomResult().asObservable()
    driver.bind(to: dataSource).disposed(by: disposeBag)
    driver.map { $0.isEmpty }.bind(to: isEmptyData).disposed(by: disposeBag)
    driver.subscribe { _ in } onCompleted: {
      self.refreshSubject.onNext(.endHeaderRefresh)
    }.disposed(by: disposeBag)
  }
}
let driver = NetworkService().randomResult().asObservable()
driver.map { $0.isEmpty }.bind(to: isEmptyData).disposed(by: disposeBag)

这边目前也支持自定义UI展示配置

/// 配置空数据展示信息
extension DZNEmptyDataSetViewController: EmptyDataSetViewable {
  func setupEmptyView(_ view: EmptyDataSetView) {
    view.titleLabelString(NSAttributedString(string: R.text("TEXT")))
    view.detailLabelString(NSAttributedString(string: R.text("测试网络异常展示")))
    view.image(R.image("base_network_error_black"))
    view.verticalOffset(-200)
  }
}

CocoaPods IGonstall

目前暂时包含如下七大模块:

  • 导入项目响应式基类模块:pod 'Rickenbacker/Adapter'
  • 导入资源模块:pod 'Rickenbacker/CatHome'
  • 导入收集模块:pod 'Ricmvvm与mvckenbacker/BeeBox'
  • 导入组件化模块:podmvvm框架 'Rickenbacker/CTMedmvvm原理iatrswift国际结算系统or'
  • 导入导航栏基础模块:pod 'Rickenba工商银行cker/HBDNavigationBar'
  • 导入swift翻译自动刷新模块:pod 'Rickenbacker/MJRefswift代码resh'
  • 导入空数据自动展示模块:pod 'Rickenbacswift系统ker/DZNEmptyDataSet'

觉得有帮助的老哥们,请帮忙点个星 ⭐..

救救孩子吧,谢谢各位老板。

最后

  • 附上传送Rickenbackermvvm的理解Demo 地址.
  • 再附上一个开发加速库KJCategoriesDemo地址喜欢的老板们可以点个星
  • 最后再附上一个好玩的滤镜框架,有需要的朋友也可以去玩玩,Harbeth

✌️.