HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

闲鱼如何解决 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:043345

评论 1 条评论

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

VideoProc Converter 4K for mac(一站式视频处理软件) v6.5中文版

Mac相关知识分享

Mac软件 视频处理软件

国际化战略:京东商品详情API的全球视野

技术冰糖葫芦

api 货币化 API 接口 API 文档 API 测试

从零到一:用Go语言构建你的第一个Web服务

快乐非自愿限量之名

Go 前端 Web goland

简单设计一个JAVA并行处理工具类

快乐非自愿限量之名

Java

给我5分钟,保证教会你在vue3中动态加载远程组件

EquatorCoco

Vue 动态加载

打卡智能中国(八):“水花消失术”的AI秘籍

脑极体

AI

Java RMI技术详解与案例分析

不在线第一只蜗牛

Java

数据复盘“黑色星期一”:加密市场震荡,代币表现如何?

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

WiFi 7 IPQ5332 vs. WiFi 6 IPQ6010: A Comprehensive Comparison

wifi6-yiyi

WiFi7

AI 点燃体育热情!使用 PAI-Artlab 定制专属海报

阿里云大数据AI技术

人工智能 奥运会 AIGC 文生图 PAI

c#12 实验特性Interceptor如何使用的一个简单但完整的示例

EquatorCoco

C# 开发语言

重磅!观测云荣获SOC 2 Type II鉴证报告

观测云

安全合规

源码低成本开发体育直播平台:实施和控制营销活动策略探讨

软件开发-梦幻运营部

腾讯云 ES 之日志分析新范式:10 倍性价比提升!基于 ES Serverless 完成审计日志溯源

腾讯云大数据

ES

从一个服务预热不生效问题谈微服务无损上线

阿里巴巴云原生

阿里云 微服务 云原生

Spring Boot 基于 SCRAM 认证集成 Kafka 的详解

不在线第一只蜗牛

kafka Spring Boot

通义灵码代码大模型应用实践访谈

阿里巴巴云原生

阿里云 云原生 通义灵码

免费一站式搭建企业云上数据库与BI 数据可视化分析平台

XxinQi

构建数据中台,引领零售业数字化转型的最佳实践

数造万象

数据中台 零售 数字化 数据智能 实践案例

天翼云HBlock有奖众测活动 在线邀请存储Geek玩转轻量存储

InfoQ写作社区官方

热门活动 礼品 活动推荐 天翼云

防盗、防泄露、防篡改,我们把 ZooKeeper 的这种认证模式玩明白了

阿里巴巴云原生

阿里云 微服务 云原生

通义灵码代码大模型应用实践访谈

阿里云云效

阿里云 云原生 通义灵码

私网环境下如何使用云效流水线进行 CI/CD?

阿里巴巴云原生

阿里云 云原生 云效

如何用 CocosCreator 对接抖音小游戏的侧边栏复访

北桥苏

小游戏 小游戏开发 CocosCreator

千行万业的数智化,将在全闪普惠的土壤上开出新花

Alter

JavaScript 字符串方法,让开发者生活更轻松

伤感汤姆布利柏

私网环境下如何使用云效流水线进行 CI/CD?

阿里云云效

阿里云 云原生 云效

代理IP如何助力品牌保护?

IPIDEA全球HTTP

品牌 代理IP

广汽集团与火山引擎签署战略合作协议

新消费日报

未来已来:阿里巴巴商品搜索API返回值的智能化展望

技术冰糖葫芦

api 货币化 API 接口 API 文档 API 测试

Golang 策略设计模式

俞凡

架构 设计模式

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