一个Swift工具类App的设计

从开始接触iOS开发,几乎都是自己在从零开始搭建一个App,每一次都有较大的收获,都会比上一次好一点。业务的复杂度不一样,对架构设计的考验也不一样,框架也会随着功能模块的不断增加,用户量的不断增加,一点点成长。(好像说了段废话😅)这是一款Swift开发的万年历App,大致描述了一下当初的结构设计。以后再从头搭建App或是重构也都来记录一下,毕竟岁数越来越大了,总要留点过往思考的回忆😄。

项目的整体概括

这是一个万年历App,大体上采用MVVM架构,用ReactiveSwift进行模块之间的交互响应。数据存储用CoreData,JSON到Model的映射使用Argo,网络请求用的Alamofire。使用Carthage进行第三方库的集成。

项目的结构图

项目中每个Group中放置的内容

  • Application: 整个App一些通用的配置,基本上是一些struct的常量定义。
  • Communication: 网络请求基础模块部分,如果有新的接口,在Urls中加上定义,新的请求要实现RequestProtocol
  • CoreDataStore: 对CoreData封装的基础模块部分,对ManagedObject的操作封装在Managed中。
  • Extensions: 对FoundationUIKit扩展的一些工具方法,特别地,像图片、StoryBoard等资源文件的名称都定义在相应的extension中,这样在后面资源文件变动时要更改一些。
  • Managers: CalendarManager是对每个网络接口的请求过程和对结果的处理,MemoryCacheManager是对日历模块上的数据的缓存。谨慎定义Manager类,能分散到其他模块就分散到其他模块去。
  • ThirdParty: 手动集成代码的第三方库,其余第三方库通过Carthage集成。
  • Models: App的数据模型和每个请求接口的Request。注意,这些Model都是struct定义的,在使用CoreData的项目中实际上是有ManagedObject可用于模块之间的数据交互的,但为了便于json的解析,其他地方的方便使用,以及struct本身的一些优势,所以对ManagedObject的使用只停留在对db的操作上。在每个Model中会封装对db的操作,以及与ManagedObject之间的转换。在xcdatamodel中定义Entity时,要将Class Name指定为Managed+ModelName。
  • Views: 各模块的视图,UIViewController也放置在这里。
  • ViewModels: 各模块的视图模型。
  • Utils: 包括日期计算、黄历计算等工具类。
  • Resources: App中用到的一些资源文件集合。
  • Tests: 放了一些在调试用的test case。

最后说一下Actions、State、Stores:

这几个模块之间相互配合,是对Delta这个库的使用。Delta主要对App的State进行管理,
这里的State指的是App在运行过程中的一些数据的State的。Actions放的就是对这些数据的改变,所有的改变都集中在Action中,这样使得整个App在运行过程中数据的变化变得非常明了。任何地方都可以对State进行监听,在变化时做出响应。本App中State中定义了主界面需要常驻内存中的数据,在从数据库中加载后和从服务器拉取到时,对其进行更改。放在内存中避免了业务逻辑操作中多次对db的读取,用Delta使得对这些数据的管理方便集中。

后续可优化点

  • ViewModel部分可以考虑定义相应的Protocol,这样便于在单元测试中打桩。
  • 想使模块更加清晰话,可以用Framework进行管理。