從探索到落地,手淘引入 Swift“歷險記”

背景

手淘 iOS APP 在 2019 年經過了約一年的時間,完成了 Swift 語言從調研到基礎設施建設再到順利落地業務。

手淘作為一個航母級別的 APP, 組織結構,工程結構,都是普通 APP 難以企及的,在手淘中實踐猶如在沼澤地艱難探索,期間和集團內眾多 Swift 愛好者,中間件負責人,一起努力探索出一條較為明朗的 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“歷險記”

Swift 研發效率

Swift 從誕生之初就是一門先進的語言,主要有三個特性。

  1. Safe Swift 從語法層面避免了很多未定義的行為,空值訪問,值類型,對工程的穩定性有非常正面的好處,曾經面試一個候選人,簡單重寫為 Swift 讓項目的崩潰率降低 30%。
  2. Fast,Swift 的語言設計讓更多的方法調度通過靜態調度完成,語言運行時效率優於 Objective - C。
  3. Expressive, 富有表現力的語法特性,讓代碼量清晰已理解,減少的代碼量約有 30%-50% 不等,簡潔的代碼也讓一些 Bug 無處藏身,也讓工程師能更高效的支撐業務發展,大大提升了研發效率。
從探索到落地,手淘引入 Swift“歷險記”

下圖是一個業務模塊重寫後的代碼量對比:

從探索到落地,手淘引入 Swift“歷險記”

其他不利因素

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% 的代碼,對研發效率有極大提升。

以下是一個簡單的代碼展示。

從探索到落地,手淘引入 Swift“歷險記”

同時我們日常工作中一直有值班看數據大盤的訴求,有時甚至需要在外出的時候查看,之前我們不得不攜帶工作電腦,迫切需要一款移動值班的 APP,剛好出來的 SwiftUI 新技術可以幫助我們快速落地原型。

但此時沒有後端支持,我們想到了 GAIA 平臺, GAIA 平臺是一款 FaaS 平臺的風格,且 Swift 是一門跨平臺語言,早在很早 IBM 就曾有 Serverless 服務,於是我們使用 Swift 遵守 GAIA 規範實現了一套 FaaS 服務,作為我們的數據大盤後端支撐。

從探索到落地,手淘引入 Swift“歷險記”

之前已經編寫了多篇文章分析了 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 業務。

從探索到落地,手淘引入 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.5Swift 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 structAdding fieldsAllowedAffects ABIReordering fieldsAllowedAffects ABIRemoving ABI-public fieldsAffects ABIAffects ABIRemoving non-ABI-public fieldsAllowedAffects ABIChanging the type of an ABI-public fieldAffects ABIAffects ABIChanging the type of a non-ABI-public fieldAllowedAffects ABIChanging a stored instance property to computedAllowedAffects ABIChanging a computed instance property to storedAllowedAffects ABIChanging the access of a non-ABI-public fieldAllowedAllowedMarking an internal field as @usableFromInlineAllowedAllowedChanging 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 的高效研發效率和安全性將更易支撐業務的快速發展。

原文鏈接

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


分享到:


相關文章: