作者|劉鎮夫(小魚)
出品|阿里巴巴新零售淘系技術部
本文是知名 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 去開發,這樣會提高個人能力,當你真正去大專案中部署這個問題時,在大部分問題已經預見過後,不至於束手無策。
隨著 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 為基礎的動態方向上的預想,這件事情在官方社群裡已經提到最高日程,大家可以去社群關注一下,剛才的設想圖也並不是完全幻想出來的,而是會在短時間內得以實現。