开发者社区> 1111665173305875> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

优酷iOS工程插件化 -- 大量模块壳工程本地如何快速编译

简介: 业务快速发展,优酷工程已有大量模块,模块耦合严重且混乱,模块依赖是一颗“树”,甚至于一张“网” ,导致开发体验持续严重下降,如何解决本地调试效率低、不支持模拟器、模块整包依赖不一致等等痛点问题,文中进行了说明。
+关注继续查看

背景

随着优酷业务的快速发展,随之而来的是模块数量的爆发式增长,基本每年以大量新增模块的速度增加,到目前为止优酷已经有非常庞大的模块依赖。模块之间通信往往是相互直接依赖调用,以至于耦合十分严重且混乱,每一个库依赖都是一颗“树”,甚至于一张“网”,对日常研发造成很多困扰:

image


插件化落地结果

iOS模块插件化已经全面在优酷落地,沉淀出各业务线的轻量工程,大量的业务及架构插件,后续可根据不同业务需求,自由组装插件工程。以下是目前插件化工程落地后的一些收益:

  • 直接收益
    • 业务插件工程编译效率提升 显著,本地编译时间大幅降低,相关全部开发已使用起来。
    • 通过插件组装生成业务插件工程,插件工程支持模拟器编译调试,并支持热重载。
    • 模块工程和整包工程均使用插件作为依赖,彻底解决模块工程和整包工程依赖模块版本不一致情况,并支持依赖模块版本自动更新。
    • 业务插件工程依赖库数量大幅减少,且pod直接复用缓存,大幅提升pod成功率及速度,磁盘占用大幅减少
  • 间接收益
    • 可提供运行内存、app启动、功耗等插件卡口,常态化保持良好的用户体验
    • 所有插件支持自由组装,通过配置中心,提供快速孵化极速版、国际版、Apple Watch、Apple TV等App的能力。
    • 依赖减少,swift断点调试时的module树快速生成,断点效率提升。
    • 提速打包效率,建立插件工程构建平台,测试同学使用平台动态配置生成插件组合安装包即可进行测试。

插件是什么

  • 插件是由一组模块聚合而成,同时也可依赖其他插件。在物理上,插件是一个文本描述文件,描述其包含的模块和插件信息。
  • 插件基于Xcode工程,可独立编译并生成App产物,支持多插件自由组合。


简单插件

一个简单的插件可以仅由一个模块组成。

# 图片库插件

target 'Plugin' do   

    #模块A

    pod '模块A','5.9.4' 

end

复杂插件

一个复杂插件可以由一个或多个插件和模块组成。

# 插件

target 'Plugin' do

   # 图片库插件

    plug '1.图片库插件'

  

    #webp图片解析模块

    pod '模块B','0.1.4' 

    #webp基础模块

    pod '模块C','1.1.0.1' 

end

为什么需要插件

和多个业务团队同学沟通后,我们发现大部分的业务在功能调试时,往往只关注涉及到自己需要迭代的业务功能,对于其他业务并不关心。于是我们想到可以基于整包工程,裁剪出一个只有单业务功能的APP,这样编译速度肯定会有极大的提升。

裁剪APP需要对模块进行解耦,如果按模块颗粒度进行解耦,巨量模块进行解耦人力成本过高,而且过大的改动也会对线上稳定性有较大的影响。于是我们对解耦粒度进行了放大,从模块解耦粒度放大到以插件为粒度进行解耦,这样我们只需要解耦插件和插件之间的横向耦合关系,插件允许向下依赖其他插件,且插件内部模块也允许相互耦合,这样极大的的降低解耦的人力成本,也方便后续以插件维度进行依赖关系进行维护。

image

插件使用规范

插件聚合原则

  • 业务插件:业务模块按业务功能维度划分边界,聚合成业务插件。
  • 通用业务插件:通用业务模块按业务可复用最小集划分边界,聚合成通用业务插件。
  • 架构功能插件:集团中间件模块、优酷中间件模块,按功能最小集划分边界,聚合成架构功能插件。

插件依赖原则

  • 业务插件不允许横向依赖其他业务插件,允许依赖下层插件。
  • 架构层插件不允许依赖上层插件,允许依赖下层插件及其他架构插件。

image

模块归属原则

  • 一个模块仅能归属到一个插件,需要明确模块的职能
  • 同一个模块被多个插件依赖,需要考虑下沉该模块为插件
  • 一个模块可以写成一个插件

插件版本原则

  • 每个插件没有版本的概念
  • 一个集成区的模块和版本对应一套插件中的模块和版本
  • 一套插件中的模块和版本默认和线上版本的集成区一致,也可设置并同步到最新集成区或历史集成区

插件层级大图

基于以上插件的概念和使用规范,我们对优酷APP架构进行插件化改造,从集团中间件到业务层,自下而上解耦聚合模块形成插件,最终沉淀了大量插件和如下层级的APP架构。

image

  • 业务实现层:对优酷现有的业务进行插件化改造,聚合成多个通用业务插件,通过业务插件和其依赖的通用业务插件、架构功能插件等少量插件,能快速组合出一个轻量级业务APP,用于提升业务Pod速度和开发调试速度。
  • 业务接口层:对优酷现有的业务进行横向解耦,形成多个业务接口插件,支撑上层业务插件横向解耦。
  • 通用业务插件:通用业务模块按业务可复用最小集划分边界,聚合成通用业务插件。
  • 架构功能插件:集团中间件模块、优酷中间件模块,按功能最小集划分边界,聚合成架构功能插件。


低成本管控方案

优酷所有模块已经完成插件化改造,为了保障在后续版本迭代过程中,防止工程腐化,制定了一套低成本管控方案,可以自动更新插件内容,管控插件依赖关系。

插件自动更新

插件内容主要包括模块名称和模块版本号,每次版本迭代,插件都面临插件中模块的新增、删除、名称变更、版本变更等问题,优酷每个版本集成大量的模块,如果全部人工手动维护,成本将非常巨大,所以我们部署了一套自动同步及巡检服务,主要有以下目的:

  • 插件中新增、删除模块自动更新;
  • 插件中的模块版本号自动变更;
  • 插件内容更新完成自动对所有插件进行编译巡检;
  • 如果巡查通过,插件合并到插件工程集成分支提供给业务插件工程使用;
  • 如果巡查失败,钉钉通知失败信息(失败插件名称、编译失败日志链接、插件新增模块提示)到钉钉群,方便快速排查问题。

image


插件依赖管控

我们基于插件的归属和层级,抽象出标准的模块依赖关系数据,然后在模块构建打包时,增加依赖检测卡口,在每次模块构建过程中,执行依赖检测卡口,只有通过依赖检测的插件才能打包通过。

image

结果数据呈现

构建提效

业务插件工程本地编译效率对比整包工程:

  • 本地编译效率得到极大的提升,平均提效显著本地编译时间大幅降低,相关全部开发已使用起来。

计算公式:

  • 编译提效公式:本地编译提效 = (整包工程构建时长 - 业务插件工程构建时长) / 整包工程构建时长
  • 节约时间公式: 每月节约编译时间(8小时工作日) = 插件工程月编译次数 * 平均单次编译节约时间(秒) / (60 * 60 * 8)

image

模拟器支持

优酷存在部分模块不支持模拟器,导致优酷整包不支持模拟器,插件化改造后,业务在通过插件组装自己业务调试工程的时候,剔除这部分不支持模拟器的插件,使得业务插件工程可以使用模拟器进行调试。模拟器优势:

  • 一个企业号真机调试限制100台设备,而模拟器无限制。
  • 模拟器支持所有iOS系统,针对一些旧系统开发和测试成本低。
  • 模拟器支持热重载,无需编译和重新运行,修改代码保存即生效。
  • 提前适配iOS新机型UI。

工程名称

模拟器支持

热重载支持

优酷整包工程

image

image

业务插件工程

image

image


磁盘占用

在模块插件化改造前,我们只能使用整包工程进行开发,使用整包工程进行日常开发的时候,需要将所有模块下载,而插件化改造完成后,我们从整包工程拆分出了多个业务插件工程,插件工程的模块数量相比整包工程大幅减少,插件工程的磁盘占用相比整包工程大幅减少。下图是整包工程和部分业务插件工程磁盘大小对比:

image



内存占用

插件化可提供运行内存、app启动、功耗等插件卡口,常态化保持良好的用户体验,以播放页的运行内存为例,播放页有播放器、页面容器、弹幕、评论等功能,以前是对整个播放页计算内存值,而现在可以按照细碎的功能来计算内存值,分别得到播放器插件、播放页容器插件、弹幕插件、评论插件的内存值。


结语

综上所述,iOS工程插件化是运用分而治之的思想,把一个复杂的App分成多个子App。通过子App可将研发聚焦于需求研发和用户体验提升上。同时,插件化的拆装特性也提高了线上可复现问题的排查效率。因此插件化对研发效率以及开发幸福感的提升都是非常有帮助的。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
iOS开发UI篇—CAlayer(创建图层)
iOS开发UI篇—CAlayer(创建图层) 一、添加一个图层 添加图层的步骤: 1.创建layer 2.设置layer的属性(设置了颜色,bounds才能显示出来) 3.将layer添加到界面上(控制器view的layer上)  1 // 2 // YYViewController.
738 0
iOS开发UI篇—CAlayer层的属性
iOS开发UI篇—CAlayer层的属性 一、position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property CGPoint position; 用来设置CALayer在父层中的位置 以父层的左上角...
830 0
iOS开发UI篇—CAlayer(自定义layer)
iOS开发UI篇—CAlayer(自定义layer) 一、第一种方式 1.简单说明 以前想要在view中画东西,需要自定义view,创建一个类与之关联,让这个类继承自UIView,然后重写它的DrawRect:方法,然后在该方法中画图。
801 0
iOS开发UI篇—核心动画简介
iOS开发UI篇—核心动画简介 一、简单介绍 Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。
884 0
iOS开发UI篇—核心动画(基础动画)
iOS开发UI篇—核心动画(基础动画) 一、简单介绍 CAPropertyAnimation的子类 属性解析: fromValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue 如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。
610 0
iOS开发UI篇—核心动画(关键帧动画)
iOS开发UI篇—核心动画(关键帧动画) 一、简单介绍 是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值 属性解析: values:就是上述的NSArray对象。
662 0
iOS开发UI篇—核心动画(转场动画和组动画)
iOS开发UI篇—核心动画(转场动画和组动画) 一、转场动画简单介绍 CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点 UINavigationController就是通过CATransition实现了将控制器...
584 0
iOS开发UI篇—CAlayer简介
iOS开发UI篇—CALayer简介   一、简单介绍 在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView。
654 0
iOS开发UI篇—Quartz2D使用(信纸条纹)
iOS开发UI篇—Quartz2D使用(信纸条纹) 一、前导程序 新建一个项目,在主控制器文件中实现以下几行代码,就能轻松的完成图片在视图中的平铺。 1 #import "YYViewController.
655 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
聚划算iOS平台动态化方案LuaView
立即下载
React-Native 在iOS上的性能优化方案
立即下载
移动 App 性能监测实践(iOS篇)
立即下载