天天看點

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

6月23日淩晨 1 點,蘋果 WWDC20 開發者大會線上上以主題演講的方式,在 Apple Park 進行直播。

23-26日,蘋果公開了 100 多個面向開發者的視訊,内容涵蓋Swift / SwiftUI 、App Clips、Widgets、Privacy & Security 等等方面。

對于開發者和程式員來說,我們有哪些新發現和新思考?

淘系技術用戶端團隊,将給大家帶來一系列關于新系統背後的啟發,歡迎交流讨論。

前言

SwiftUI 是蘋果公司于 2019 年推出的 Apple Platform 的新一代聲明式布局引擎,筆者于去年第一時間更新 Beta 嘗鮮全家庭,并在短時間内迅速落地了基于 SwiftUI 的内部 APP, 也分享了幾篇關于 SwiftUI 的文章, 但 SwiftUI 1.0 基本沒有任何公司敢用在正式上線的主 APP 上,API 在 Beta 版本之間各種廢棄,UI 樣式經常不相容,大清單性能差,彼時都辨別着 SwiftUI 還稱為一個 Toy Framewrok.

随着 WWDC 20 相關新特性和介紹視訊的釋出,都明确的宣告着 SwiftUI 元年已經到了,SwiftUI 已經成長為新時代的布局引擎。

以下從幾個方面分享關于 SwiftUI 的重大改變及核心優勢。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

PS: 需要讀者對 Swift 及 SwiftUI 1.0 有一定熟悉。

SwiftUI Apps

蘋果在最近幾年的動作中一直在搞 Apple Platform 統一的事情,從最近幾年的 iPad 多任務 多視窗,到 Mac Catalyst 再到今年更進一步直接推出了 Apple silicon 晶片更是從硬體上做到了真正統一(話外音:你們在軟體上玩的那些跨平台的都是小玩意,硬體才是王道)。

還提供了 Rosetta2 Universal2 幫助開發者基本無成本的遷移到新平台上。但是作為軟體工程師還是要更多的關注軟體生态的變化。首先了解下建立 APP 時的變化

可以看到建立新工程時有了一套全新的模闆基于 SwiftUI App Lifecycle 的跨平台項目。

代碼也從原本的基于 UI/NS HostViewController 變成了基于 APP 的聲明式描述,下面是代碼的前後對比.

  • Before
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let contentView = ContentView()
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}           
  • After
import SwiftUI 
@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}           

其中@main 是Swift 5.1 新增的 Attribute 标記了應用程式的入口點,更多請參看

SE-0281-main-attribute.md

乍看好像隻有代碼精簡了不少,很多人會認為這個簡潔程度還不如Flutter 的 main() => runApp(MyApp());.

但最重要的變化是這是第一次跨平台代碼,完全無需引入任何 UIKit APPKit WatckKit 等相關Framewok, 即可直接運作在不同平台上。這意味着我們後續在UI布局系統上可以逐漸擺脫對傳統指令式 UI 程式設計的依賴。達到真正的平台無關。

SwiftUI 将整個原有的平台差異部分抽象為 App 和 Scene,對于一個 mac/iOS/iPad/watch/tv/..應用,來說 App 代表了整個應用,Scene 代表了與 Window 相關的多視窗,有些裝置隻有一個 Scene 有些則有多個,雖然不同的 OS 确實存在差異,但是在語義層面達到了一緻。

其次一個沒有曆史包袱的 APP,也可以完整的從 Swift APP lifecycle 風格式的模闆開始,無需再和傳統的 UIKit/APPKit 等混合。這也意味着可以達到 APP 完全 Declared and State-Driven。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?
詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

Viusal Editing

▐ Preview

在傳統的利用 DSL 可視程式設計架構或者平台,諸如 Web Flutter 等技術,都是開發者編寫好對應的代碼,運作在對應的平台或者調試工具上。SwiftUI 作為蘋果最重要的軟體層戰略架構,更是和 Xcode 深度結合,在運作之前就可以完整的預覽你所編寫的界面。

強大的 Preview 可以讓你既可以從編寫 DSL 到立即預覽效果,也可從預覽的 Canvas 畫布中直接修改效果在代碼編輯器中生成代碼,這對于日常開發的效率有非常大的提高,尤其是在 UI 微調時,效果尤為突出。

Xcode12 可以在 Canvas 上同時預覽多個不同裝置環境的界面,也可以直接投射到真實的裝置上來預覽。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

對于日常開發來說,編寫一個UI界面通常依賴外部的網絡/磁盤/其他資料,才能正常的建構,這也造成了UI開發雖然是開發中較為簡單的一步,但同時也是最耗時的一步,有了預覽功能,可以把很多繁瑣的工作前置解決掉,對于研發效率會有非常大的提高。

▐ Xcode Library

在編寫真實項目中,一個公司的 APP UI 包含成百上千種風格的 View 元件,對于 UI 元件豐富的産品,如果一個新需求可以由現有的元件組合,那麼需求傳遞的時間也會大大縮短。

但是對于一個大型的開發團隊而言,一個開發同學是很難知道公司内到底有多少種元件庫,而且即便知道有某種元件庫,開發同學初期看到的也是代碼,一般需要書寫一定的 Demo 才可以用眼睛感覺到這個元件到底是否是我想要的。

在 Xcode 12 中提供了更強大的工具,一個自定義元件,隻需要遵守一個 LiberyContentProvider 協定就可被Xcode識别,可以像系統控件一樣直接從 Xcode 裡面識别并預覽。對于一個大型團隊來說,此功能可以大大提高找尋元件和檢視元件樣式的效率。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?
// Without trailing closure:
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }, completion: { _ in
          self.view.removeFromSuperview()
        })
        // With trailing closure
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }) { _ in
          self.view.removeFromSuperview()
        }
        // Multiple trailing closure arguments
        UIView.animate(withDuration: 0.3) {
          self.view.alpha = 0
        } completion: { _ in
          self.view.removeFromSuperview()
        }           

DSL

随着 Swift5.3 和 SwiftUI2.0 的推出,SwiftUI 在 DSL 上也更富有表現力, Swift 支援了多重尾閉包文法和在 ViewBuilde 裡面支援 Switch Case 語句。

▐ Multiple Trailing Closures

雖然社群對多重尾閉包的讨論上一直存在争議問題,但最終 Swift5.3 還是接受并實作了,在普通指令式程式設計的地方使用會有一定的困惑性,但是在 SwiftUI 中 DSL 也更有聲明式的味道。

// Without trailing closure:
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }, completion: { _ in
          self.view.removeFromSuperview()
        })
        // With trailing closure
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }) { _ in
          self.view.removeFromSuperview()
        }
        // Multiple trailing closure arguments
        UIView.animate(withDuration: 0.3) {
          self.view.alpha = 0
        } completion: { _ in
          self.view.removeFromSuperview()
        }           

▐ Switch Case Support

在 SwiftUI 的 ViewBuilder DSL體系中也支援了 Switch case 文法。

var body: some View {
            switch c {
            case .a:
                return Text("A")
            case .b:
                return Text("B")
            case .c:
                return Text("C")
            }
        }           

Data Flow

在使用傳統指令式程式設計編寫 UI 代碼時,開發者需要手動處理 UIView 和 資料之間的依賴關系,每當一個 UIView 使用了外部的資料源,就表明了 UIView 對外部的資料産生了依賴,當一個資料産生變化時,如果意外的沒有同步UIView的狀态,那麼 Bug 就産生了。

處理簡單的依賴關系是可控的,但是在真實項目中,視圖之間的依賴關系是非常複雜的,假設一個視圖隻有 4 種狀态,組合起來就有 16 種,再加上時序的不同,情況就更加複雜。

人腦處理狀态的複雜度是有限的,狀态的複雜度一旦超過人腦的複雜度,就會産生大量的 Bug,并且修掉了這個産生了新的Bug。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?
詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

那麼 SwiftUI 是如何解決這個問題的?

SwiftUI 的架構提供了幾個核心概念:

  1. 統一的 body 屬性,SwiftUI 自動從目前 App 狀态集自動生成基于目前狀态的快照 View。
  2. 統一的資料流動原語。
詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

關于 SwiftUI 中的 Data Flow 是如何消除視圖和狀态不一緻的,請參考去年撰寫的文檔 系列文章《深度解讀SwiftUI 背後那些事兒》

今年 SwiftUI 2.0 新增的 StateObject 資料流原語讓 SwiftUI 在重複建立 View 時避免重複建立 ObservedObject 進而提高 View 重建的性能。

SceneStorage 和 APPStorgae 讓一些可持久化的資料變得更加簡單且具有語義化。

New Controls

前面提到的,新增的 DSL 文法 SwiftUI App Lifecycle,以及 Xcode Library Preview 其實本質上都是對去年 SwiftUI 1.0 錦上添花的新擴充。

真正重要的是今年新增的各類新控件,其中通過導出來自 Xcode11.5 和 Xcode12.0 beta 版本的 Swift 聲明檔案,可以觀察到整個聲明檔案從原來的 10769 行增加到 20564行。

新增了約 87 個 struct 16 個 protocol。有了這些豐富的元件才可以更好的建構我們的 APP 。

▐ 大清單元件

在任何一款 APP 中都會存在類似大清單元件,如淘寶 APP 裡面的某家店鋪裡面商品清單流,首頁的資訊流,都是具有超長内容的清單頁資料。對于長清單頁來說,過長的 UI 頁面會導緻過多的記憶體占用,在使用者的裝置中,記憶體是最為重要的名額,對于目前國内的 APP 市場,低端手機仍然占據大量的市場,對于這些裝置來說,一旦記憶體超标,APP 就很容易 OOM,這會導緻使用者體驗非常差,在現有競争關系激烈的市場環境下,體驗差意味着會失去使用者。

對于傳統的指令式程式設計來說,我們可以主動控制 UITableViewCell 的重用,自建緩沖池等一系列手段去優化我們的 APP 記憶體占用,但是對于 SwiftUI 1.0 來說,系統提供的控件并沒有有效的辦法去讓我們控制頁面的渲染,對于大清單頁面就容易出現記憶體占用過高的問題。

SwiftUI 2.0 推出了 LazyHStack 和 lazyVStack 加上 List 渲染模式預設就是 Lazy 的直接解決了最大的性能問題。

筆者以去年使用 SwiftUI 編寫的 Emas App 為例,當清單頁(并無大圖)加載到 500個時, APP 使用記憶體已經達到了将近 360MB 。而隻需要切換到 Xcode12 API 調整為到 LazyVStack 記憶體占用直接降低 300MB 。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?
詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

Widget and Clips

蘋果與 WWDC 20 推出的 WidgetKit 支援的 API 是 SwiftUI Only,雖然已經可以混合部分UIkit 裡面的View,但相信沒有曆史包袱 最低支援版本為 iOS14 的 Widget 沒有人會選擇笨重的指令式 API。

同理 Clips 也一樣。這裡因為篇幅原因就不做展開,後續會有專門的文章分析相關技術。

Swift & SwiftUI 的機會在哪裡?

筆者曾經在公司推動集團更新了基建,支援了 Swift 開發環境也在淘寶落地了一些場景,但是集團内一直有一些質疑的聲音, 引入 Swift 到底有什麼用?

SwiftUI 又是 N 年後才可以用上的小玩意,Objective-C 不夠用嗎?現在筆者可以回答這些質疑的聲音, Swift 未來的機會在 效率,體驗和蘋果的技術紅利。

▐ 效率

從研發效率上來說, Swift 對比 Objective-C 的精簡程度不言而喻,筆者在淘寶 APP 上線的子產品代碼量下降了 40 %。

但更進一步,如果編寫 UI 界面從 UIKit 轉向了 SwiftUI 代碼量直接少了不止一倍。更少的代碼意味着更快的傳遞,在目前競争激烈的市場會有更多的試錯場景。

關于使用 UIKit 編寫代碼轉向 SwiftUI 的代碼量對比,讀者可以參考開源 APP

MovieSwiftUI

直覺了解。

▐ 體驗

讀者可能比較困惑對于切換語言和架構,對體驗看上去沒有任何幫助,但事實真是這樣嗎?

首先引入 Swift 後,由于 Swift 語言設計之初便對安全性列為最重要的目标,Swift的引入會讓代碼盡可能的減少未定義的行為,減少 Crash 意味着APP的穩定性提高,體驗自然更佳。

其次雖然 Swift 同樣的語言出于對安全性考慮編譯處理的指令會比 Objective-C 更多,但是如果UI部分都用 SwiftUI 來寫呢?

更少的代碼意味者更小的包大小,目前國内巨頭 APP iOS 端 APP 包大小都朝着 200 MB 奔去,如果能減少更多的代碼對包大小也可以在 200MB 的限制下承載更多而業務。對使用者的體驗也有較大的提升。

更進一步由于 Swift 選擇使用值類型建構整個APP,值類型的有點在于更扁平化的内聯資料結構去配置設定記憶體,而不是使用更多間接指針引用,減少了大量不必要的堆記憶體消耗,意味着整體記憶體使用量的降低。對整個 APP 的穩定性也有較大的提高。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?
詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

▐ 蘋果的選擇

Swift 做為蘋果的戰略語言已經發展的越來越壯大,自 2019 年 Swift ABI 穩定後,蘋果在 Swift 的投入越來越大。我們可以進入 /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/swift , /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks ,

https://github.com/apple

https://github.com/swift-server

看到, 自 iOS 13 以來 蘋果新增了約 10+ Pure Swift Library , 10+ Open Source Swift Library, 以及針對 144 個公開 Framework,根據 Swift Style 重新設計了 57 個 Framework 的API。

從以下資料:

從 WWDC17 後 蘋果已經不再使用 Objective-C 做 Sample Code 示範

https://developer.apple.com/

不再更新 Objective-C 相關的文檔

WidgetKit 是 SwiftUI only。

App Clips 10M的包大小, SwiftUI 是最合适的架構

開源社群逐漸放棄 Objecive-C 如 Lottie。

可以判斷,Swift 是未來 Apple 平台的唯一選擇,越是有包袱的大廠 APP,從現在還不盡早儲備,在未來越會寸步難行。

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?
詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

▐ 我們需要做些什麼?

✎ Swift

我們已經做了什麼

一套支援 Swift 二進制的研發環境

300+ 支援了混編的淘系 SDK。

手淘落地了 6 個子產品。

集團新增了約 20個 支援 Swift 的APP。

10 多場技術教育訓練。

169+ 語雀知識沉澱。

300+ 工程師的集團 Swift 官方組織。

2 個 技術創新産品

經過去年橫向組織大家共同的努力,我們已經已經支援了橫向大基建。包括研發環境,工具支撐,沉澱了大量的文檔,還有相關的技術課程。

▐ 要朝什麼方向去努力

目前集團對于 Swift 的呼聲越來越高,我們大量的工程師希望的去使用 Swift 。目前首先要做的事情是依托 Swift 和 SPM 提升我們的開發體驗,更新我們的中間件,使業務可以大量的用起來 Swift ,提高我們的研發效率和代碼品質。

更新基于 SPM 的新的包管理體系

更新老舊基礎庫,打磨新一代基建。

引入新的 Swift 特有庫 賦能業務。

✎ SwiftUI

雖然前文提到了 SwiftUI 的衆多優點,包括研發效率,體驗的提高,但是在國内的環境中 SwiftUI 也有它緻命的弊端

iOS 14 才可放心的使用。

隻支援 Apple Platform,這和國内的要支援 Mobile Platform 從理念上沖突。

大型 APP 要解決的是如何部署到低版本作業系統上和安卓平台上,畢竟很多公司還在支援 iOS 9 對于更新到最低支援 iOS 14 好像還需要一個世紀那麼漫長,而且國内的裝置占比大頭還是以 Android 巨多 。

雖然可以看到 Swift 語言也在逐漸支援 Android 平台,但是也看到蘋果對于安卓平台的 SwiftUI 并沒有太大興趣。

從體驗上 Flutter 遠不如 SwiftUI 這種親兒子效果好, 但對于國内跨端欲望旺盛的市場來說 SwiftUI 還是比不過 Flutter, 不過既然 SwiftUI DSL 層已經基本固定,那麼也有可能投入人力直接在低版本作業系統上實作一套自建的 SwiftUI 引擎,或者将 SwiftUI 引擎移植到安卓平台,比如對接 Flutter 或者直接對接 Android Native。

比起 Flutter 引入雙端帶來的包大小增量和體驗不一緻的情況, SwiftUI 保留 iOS 平台體驗,隻侵入一端的選擇顯然要更好一點。

不過短期内我們可以在 Clips 和 Widget 場景下開始使用 SwiftUI, 畢竟 SwiftUI 快速的開發效率對和較低的包大小占用非常适合這樣的場景,我們可以在業務場景中練兵儲備我們的 SwiftUI,并積極在主 APP 中嘗試。

✎ 下期介紹

下一期,我們将結合最新資訊,聊聊 【 iOS14 隐私适配及部分解決方案】,敬請持續關注~

參考

SwiftUI 背後那些事兒 Add custom views and modifiers to the Xcode Library Structure your app for SwiftUI previews Introduction to SwiftUI What's new in SwiftUI App essentials in SwiftUI Visually edit SwiftUI views Stacks, Grids, and Outlines in SwiftUI Build document-based apps in SwiftUI Data Essentials in SwiftUI Build a SwiftUI view in Swift Playground Build SwiftUI apps for tvOS Build SwiftUI views for widgets Build complications in SwiftUI What's new in Swift Swift packages: Resources and localization Distribute binary frameworks as Swift packages Explore logging in Swift Create Swift Playgrounds content for iPad and Mac Embrace Swift type inference Explore numerical computing in Swift Unsafe Swift Safely manage pointers in Swift Explore Packages and Projects with Xcode Playgrounds Use Swift on AWS Lambda with Xcode

手淘用戶端架構組

負責淘寶用戶端的基礎架構包括元件化容器、啟動器、路由、UI架構等,負責高可用包括Crash、卡頓、記憶體、耗電等監控,負責全局性能、體驗優化,負責重點技術包括存儲、日志、修複等,負責系統新特性、新技術、新裝置探索,在這裡你會面臨海量使用者、大規模業務、雙十一大促帶來的巨大技術挑戰,你能與資深大牛并肩作戰,深入系統核心研究解決複雜問題,迅速成長為業界優秀工程師!

履歷投遞:[email protected]

關注「淘系技術」微信公衆号,一個有溫度有内容的技術社群~

詳解 WWDC 20 SwiftUI 的重大改變及核心優勢前言SwiftUI AppsViusal EditingDSLData FlowNew ControlsWidget and ClipsSwift & SwiftUI 的機會在哪裡?

繼續閱讀