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

从探索到落地,手淘引入 Swift “历险记”

  • 2020-02-20
  • 本文字数:4031 字

    阅读完需:约 13 分钟

从探索到落地,手淘引入 Swift “历险记”

背景

手淘 iOS APP 在 2019 年经过了约一年的时间,完成了 Swift 语言从调研到基础设施建设再到顺利落地业务。


手淘作为一个航母级别的 APP, 组织结构,工程结构,都是普通 APP 难以企及的,在手淘中实践犹如在沼泽地艰难探索,期间和集团内众多 Swift 爱好者,中间件负责人,一起努力探索出一条较为明朗的 Swift 落地指南。

时间轴

Swift 预研

Swift 语言在 2018 年就已经宣布 ABI 稳定是最重要的目标,虽然早在 Swift 4.x 时代, 语法就已基本不变,但受限于手淘是一个航母级 APP, 工程交付以二进制组件化为主,ABI 未稳定的 Swift 只能固定 Swift Toolchain 的版本,加之会有将近 3MB 的包大小压力,彼时都不适合引入 Swift。苹果与 2019 年 3 月 25 日发布了 Swift 5.0 版本,宣布了 ABI 稳定,彼时又让团队的 Swift 燃起了信心,架构组作为新技术的把控团队,决定在百忙之余让团队成员各自分担一些对 Swift 的调研工作。


在工作之余,我们完成了调研工作,从中得到两个比较重要的结论。

Swift 流行度

我们通过爬虫分析国内外 APP Store 排行榜 Top1000 的 APP,通过文件扫描分析得到结论。


  1. 国内使用 Swift 的 APP 约占比 22%,美区使用 Swift 的 APP 约占比 78%,其中美区剩余没有使用 Swift 的 APP 大部分来自中国地区本地化的产品,如抖音,快手等,可以得出一个结论,国内还是小众的 Swift,在国外已经是现状。

  2. Github/Stack Over Flow 社区等 Objective-C 开源库和问题提问已经基本停滞,未来我们在落地新技术,Objective-C 可能已经是最坏的打算,加之 WWDC 17 年以来,苹果不再提供 Objective-C 的示例,组内同学也多次遇见 Objective-C Bug 去社区提问,毫无热度的情况。

  3. 苹果在 WWDC19 年发布了 4 个 Pure Swift 框架,无法简单的被 Objective-C 混编。


未来我们极有可能因为苹果的强制推进风格和社区文化的落后产生技术踏空,无法迅速响应业务,甚至无法招聘到会使用 Objective-C 的工程师。



Swift 研发效率

Swift 从诞生之初就是一门先进的语言,主要有三个特性。


  1. Safe Swift 从语法层面避免了很多未定义的行为,空值访问,值类型,对工程的稳定性有非常正面的好处,曾经面试一个候选人,简单重写为 Swift 让项目的崩溃率降低 30%。

  2. Fast,Swift 的语言设计让更多的方法调度通过静态调度完成,语言运行时效率优于 Objective - C。

  3. Expressive, 富有表现力的语法特性,让代码量清晰已理解,减少的代码量约有 30%-50%不等,简洁的代码也让一些 Bug 无处藏身,也让工程师能更高效的支撑业务发展,大大提升了研发效率。



下图是一个业务模块重写后的代码量对比:


其他不利因素

Swift 虽然在 5.0 版本完成了 ABI 稳定,但是在低版本操作系统中 (iOS 12.2 以下) 仍旧会有一些不够完美的地方。


  1. 在低于 iOS12.2 以下的操作系统会带来约有 3MB 的包大小问题,但幸运的是苹果放开了蜂窝数据网络下 200M 的下载大小。在 iOS13 上甚至可以超过 200MB。

  2. 在低于 iOS12.2 以下的操作系统会有 100-200ms 不等的启动耗时增加,但在团队同学的努力下上线了二进制重排,启动性能大幅度上升,具体分析请看 手淘架构组最新实践 | iOS基于静态库插桩的⼆进制重排启动优化

集团横向组织成立

在充分的说明了 Swift 的优势和未来的情况下,我们决定不再停留与各种了解,准备下决心落地 Swift,毕竟所有的 iOSer 都知道,Swift 是未来,但是喊了这么多年的口号,总需要有组织的向前推进,只有自己做了并且落地了才有未来。


在基础会议上讨论了一些 关于 Swift 落地的计划和核心任务。如 Swift 基础建设,基础库适配,Xcode 升级, 以及新框架 SwiftUI, Combine, 容器化架构等。


并逐步拆解任务,落地下去。

SwiftUI & GAIA FaaS

在了解 Swift 的同时恰逢 WWDC19, 苹果与 WWDC 推出了跨 Apple 平台下一代声明式的 UI 布局框架 “SwiftUI”。作者第一时间了解了 SwiftUI 的方方面面的特性,简洁清晰的 DSL, 表现力十足的数据流管理,能减少传统 Cocoa 命令式编程 80% 的代码,对研发效率有极大提升。


以下是一个简单的代码展示。



同时我们日常工作中一直有值班看数据大盘的诉求,有时甚至需要在外出的时候查看,之前我们不得不携带工作电脑,迫切需要一款移动值班的 APP,刚好出来的 SwiftUI 新技术可以帮助我们快速落地原型。


但此时没有后端支持,我们想到了 GAIA 平台, GAIA 平台是一款 FaaS 平台的风格,且 Swift 是一门跨平台语言,早在很早 IBM 就曾有 Serverless 服务,于是我们使用 Swift 遵守 GAIA 规范实现了一套 FaaS 服务,作为我们的数据大盘后端支撑。



之前已经编写了多篇文章分析了 SwiftUI 和 FaaS 的核心实现,这里就不再赘述。


  1. 新晋网红SwiftUI——淘宝带你初体验

  2. 系列文章深度解读|SwiftUI 背后那些事儿

  3. 历时五天用 SwiftUI 做了一款 APP,阿里工程师如何做的?

  4. Swift 在 GAIA 平台云端一体化的探索

SwiftUI 的未来

随着前面的调研,使用分析等,虽然 SwiftUI 在初期使用 UIKit/APPKit 在性能上略显不足于 Flutter,但是 SwiftUI 的 DSL 和其他特性比 Flutter 简介不少,相信苹果在未来的版本种会持续优化,现在的技术储备让我们可以轻松应对未来 SwiftUI 的落地。

业务模块重写

手淘在多年的历史迭代中,或多或少遗留了一些历史包袱,如 Cocoapods 不规范使用,头文件管理不规范,工程模版老旧。为了发现是否存在工程问题会导致 Swift 无法落地业务,我们尝试编写一个代码量适中的 SDK,来验证 Swift 的研发效率等提升。完成 SDK 初步重写后,我们发现了现有工程中遗留了大量的问题,导致现有的项目完全无法使用 Swift。


主要存在以下问题:


  1. 头文件不规范无法混编;

  2. 不支持 Module 无法被 Swift 导入;

  3. 工具链老旧支持 Swift 源码开发调试;

  4. Swift 5.0 不是 Module Stability, 对 Xcode 版本有强制限制。

适配基础库

为了解决 Swift 落地工程中的问题,我们结合集团 Swift 横向组织的力量,号召 Swift 爱好者,调研适配技术,编写适配文档,提供自动化工具,梳理出大量的 Swift 适配文档,推动中间件负责的同学,在不影响业务业务迭代的同时,顺手改掉历史包袱,满足 Swift 业务。



截至目前阶段,我们适配了约 100+ 基础库模块, 开启了强制打包卡口,长期有效的治理历史包袱,部分模块在治理历史包袱时,对自己的打包时常,和研发效率都有不小的提升。

适配 Xcode + Cocoapods

手淘的开发模式不同于其他中小型 APP,我们的开发团队复杂,交付方式主要由打包 SDK 二进制集成为主,但 Swift 5.1 才满足了 Module Stability,苹果于 9 月份才正式推出 Swift 5.1, 我们开始着手升级 Xcode11。


对于手淘这样的 APP, 每年升级 Xcode 也会带来大量的 Break Change Future,我们通过查看官方文档,提供适配方案,推动业务方修改了大量 Bug 适应了大量 Futuer,我们与 11 月初完成了 Xcode11 的适配工作。


同时由于 Cocoapods 1.5.x 才支持 Swift 静态库,我们将 Cocoapods 升级到了 1.7.5, 升级还带来不少 SDK 打包效率巨大的提升。


-Xcode 10 + pod 1.2.0Xcode 11 + pod 1.7.5
Swift 5.1无法支持Swift环境落地多个业务,且向前兼容
DarkModeXcode10 无法使用DarkModeAPI支撑业务适配 DarkMode 已上线
打包时间最短时间8min左右5 分 30s
打包时间平均时间 (Debug)14.58 min
打包时间平均时间 (Release)14.29.7 min
源码环境构建 (初次 pod install)3分钟1分钟
源码环境(增量构建)1分钟20s

Swift 二进制不兼容研究

Swift 是一门相对静态的语言,不同于 Objective-C 大部分通过 msg_send 动态调度,静态语言需要访问到其他依赖 SDK 的数据结构的静态布局信息,且手淘的研发方式是二进制依赖交付,容易造成下层 SDK 升级未通知上层 SDK 升级重新编译,带来的二进制不兼容问题很有可能留到线上在爆发,Swift 5.1 同时带来的 Library evoluation 功能帮助我们避免二进制不兼容问题发生。


以下是一份会打破二进制不兼容的 API 变动列表:


ChangeNormal struct@frozen struct
Adding fieldsAllowedAffects ABI
Reordering fieldsAllowedAffects ABI
Removing ABI-public fieldsAffects ABIAffects ABI
Removing non-ABI-public fieldsAllowedAffects ABI
Changing the type of an ABI-public fieldAffects ABIAffects ABI
Changing the type of a non-ABI-public fieldAllowedAffects ABI
Changing a stored instance property to computedAllowedAffects ABI
Changing a computed instance property to storedAllowedAffects ABI
Changing the access of a non-ABI-public fieldAllowedAllowed
Marking an internal field as @usableFromInlineAllowedAllowed
Changing an internal ABI-public field to be publicAllowedAllowed

业务完成

完成以上基本工作后,我们把之前重写的 SDK 通过回归测试后在手淘新版本正式上线,上线后的业务调用量等同于手淘 UV,且 0 Crash, 对开发同学造成了极大的鼓舞,多位同学主动尝试使用 Swift 落地业务。

培训

在初期的业务落地中,我 Review 了大量的代码,发现各位同学写的代码还带有浓浓的 Objective-C 风格,甚至由于不习惯可选类型,引入了强制解包等语法,这些语法会在安全性造成隐患,极易 Crash,我们了解到大量的同学 “看的懂 Swift 语法,但应对不了 Swift 风格和混编环境” 为了解决这些问题,我们组织了集团一些 Swift 大牛,指定规划了一列课程帮助各位开发者轻松的过渡到 Swift 开发环境中 未来我们会考虑向业界开发者提供,敬请期待。

未来已来

手淘在完成 Swift 落地实践中产出了大量的适配文档,工具,教程,方法论,在 2019 年初我们指定的目标和方向已经基本完成,我们做到了!!!在 Swift 诞生这 6 年时间里,各位开发者一直在声称 Swift 是未来,但是在我们手淘架构组的努力下,Swift 不再是未来,而是此刻。


在接下来的计划里,我们会提供一种渐进式的 SDK 迁移方案,逐步将老旧 SDK 迁移到 Swift 中去,Swift 的高效研发效率和安全性将更易支撑业务的快速发展。


本文转载自公众号淘系技术(ID:AlibabaMTT)。


原文链接


https://mp.weixin.qq.com/s/oHGkoGzhMs-l8TX6t0831w


2020-02-20 10:004355

评论

发布
暂无评论
发现更多内容

我国开启“逆袭战”,区块链的盛夏来了?

CECBC

云计算 区块链技术

网站域名备案怎么做?有哪些快速备案的方法?

姜奋斗

网站 备案 网站搭建 域名解析 网站平台

手抖了

shengjk1

随笔杂谈

别让非理性思维毁了你的人生

看山

随笔杂谈 非理性 认知偏差 自控术

每个大火的“线上狼人杀”平台,都离不开这个新功能

ZEGO即构

游戏 RTC 社交

浅析Python中的列表和元组

王坤祥

Python python升级

SpringBoot系列(三):SpringBoot特性_SpringApplication类(自定义Banner)

xcbeyond

Java 微服务 springboot Banner

解析中美数字货币竞争战略 | 构建属于“人类命运共同体”的货币体系

CECBC

数字货币 人民币

关于微服务架构的一些思考

俊俊哥

微服务

奋斗在一线大城市的年轻人的生活工作实录(工厂蓝领篇)

Learun

程序员 软件开发 故事 企业信息化 短片小说

DSN 主流项目调研 3——Orbit数据库的故事

AIbot

区块链 分布式存储 IPFS 分布式文件 Orbit

易观CTO郭炜:如何构建企业级大数据Ad-hoc查询引擎

易观大数据

低/零代码会让程序员失业吗?

代码制造者

程序员 低代码 零代码 信息化 编程开发

Django中的session的使用

BigYoung

django session Cookie

SpringBoot系列(二):如何灵活使用SpringBoot

xcbeyond

Java 微服务 springboot

Django查看操作数据库的执行命令

BigYoung

数据库 django 操作

普通工程师简史

郭华

《深度工作》学习笔记(完)

石云升

读书笔记 时间管理 专注 深度工作

Cobra 命令自动补全指北

郭旭东

cobra Go 语言

数据平台、大数据平台、数据中台……你确定能分得清吗?

华为云开发者联盟

大数据 数据中台 开发者 数据湖 数据

JAVA位运算

彭阿三

Java 位运算

流媒体云时代的声与色,融云铺就的桥与路

脑极体

美丑平等

shengjk1

随笔杂谈

你看脸吗?

shengjk1

随笔杂谈

《深度工作》学习笔记(6)

石云升

读书笔记 专注 深度工作

DSN 主流项目调研 2——Sia和SAFE Network

AIbot

区块链 分布式存储 分布式文件存储 Sia SAFENetwork

LeetCode题解:88. 合并两个有序数组,for循环合并数组+sort排序,JavaScript,详细注释

Lee Chen

大前端 LeetCode

流量明星翻车的“直播卖房”,为什么众盟做成了?

脑极体

一文搞懂Flink rocksdb中的数据恢复

shengjk1

大数据 flink源码

熬得住,人生路

shengjk1

随笔杂谈

害怕

shengjk1

随笔杂谈

从探索到落地,手淘引入 Swift “历险记”_架构_姜沂(倾寒)_InfoQ精选文章