AICon议程上新60%,阿里国际、360智脑、科大讯飞、蔚来汽车分享大模型探索与实践 了解详情
写点什么

闲鱼如何解决 iOS 环境搭建与 APP 打包速度问题

  • 2020-08-13
  • 本文字数:3329 字

    阅读完需:约 11 分钟

闲鱼如何解决iOS环境搭建与APP打包速度问题

随着 Flutter 等跨端框架的出现,业务开发同学经常需要在 Android/IOS 上跨端进行业务开发,问题定位等。新的不熟悉的环境的搭建总会遇到各种各样的问题,导致搭建失败,特别是 IOS 开发环境,是最复杂的,不仅环境搭建繁琐,而且切分支后的打包速度很慢,所以我们设计实现了两个工具,用于优化闲鱼 IOS 开发体验。

IOS 开发体验存在的问题

开发环境搭建难

  • 开发环境依赖特定软件版本,配置复杂


闲鱼 IOS 工程不仅依赖 XCode,还依赖了 taobaoenv 1.2.0 和 cocoapods 1.2.0 这两个包管理工具。根据大家的经验,这两个工具在 ruby2.3.x 时,问题较少。特定软件版本,系统自带软件版本冲突,环境变量设置等等一些列的操作步骤导致环境搭建复杂,需要求助 IOS 开发同学才能搞定。


  • 维护难


Mac 系统升级后,cocoapod 容易出现问题,不得不重新搭建开发环境。具体原因也是多种多样:系统环境变量变了,导致找不到特定版本 ruby;ruby 随系统升级导致 cocoapod 不能用,需要重新安装;Gem 版本问题;Ruby 源问题等等。这也导致许多开发同学不敢轻易的去升级系统,无法及时体验到新系统的特性。


  • Pod 依赖下载量大


由于 cocoapod 本身的工作原理,pod 更新下载工程依赖时,会下载各个版本的文件信息,总量特别大。以闲鱼 IOS 工程为例,总共需要下载近 20G 的缓存文件,而且大部分都是几 K 的小文件,下载时间可能会持续十几个小时,导致新环境搭建到初次体验时间跨度非常久。

切分后 APP 打包慢

当开发同学在多个分支/版本开发的时候,时常需要切换分支开发调试和 bugfix。但是切换分支之后,整个 IOS 工程打包时间在 30-40 分钟左右。有时候为了修复一个版本的 bug,不得不切换分支,然后重新打包调试。修复和验证 bug 可能只需要五分钟,打包却用了 30 多分钟,投入产出不成比例。


为了解决这些存在的问题,我们进行了一些列的探索,跟大家一起分享下,也欢迎有更好的解决方案出现。

IOS 环境搭建

虚拟化技术的不断发展,为我们统一端侧开发环境提供了新思路,我们设想如果 IOS 开发环境能够跟 Mac 解耦,且可以移植,大家可以轻松复用,那么第一二个问题就迎刃而解了。为此我们做了几个尝试:

虚拟机方案

在 MacOS 本地搭建虚拟机,内装 MacOS 系统。在虚拟机内搭建 IOS 开发环境,然后通过虚拟机镜像 copy 实现 IOS 开发环境移植,解决环境搭建难题。



这个方案存在以下几个问题:


a. 性能问题,IOS 的编译过程是一个 IO 密集型和 CPU 密集型操作,虚拟机通过虚拟 HOST 系统的磁盘和 CPU,性能会大打折扣,导致编译时间变长,影响开发体验。


b. 安全问题。在 Mac 工作机安装虚拟机,需要通过公司安全审核。


c. 黑苹果问题:虚拟机内的 Mac 系统是没有经过授权的,会带来盗版侵权风险。


虚拟机是比较重的虚拟化技术,因此我们转向了更加轻量化的 docker 技术。

完全 Docker 化

将 IOS 开发依赖的软件和环境变量全部 docker 化。通过 docker 镜像实现 IOS 开发环境的移植。对于 cocoapod, taobaoenv 等 ruby 类工具,鉴于 ruby 的跨平台特性,可以很方便的迁移到 docker 内。但是对于强依赖 MacOS 的 XCode,我们尝试用 Facebook 出品的 xcbuild 替代。这是一款兼容 xcodebuild 的编译工具,网上也确实有网友用这个软件搭建 IOS 编译环境。



这个方案存在以下几个问题:


a. Xcbuild 跟 Xcodebuild 的兼容性无法评估


b. xcode 升级后,xcbuild 跟进升级兼容的一段时间内,只能回退到原来的开发方案,来回切换开发环境,体验差。


上面两个方案都没有很好的解决 IOS 开发环境移植和解耦的问题,但是在完全 docker 化的尝试中,我们发现最复杂的 cocoapod 和 ruby 安装配置部分是能够 docker 化的,xcode 安装后并不需要特殊的配置,因此我们设计实现了一个折中方案:Host 内开发(部分 docker 化)

Host 内开发(部分 docker 化)

本方案中:开发编译调试工作仍然在 MacOS 本地,使用 xcode; 而将 cocoapod 和 taobaoenv 相关的软件和环境变量配置等 docker 化。这样既遵循了开发同学一贯的开发体验,又兼顾了开发环境的可移植问题。



为了能够让 Docker 内 cocoapod 拉取的依赖文件和生成的 pod 工程能被本地的 XCode 识别,我们将本地 pod 缓存目录挂载到 docker,这样 Pod 拉取的依赖既能在 docker 内更新,也能在 MacOS 中被 XCode 访问,具体如下图(统一编程平面端+Faas 软件架构图):



这样既做到了简化开发环境搭建的复杂度,方便了想尝试 IOS 开发的同学快速搭建环境,还能给开发同学无差别体验。而且通过这个方案,我们的 IOS 开发环境可以方便的在各个同学的开发环境中迁移,而且也可以统一进行升级改造。


本方案将 Pod 相关的依赖迁移到了 Docker 中,与 MacOS 解耦,因此 IOS 开发同学可以自由升级 Mac 系统,不用担心开发环境被破坏,解决了维护难的问题。


为了解决新搭建的环境需要大量拉取 pod 依赖的问题,我们将 pod 的本地中间文件上传到 OSS 云盘(上图蓝色 OSS 云盘),开发同学只需要一次性下载压缩包并解压到本地,然后增量更新就可以了。

切分支后 APP 打包速度问题

客户端开发同学经常需要在多个分支(版本)上面开发业务,且时常需要来回切换进行业务开发和问题定位。这带来的一个问题是:当开发同学从 A 分支切换到 B 分支的时候,需要重新打包 APP,整个过程大概需要 30-40 分钟左右。


在分析了闲鱼 IOS 工程打包过程后,我们将耗时锁定在两个阶段:Pod 操作和 XCode 编译。打包速度优化也将分为两个阶段进行:

Pod 操作加速

Pod install/update 主要的工作是读取 Podfile,进行依赖版本控制和冲突解决,并生成 Pod 工程。生成的相关文件存储在 Pods 目录和 Pods.xcodeproj 中。当切换回之前分支时,Podfile 经常是不会发生变化的,因此重新生成 pod 工程实属浪费。


经过测试,如果我们将这些中间文件保存起来,多次切换分支后,这些中间文件仍然能够还原之前的 Pod 工程,从而避免切分支后重新生成 Pod 工程的步骤,省去 10 分钟左右的开销。

XCode 编译速度优化

对于 XCode 编译速度优化,网上有很多方案,大致可以分为三类:


  • Cocopods 依赖编译加速


比如 cocoapods-packager,它可以将 pod 依赖打包成 static library,IOS 工程以静态库的形式引入 pod 依赖,省去重复编译的时间。


但是这个方案也存在一些问题;私有库和第三方库更新很麻烦,每次都需要重新打包静态库,并上传到代码仓库;且很难调试源码


  • 分布式编译:比如 distcc


分布式编译的原理是将需要编译的文件分散到编译集群的其他机器上编译,然后将编译好的二进制文件传回。本地编译器再将这些二进制文件链接在一起。分布式编译对于大工程提速明显,但是对于小工程,反而会拖累编译速度。


  • 缓存编译的中间结果:CCache,BUCK


更为广泛的加速方案是缓存编译的中间结果,比如 CCache,Buck 等,这些方案,网上有详细的资料,不再一一赘述。但是引入这些方案,都需要对目前的 IOS 工程进行改造,甚至需要改变用户的开发习惯,因此不符合我们的要求。但是缓存中间编译结果的方案给我们提供了一些启发:


我们知道 XCode 是具有增量编译能力的,这其实也是利用了上一次编译的中间产物,本地再次编译的时候,如果发现文件没有变化,则忽略这个文件,如果源码文件时间戳更新了,那么就重新编译这个文件,因为每次变化的源码都是少量的,这样就可以达到加快编译速度的目的。


对于闲鱼 IOS 工程,如果我们在切分支之前保存当前 IOS 分支编译的中间产物,然后在切换回当前分支的时候,恢复之前保存的中间产物,那么是不是就可以触发 XCode 增量编译了呢?事实确实如此。



具体方案:


  1. 在切分之前缓存当前分支的 Pods Project, Flutter Project 以及编译的中间产物,Podfile.lock, linkmap 等等相关文件。

  2. 切换分支

  3. 恢复新分支之前缓存的中间产物

  4. 重新打包 IOS APP。


通过这两步优化,我们将闲鱼 IOS 工程切分支后的打包时间由原来的 30-40 分钟降低到五分钟以内,效率提升近六倍。

总结

IOS 环境搭建中复杂和耗时的步骤,通过 docker 镜像和缓存优化后,搭建的难度大大降低,IOS 新手也基本可以在三小时内搞定



同时,通过缓存和复用打包过程产生的中间产物,切换分支后的打包耗时控制在五分钟内,降低为原来的六分之一,提升了开发效率。


本文转载自公众号闲鱼技术(ID:XYtech_Alibaba)。


原文链接


https://mp.weixin.qq.com/s/R2XYOczL4-qftewWM7VKNg


2020-08-13 10:043322

评论 1 条评论

发布
用户头像
IOS还是好好写成iOS吧,名称还是要规范的
2020-08-13 12:43
回复
没有更多了
发现更多内容

极客时间运维进阶训练营第十二周作业

Starry

非侵入式入侵 —— Web缓存污染与请求走私

vivo互联网技术

CDN

开源的未来:启动 Open100

开源雨林

社区 开源软件 商业化

DockQuery | 基于E-R图的数据建模功能使用实践

BinTools图尔兹

数据建模 信创 #数据库

URule规则引擎

规则引擎 java

真的有那么丝滑吗?面试阿里(Java岗)从投简历到面试再到入职

做梦都在改BUG

Java java面试 Java八股文 Java面试题 Java面试八股文

【网络安全必备知识】本地提权漏洞分析

网络安全学海

黑客 网络安全 信息安全 渗透测试 漏洞挖掘

京东小程序CI工具实践

京东科技开发者

小程序 ci 开发 代码 企业号 3 月 PK 榜

Blazor在IoT领域的前端实践 @.NET开发者日

MASA技术团队

.net blazor MASA MAUI

科技助力金融转型 阿里云联合中国信通院在京举办未来金融思享会

阿里云云效

DevOps 数字化转型 金融 BizDevOps 业技融合

OpenHarmony内核学习[1]--单独编译OpenHarmony标准系统内核

离北况归

OpenHarmony

一天吃透MySQL锁面试八股文

程序员大彬

MySQL 面试

Polygon马蹄链质押DApp开发合约部署案例

薇電13242772558

智能合约 dapp

从零开始搭建一个通用的业务技术架构,这套架构 有点牛逼!

程序知音

Java 程序员 编程语言 后端

使用Assembly打包和部署Spring Boot工程

做梦都在改BUG

Java spring Spring Boot assembly 框架

3D摄影棚布光工具Set A Light 3D Studio

Rose

Mac软件 Set A Light 3D Studio 3D摄影棚布光工具

OpenHarmony编译固件新增支持Ubuntu22.04平台

离北况归

OpenHarmony

OpenHarmony NAPI 类对象导出及其生命周期管理(下)

离北况归

OpenHarmony

图解Redis,谈谈Redis的持久化,RDB快照与AOF日志

小小怪下士

Java redis 程序员 后端

OpenHarmony NAPI 类对象导出及其生命周期管理(上)

离北况归

OpenHarmony

【OpenHarmony设备开发】修改屏幕 DPI(像素密度)

离北况归

OpenHarmony

如何规避MyBatis使用过程中带来的全表更新风险

京东科技开发者

数据库 mybatis 代码 代码规范 企业号 3 月 PK 榜

@所有人,优秀前端都应该具备的开发好习惯

引迈信息

前端 低代码 开发

Matlab常用图像处理命令108例(四)

timerring

图像处理

被问了n遍怎么把FB视频无水印下载到手机相册!现在双手奉上教程!

frank

facebook #Facebook

8年服务百万客户,这家SaaS公司是懂云原生的

科技热闻

助力白帽成长 百度安全2022 BSRC年度盛典圆满收官

Geek_283163

百度 #百度#

NineData x 阿里云 正式上线

NineData

数据库 阿里云 数据迁移 数据管理 NineData

企业如何构建内部开发者平台?

SEAL安全

IdP 平台工程 企业号 3 月 PK 榜 内部开发者平台

可插拔组件设计机制—SPI

京东科技开发者

spi Java】 JavaSPI 企业号 3 月 PK 榜

PyTorch深度学习实战 | 深度学习框架(PyTorch)

TiAmo

深度学习 PyTorch

闲鱼如何解决iOS环境搭建与APP打包速度问题_安全_柬超_InfoQ精选文章