本文是知名 ios 开发者 NSHipster中文译者-刘镇夫(小鱼),在云栖大会上为大家带来的分享,本文主要介绍几点,第一、Swift 5 代表什么?第二、Swift 5 在社区中应用的情况和我们真实开发环境中是什么样的过程和现状?第三、在实际开发中我们应该怎样面对 Swift 5 的决定性因素?第四、基于上面三个话题的讨论结果来看在新时代下,有什么新的路线和发展方向值得我们去探索。
01、Swift 5 带来了什么?
▐ 稳定的 ABI
Swift 5 带来了什么?最重要的一点是稳定的 ABI ,5.1 版本后,我们可以用不同Swift 支持的第三方框架,最终编译成同一个 APP ,这是成熟语言的标志,只有这样才能让不同的框架和代码为你所用,大家使用时也不会有那么多的顾虑。
▐ 共享 Runtime 库
除 ABI 外 Swift 5 也带来了共享 Runtime 库,上图中 66.6MB 和 30.1 MB 都是以前的现状,Swift 出来后再配合新的编译工具,现在这些库都能够共享,会显著减少我们的包体大小,因为共享的 Runtime 让使用时间减少 5% 左右,用户在下载和使用时,代码构建量会减少 10% 左右,开启“optimize for size”构建量会减少 15% ,这是大家采用三方 Swift 5 的一个关键性因素。
▐ Objective-C 混编调用效率更高
现在大部分都是自建的,当不在纯 Swift 环境下开发时,这里面写出来的一些数据,是开发过程中不可避免的一个问题, Swift 5 更新后,在第一程度调动方面有 1.6 倍的提高,在 NSString 方面有 15 倍的提高。
▐ Swift Package Manager
随着 Swift 5 的发布,我们还能看见一些新工具产生,这在 IDE 和 Xcode 里可以直接看到,哪些地址有高依赖?引用了哪些库?相对以前没有官方的支持,好处非常明显,以前使用时,第一次缩影下要下载大量的内容,这是非常痛苦的一点。Swift Package Manager 虽然没有这样的问题,但他的步骤也比较复杂,不是简单一个包的名字安装上去就可以,苹果新出的 Swift 5 manger 相对于官方的指导意见,同时支持后台直接登录一些账号,包括企业自己的项目管理地址,这个相当于node 的环境,有 npm 的环境,是官方推荐的包管理工具,整个过程变的非常简单,他是可以和第三方工具并用的,切上来之后也不用担心没有支持的问题。
▐ Swift UI
SwiftUI 大家应该比较了解,简单来说就是用上图只有五行左右的核心代码去完成右侧页面的简单操作过程,估计大家都已经玩过,下面也会展开讲一下这个功能上可以探索的一些新路线。
02、Swift 在实际研发中的使用情况
相对来说,现在国内实际研发中有真正用到 Swift 的同学较少,但是 Swift 本身的发展已经没有几年前滞后的情况,现在的发展是飞速的。
▐ Swift 发展进程
Swift 在 2010 年开始立项,第一个版本是 2014 年 9 月的 1.0 版本,2.0 版本在2015 年 4 月 ,这里面变成了基本的调动速度,后面是每一年发布大的更新,所有基本的类型都是 Swift 自己不用调动的,现在是一个重要的时间点,可以看到 Swift 的前景广阔,不用再依赖别的语言实现,2019 年 6 月发布的 Swift 5 ,让他成为现代化的成熟语言为我们所用。
▐ 社区表现对比
Swift Kanban,我收集的数据有 11159 个,有 6474 个标记已经被处理,剩下的不清楚对话是怎么产生,通过这个数据可以看到官方一直在非常努力的推进开发以及与开发者交流,可以看到每天官方的情况,大概 3 到 4 个小时就会有官方来回复开发者告诉大家最新的 bug 。
对比来说,一个开发的官方社区维护不太好的语言做不到这样的响应速度,官方的态度是非常快速的修复这些问题,大家也不用担心在开发过程遇到什么问题,上图是我在网上收集到的一些数据,Y轴是 Pull Request 数量,蓝色的线是 Objective-C ,橙色的线是 Swift 。
从 2016 年开始,Swift 的数据已经超过了 Y 轴,现在有一种取而代之的快速发展趋势,这个说明社区中更多的开发者习惯把精力放在 Swift 上,而不是放在 Objective-C 上,这对大家的 APP 也是一个相关的提醒。如果你坚持只用 Objective-C ,那么你可能会面临一个风险——你所依赖的第三方开发库已经不愿意去维护他们。
上图是两个在社区中最著名的第三方库,一个是 AFN ,一个是 Swift 上做的,左边是 Objective-C 上做的,这都是一个开发团队同一套开发团队库,就目前状况来说,他们在 stars 上面的数量是差不多的,关注度和使用量也是差不多的情况,但是 opening issues 上面的 afn 已经积累了 322 个未处理,ALAM 只有 32 个,这里面有各种各样的问题,官方不管 issues 的同时, Alamofire 只有 9 个没有处理,而 AFN 有 83 个没处理,最后一次 Swift 版本其实前一面就有新的肯定的出现,而 Objective-C 要往前推 6 个月才有一个 commit ,最后一个版本需要往前推一年半才可以找到。
举个实际的例子,比如大家都是做 HTTP 请求的,3.0 协议已经发出,如果未来的开发者更愿意把精力放在 Swift 上面,现在 SSL Certificate Verify 的验证,是可以把证书链从上至下全部验证一遍,这在 Alamofire 里已经支持的非常好,大家在此领域目前是缺失的,所以目前而言的现状是有一些不能带来了,这是老框架不能做到的,个人建议,如果大家想转到 Swift ,可以尽快实行,以避免在未来时间点,你所依赖的第三方非常重要的开发框架有严重问题时,可能会跟不上进度。
▐ Objective-C 的发展史
为了打消大家对 Swift 应用前景的疑虑,Objective-C 1981 年开始创建,至今已有 20、30 年的时间,1988 年乔布斯创建了 iOS 并买下授权,这个语言用了 20 多年的时间才成为苹果平台的一个专属主流的语言,Swift 只用了 5 年的时间就达到现在的结果。2007 年 Objective-C 2.0 操作的版本,也就是现在手动管理内存的版本 2007 年发布,现在大家都在使用这个版本,至今相当于过了30 多年的时间,才处理了他在系统上的地位。
Objective-C 的发展历史也不是没有问题,他出来时比 Swift 的问题更多,在 2005 年才有垃圾回收机制,并且是没有命名空间的,大家都知道系统的数据是 NS 开头,如果写一个很大的数据就没有办法编译了,没有运算副重在,他出来时作为 C 语言的扩展机制,所以刚出来时面临的问题要比 Swift 现在面临的问题要多的多,但苹果还是吸收了他作为主流的开发语言,这里面不但有技术性的一些挑战和考量,也有在整个生态中开发环境的开发者对于语言喜好的一个考量。当时有五大平台,Java 在苹果生态里可以继续开发,但是最后苹果还是选择了 Objective-C ,一个重要的原因是,在苹果生态内部经过 20 多年的内部工程师的使用,更喜欢这个语言所带来的感觉,并不是 Java 不好才没有选择,而是社区的人的喜好,大家在选择的时候,要考虑一下团队的情况,和大家对新语言的兴趣和努力方向在哪里,而不是要不要接受新的语言使用新的框架,以确定在未来的情况下不会作出错误的决定。
03、项目引入 Swift 的考量因素
回归到实际问题,项目开发中到底要不要引入 Swift 的考量因素?我主要将其分为五大模块,目标、成本、过程、结果和反馈。
首先看目标是什么?为什么要考虑在项目中是否引入 Swift 的新语言?希望大家不是单纯为了使用新语言而用,是要节省开发效率、还是提升运行效率、或者是要减少包的大小,还是让整个团队的技术跟上新的潮流去做一个提升?都是有一个目标,这也也会产生一个成本,这里面的考量是为了达成新的目标,这个成本是否值得付出?以及是否会造成一些 APP 不稳定的情况,这里会有一些负面的影响,而你能否在实际开发和实际交付的过程去承担?
如何把新的语言、新的框架应用到业务的 APP 里面去?分模块开发还是分页面开发?都是要考虑的过程,这对于APP开发的风险还是比较大的,业界也有一些比较失败的案例,他们在使用 Swift 后又全部换回来了,这都是大家不想看到的,比如在引入 Swift 作为其中几个模块的开发,是否真正产生了你想要的结果?是不是真的节省时间了?
如果你的 APP 过于复杂,里面有互相嵌套的地方,那可能不太适合你们团队的现状,所以不要觉得引入之后,在交付上面就是适合的,反馈过程也很重要,因为 APP 开发是持续的过程,不是交付这一版就结束了,仍然要考虑下一个迭代中是否要用新语言做开发,或已经开发的模块适不适用新语言去做扩展。
举个例子,我实际参与的项目第一是某区块链客户端,在密码选用时选了 Swift 做实践,其他的基础层面用了 Objective-C,原因非常简单这两部分在应用中隔离的比较好,和谐的比较开,互相没有太多搀杂在一起的地方,并且有一个好处:Swift 编译出来的包在逆向工厂和反编译中目前是属于比较困难的状态,所以他非常适合密码和区块链顶层的应用,能够保证 APP 安全的运行在客户的手机上。
日程管理类的 APP ,需要记录你要做的事,所涉及到的文本类会较多,为了避免 Swift 处理方面出现问题,所以保留了 Objective-C 的实践,各种细碎的页面较多,团队内部有人想要尝试新语言时,会建议他在新的页面上尝试这个语言,核心部分依旧保留 Objective-C,并且在对应的 ReactiveCocoa 上用 Swift 对应的 2.0 版本。
总的来说如果企业有新的项目区,建议用新的语言,在新项目上有技术的实践,在新项目中把功能训练的比较完善,去解决一些问题,个人项目还是完全使用 Swift 去开发,这样会提高个人能力,当你真正去大项目中部署这个问题时,在大部分问题已经预见过后,不至于束手无策。
04、新的机遇与挑战
随着 Swift 5 语言慢慢发生,我们可以看到一些新的变化,第一是 Project Catalyst 一键生成酷炫的功能,第二是 SwiftUI,第三是 Combine ,这是苹果官方发出的消息队列机制,第四随着 Swift 4.0 版本发出的 Swift for Tensorflow ,在 AI 方面都搞一些涉猎,这是社区对这个方面的侧重,目的是用这些新的功能去吸引最顶尖的开发者去加入。
Dropbox结合 Swift ,是做文件同步的,他不像 Telegram 在重写 Swift 的客户端时所说的原因那么简单,所谓都重写,原因很简单,重写后用电量明显减少,以前一些隐藏的 bug 解决之后,都不见了,完全没有考虑性能,他有一个 C++ 的代码,在各种平台都可以用同一套客户端去做这件事,现在放弃了 C++ 去做原商代码的开发,目的很简单,很多移动工程师对学习 C++ 毫无兴趣,以及他们在移动端互相配合的过程中产生了极大的问题,这样就导致了优秀的开发者想用 Swift 开发时已经没有太多的用武之地,因为核心功能都不是这个语言写的,最后导致很多优秀的工程离开了这个团队。
拥抱新技术也是挑战,在应用 Swift 的开发之后一定会遇到一些原来没有的问题,高效率的问题可能也会遇到,我觉得优秀的开发者就是这样,当你拥抱新技术的时候、新的挑战所带来的问题你也能够承担,也能够把他解决,这才是正确的态度。
有的同学可能说 Objective-C 并不是阻止我们使用 Swift 的最重要的原因,我们的应用全是动态内容分发,或者一些常见的框架,即使 Swift 再好可能也没办法去处理那些动态页面的交付,这个问题不在于 JavaScript 和 Swift ,他们的执行效率没有原生的那么快,好处是这些动态内容的交付有了一个可交付的结果,如果你的 APP 里要求动态内容、动态页面、动态布局,其实是很难实现这么高的切合度的。
基于 Swift 目前的发展现状,Swift UI 之所以能够这么简洁、高效的开发,是基于 Function Builde 的开发,现在看到的 Swift 其实是可以做简化的,包括一些名字都是可以简化掉的,一些单行的 return 都可以不用写了,我觉得未来有一个方向就是你可以把 Swift UI 写成右面那种形式,我们可以和 Function Builder 做对比,包括他的逻辑可以让你去做一些相关的 DSL 的书写。
左边的 DSL 可以通过社区目前正在研发的 Builder ,他的语法和表现形式变的更加简洁和方便,如果所有的 UI 层面和逻辑层面的代码都能够写的像左边这样的话,差异就不是特别大,在所有平台动态里内容分发也不会有太大的问题,上图是我在开源社区翻的到的一个可能的实践,这个人基于 Function Builder 做了 HTML ,由左边这种形式直接转化成页面,当你收到服务器语言时,直接将其绘制出来附着上去,对我们来说还是有进一步的研发和众多可能性,对比目前这些动态环境来说,动态内容造成的环境,像左边几个大多数是用 JS 做基础语言去做编写的,运行时依赖 JS 的用户,用这个框架去做一次解释和翻译才能完成最后的结果。
▐ 跨平台解决方案
有人说我们的这个是跨平台的,如果大家仔细观察右面的形式,会发现他非常像 Swift 5 的 DSL,所以安装新的开发框架有 Jetpack Compose 的一个东西,像 Swift UI DSL 一样,可以完成同样语法的简便形式,这样大家要达成统一时,在双平台都可以用原生语言去实现,而不再依赖 DSL 的翻译,整个研发和运行效率都会大大的提升。
未来新的挑战和机遇是我们都用自己平台的语言,不依赖 JS 去解析,非常建议 DSL ,动态内容由服务端分发,十分简洁。APP 前端的一些界面在使用 Swift ,生成前的 Swift 前端最方便的方式是什么?就是后端也是用Swift 写的。Swift 用 Swift ServerSide 生成的前端也是 Swift 这个语言生成的 DSL 可以给移动开发者用,也可以给安卓开发者用,作为一个非常酷的 APP,例如换脸,可能会依赖 tensorflow,AI相关的部分也是用 Swift 5 写的,所以我觉得前景是大家只会去学Swift 的语言,把这种语言用好你们就可以成为前平台的开发者上市。
05、总结
稳定的 ABI ,是我们最基本的运营,保护运行状态相对稳定、成熟,对我们来说非常重要,接下来是 Runtime ,和 Objective-C 混编调用效率更高,可以保证大家在使用的时候不会遇到太多的问题,后面是社区的支持和开发者对 Swift 的喜爱,还有以 DSL 为基础的动态方向上的预想,这件事情在官方社区里已经提到最高日程,大家可以去社区关注一下,刚才的设想图也并不是完全幻想出来的,而是会在短时间内得以实现。
One More Thing
淘系技术部依托淘系丰富的业务形态和海量的用户数据,我们持续以技术驱动产品和商业创新,不断探索和衍生颠覆型互联网新技术,以更加智能、友好、普惠的科技深度重塑产业和用户体验,打造新商业。我们不断吸引用户增长、机器学习、视觉算法、音视频通信、数字媒体、移动技术、端侧智能等领域全球顶尖专业人才加入,让科技引领面向未来的商业创新和进步。
请投递简历至邮箱:[email protected]
本文作者:刘镇夫(小鱼)
阅读原文
本文为云栖社区原创内容,未经允许不得转载。