iOS组件化

1. 组件化介绍

在一个项目越来越大,开发人员越来越多的情况下,项目会遇到很多问题。

  • 业务模块间划分不清晰,模块之间耦合度很大,非常难维护。
  • 所有模块代码都编写在一个项目中,测试某个模块或功能,需要编译运行整个项目。

为了解决这些问题,就需要用到组件化。组件化的作用如下:

  • 模块间解耦
  • 模块重用
  • 提高团队协作开发效率
  • 单元测试

并不是所有的项目都需要组件化,如果:

  • 项目较小,模块间交互简单,耦合少
  • 模块没有被多个外部模块引用,只是一个单独的小模块
  • 模块不需要重用,代码也很少被修改
  • 团队规模很小

那么这些项目就不需要组件化。

组件化最重要的部分就是颗粒度的划分,划分的越精准,组件化的效果就越好。组件化颗粒度的划分不是越小越好,颗粒度太小会增加通讯的成本。
一般来说组件化分层分为三层:

  • 业务模块
  • 通用模块
  • 基础模块

这里一般从基础模块开始构建,然后构建通用模块,最后构建业务模块。
在这里插入图片描述
组件化需要注意以下几点:

  • 只能上层对下层依赖
  • 项目公共代码资源下沉
  • 横向的依赖 最好下沉

2. CocoaPods

平时我们是如何把远程代码拉到本地的呢?这里需要一个东西去找到远程代码——CocoaPods。这里以AFN为例,可以在CocoaPods找到AFN的文件,然后找到对应版本的json,并通过里面的信息来获得AFN
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
流程图:
在这里插入图片描述

3. 组件化操作

3.1 创建模块

Terminal中打开指定文件夹后输入 pod lib create 文件名生成一个模块, 创建好后会自动打开一个工程。
在这里插入图片描述
接下来打开这个模块,在这个模块的classes里面开始编写代码。

在这里插入图片描述
写好代码后,在进行一次pod install 操作,这样就可以看到之前创建的模块了。
在这里插入图片描述

3.2 第三方库和其他模块

如果文件依赖一些第三方库,那么就需要为其配置。
在这里插入图片描述
然后重新pod install
在这里插入图片描述
基础库也是一样的,但是需要在Podfile里面为其指定路径。
在这里插入图片描述
在这里插入图片描述

3.3 获取模块资源文件

如果需要用到其他模块的资源文件,那么就会找不到。那么要怎么做呢?
在这里插入图片描述
首先把要用到的图片放在对应模块的Assets里面。
在这里插入图片描述
然后在podspec里面添加resource_bundles后重新 pod install
在这里插入图片描述
然后就可以获取到相应的bundle获取图片。
在这里插入图片描述
获取json文件也是一样的。这里可以看到如果是正常的mainBundle获取就会有问题。
在这里插入图片描述
根据相应的bundle来获取json文件的话就没事了。
在这里插入图片描述

3.4 模块通讯

模块通讯三种方式:

  • url路由
  • target-action
  • protocol匹配
url 路由

目前iOS上大部分路由工具都是基于URL匹配的,或者是根据命名约定,用runtime方法进行动态调用

这些动态化的方案的优点是实现简单,缺点是需要维护字符串表,或者依赖于命名约定,无法在编译时暴露出所有问题,需要在运行时才能发现错误。

URL路由方式主要是以蘑菇街为代表的的 MGJRouter

其实现思路是:

  • App启动时实例化各组件模块,然后这些组件向ModuleManager注册Url,有些时候不需要实例化,使用class注册

  • 当组件A需要调用组件B时,向ModuleManager传递URL,参数跟随URL以GET方式传递,类似openURL。然后由ModuleManager负责调度组件B,最后完成任务。

// 1、注册某个URL
MGJRouter.registerURLPattern("app://home") { (info) in
    print("info: \(info)")
}

//2、调用路由
MGJRouter.openURL("app://home")

URL 路由的优点

  • 极高的动态性,适合经常开展运营活动的app,例如电商
  • 方便地统一管理多平台的路由规则
  • 易于适配URL Scheme

URl 路由的缺点

  • 传参方式有限,并且无法利用编译器进行参数类型检查,因此所有的参数都是通过字符串转换而来
  • 只适用于界面模块,不适用于通用模块
  • 参数的格式不明确,是个灵活的 dictionary,也需要有个地方可以查参数格式。
  • 不支持storyboard
  • 依赖于字符串硬编码,难以管理,蘑菇街做了个后台专门管理。
  • 无法保证所使用的的模块一定存在
  • 解耦能力有限,url 的”注册”、”实现”、”使用”必须用相同的字符规则,一旦任何一方做出修改都会导致其他方的代码失效,并且重构难度大
target-action

这个方案是基于OC的runtime、category特性动态获取模块,例如通过NSClassFromString获取类并创建实例,通过performSelector + NSInvocation动态调用方法

其主要的代表框架是casatwy的 CTMediator

其实现思路是:

  • 利用分类为路由添加新接口,在接口中通过字符串获取对应的类
  • 通过runtime创建实例,动态调用实例的方法
//******* 1、分类定义新接口
extension CTMediator{
   
    @objc func A_showHome()->UIViewController?{
   
        let params = [
            kCTMediatorParamsKeySwiftTargetModuleName: "CJLBase_Example"
        ]
        
        if let vc = self.performTarget("A", action: "Extension_HomeViewController", params: params, shouldCacheTarget: false) as? UIViewController{
   
            return vc
        }
        return nil
    }
}

//******* 2、模块提供者提供target-action的调用方式(对外需要加上public关键字)
class Target_A: NSObject {
   
    
    @objc func Action_Extension_HomeViewController(_ params: 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值