牛叉的demoIos@IONICiOS高级开发

iOS 基于MVVM + RAC + ViewModel-Bas

2017-11-01  本文已影响6264人  CoderMikeHe
前言
代码结构
  1. 结构

    CodeStructure.png
  2. 说明

    • Model :存放数据-模型(data-model),例如:MHUser.
    • View:存放功能模块自定义的View。例如:MHMainFrameTableViewCell.
    • ViewController:存放功能模块的是视图控制器。例如:MHMainFrameViewController.
    • ViewModel:存放功能模块的是视图对应的视图模型。例如:MHMainFrameViewModel.
    • Utils:存放工具类和管理类。例如:分类Category,网络服务层MHHTTPService,管理类MHFileManager...
    • Vendor:存放第三方框架。例如:MJRefresh...
    • Macros:存放常量。例如:宏(#define)定义常量,const常量,枚举(NS_ENUM)常量,inline函数,URL路径常量。
    • Resource:存放资源文件,例如:图片,DataSQL文件。
  3. 细节

    • 代码结构完全按照MVVM来设计命名,实际上MVVMV应该包括视图控制器(ViewController)视图(View),这里只是将其单独分开,以便于更好的阅读和开发。
    • 必须强调文件夹的命名,这里笔者是按照主功能模块来命名,相信大家可以很清楚的看到 ViewViewControllerViewModel三个文件夹里面的子模块文件夹都是一样的。而后期若在设计子文件夹的时候,参照这种方式来创建文件夹,那么大家会发现,你的代码目录会非常非常的整齐漂亮,同时方便后期维护和其他开发人员阅读代码,何乐而不为呢。
    • 同时强调一下自定义的视图控制器和视图模型的命名,理论上,一个视图控制器配备一个视图模型,所以笔者这里只是将视图控制的名字的ViewController替换成ViewModel即为配备的视图模型的名字:例如:视图控制器的名字为MHMainFrameViewController,则视图模型的名字为MHMainFrameViewModel。这样整个项目开发下来,你会发现ViewControllerViewModel文件下的文件都是对称的。
    • 目录层级不能超过三层。因为层级越深,越不易查找,且不易阅读。这里就以我的(Profile)为例,我的(Profile)界面有一个用户信息(UserInfo)子模块,用户信息(UserInfo)里面有一个更多(MoreInfo)子模块,更多(MoreInfo)模块当然也有子模块等等。如果这样划分,必然会导致目录结构很深,所以为了避免其发生,就尽量限制在三层即可,正所谓事不过三嘛,所谓三层目录可想而知,就是ViewController - Profile - UserInfo这三层便是,那么我们就可将更多(MoreInfo)模块与用户信息(UserInfo)并列即可,当然你也可以将更多(MoreInfo)模块的写在用户信息(UserInfo)里面,但是只创建文件,而不创建文件夹。只要保证不超过三层目录即可。即如下图所示:
ProfileCodeStructure.png
第三方框架

第三方框架想必对与小伙伴在熟悉不过了,其作用简而言之就是:辅助。让我们更专注于产品的业务逻辑开发,而不是某个功能点开发。这里简单介绍一下此次搭建微信(WeChat)基本架构中主要用到的第三方框架。目的希望能够让大家学习更多更好用的轮子,以及结合自身项目的实际情况集成进去,减少不必要的开发。更多详见Demo的Podfile文件。

BaseClass

本项目中采用的是继承的方式来设计的,所以BaseClass的存在在所难免,但是它在项目中的作用是举足轻重的,简直神一样的存在。笔者这里主要详述ModelViewControllerViewModel中的BaseClass,而View中的BaseClass无非是实际项目中开发者自定义的功能View,方便后期要使用只需继承该功能View就可以了,减少了开发中的冗余代码。比如:笔者项目中的MHButton是继承于UIButton,而其作用只是去掉了按钮的高亮状态- (void)setHighlighted:(BOOL)highlighted {},以及MHImageView是继承于UIImageView,而其作用只是增加了允许用户的交互self.userInteractionEnabled = YES;。这里主要解析的各个是BaseClass的头文件的属性和方法,以及各自的使用场景和注意点。基类主要文件如下:

MHObject:所有数据模型的基类。
MHViewModel/MHViewController:所有自定义视图控制器的基类,以及配备的视图模型。
MHTableViewModel/MHTableViewController:所有需要显示UITableView的自定义视图控制器的基类,以及配备的视图模型。
MHWebViewModel/MHWebViewController:所有需要显示WKWebView的自定义视图控制器的基类,以及配备的视图模型。
MHTabBarViewModel/MHTabBarController:需要展示UITabBarController的自定义视图控制器,以及配备的视图模型。
Q&A

Q:项目中若同时集成 YYCategoriesReactiveCocoa,使用@weakify(self)@strongify(self);将会报Ambiguous expansion of macro weakifyAmbiguous expansion of macro strongify的警告。

weakify&strongify警告.png

A:由于 YYCategoriesReactiveCocoa都定义了weakifystrongify引起的。解决办法如下:

weakify&strongify警告解决.png

知识点:怎样去除Xcode中的警告️


Q:Xcode 9.0上,ReactiveCocoa(2.5)Unknown warning group '-Wreceiver-is-weak', ignored的警告。

Wreceiver-is-weak警告.png

A:RACObserve定义如下:

#define RACObserve(TARGET, KEYPATH) \
    ({ \
        _Pragma("clang diagnostic push") \
        _Pragma("clang diagnostic ignored \"-Wreceiver-is-weak\"") \
        __weak id target_ = (TARGET); \
        [target_ rac_valuesForKeyPath:@keypath(TARGET, KEYPATH) observer:self]; \
        _Pragma("clang diagnostic pop") \
    })

在之前的Xcode中如果消息接受者是一个weak对象,clang编译器会报receiver-is-weak警告,所以加了这段push&pop,最新(iOS 11)的clang已经把这个警告给移除,所以没必要加push&pop了。
解决办法:修改Podfile文件,将 pod 'ReactiveCocoa' ,'2.5' 改成如下

pod 'ReactiveCocoa', :git => 'https://github.com/zhao0/ReactiveCocoa.git', :tag => '2.5.2'

该方法原文参照:简书App适配iOS 11


Q:在Xcode 9.0上报 error: Illegal Configuration: Safe Area Layout Guide before iOS 9.0错误。

SafeAreaLayoutGuide.png

A:SafeArea的概念是在iOS 9.0以后才支持,所以只需要设置项目支持的版本:设置Deployment TargetiOS Deployment Target9.0以上即可。

SafeAreaLayoutGuide解决①.png SafeAreaLayoutGuide解决②.png
总结

本篇主要介绍了笔者在使用MVVM + RAC + ViewModel-Based Navigation来搭建微信基本架构过程中的一点见解,其更深次的实践还需要各位小伙伴去自行体会,建议结合笔者文末提供的Demo以及雷纯锋大神开源的MVVMReactiveCocoa来实践。
当然实践过程如人饮水,冷暖自知,多多重复,百炼成钢。希望小伙伴通过阅读这篇文章,能对MVVM + RAC + ViewModel-Based Navigation的使用有一定基本的了解和使用,不一定要求完全去掌握它,这仅仅是我们众多开发模式的一个参考罢了,最主要的还是编程思想细节处理。显然你也可以将其运用到MVC设计模式中去,比如代码规范文件目录BaseClass等等。使得MVVM真正做到从群众(MVC)中来,到群众(MVC)中去。
或许还有许多细小逻辑和细小Bug需要我们去优化和处理,当然这便是此篇文章的存在的意义:集众人之智,成众人之事

未完...待续...(PS:点关注,不迷路,笔者带你上高速)

考虑到文章篇幅过长影响阅读性,讲述其中技术的拓展性和全面性。笔者在接下来的时间内,会陆续将在开发WeChat中的好用的技术以及细节处理分享出来,希望提供大家一个参考,并且可以运用到自己的实际的项目中去。主要是关于以下几个问题的解释和分析,还请小伙伴移步续篇👉iOS 基于MVVM + RAC + ViewModel-Based Navigation的微信开发(二)

期待
  1. 文章若对您有些许帮助,请给个喜欢❤️,毕竟码字不易;若对您没啥帮助,请给点建议💗,切记学无止境。
  2. 针对文章所述内容,阅读期间任何疑问;请在文章底部评论指出,我会火速解决和修正问题。
  3. GitHub地址:https://github.com/CoderMikeHe
  4. 源码地址:WeChat
参考链接
上一篇下一篇

猜你喜欢

热点阅读