老司機 iOS 週報 #64 | 2019-04-22

老司機iOS週報發表於2019-04-22

老司機 iOS 週報,只為你呈現有價值的資訊。

你也可以為這個專案出一份力,如果發現有價值的資訊、文章、工具等可以到 Issues 裡提給我們,我們會盡快處理。記得寫上推薦的理由哦。有建議和意見也歡迎到 Issues 提出。

新手推薦

? Designing Swift APIs

@zvving:如何寫出可讀性更高的程式碼?本文提供一些示例:引數標籤可以幫助我們定義清晰易讀的 API,巢狀型別能提供輔助的上下文關係,強型別為程式碼增添必要的儀式感,可擴充套件的 API 設計能同時滿足便捷呼叫和豐富定製。

作者認為:『人人都是 API 設計師,當我們在設計非私有屬性或方法時,我們都在設計 API』,你認為呢?

文章

? ? Humble Asset Catalog & Assets Catalogs 與 I/O 優化

@looping:這兩篇文章分別從各自的角度解釋了在使用 Asset Catalogs 後,讀取圖片資源的速度變快的原因。

通過仔細閱讀這兩篇文章,我們能夠更清晰地瞭解到:

  • Asset Catalogs 和 car (Compiled Asset Catalogs) 檔案的相關內容以及它們的作用
  • CoreUI 框架對圖片資源載入過程的一些邏輯細節

從而明白使用 Asset Catalogs 後,在載入資源上速度更快的原因:

  • Asset Catalogs 會對圖片進行分類壓縮儲存,減少在目標機型上的資原始檔大小,提高讀取速度
  • 通過記憶體對映 (mmap),減少 I/O 操作,加速讀取 car 檔案內容
  • car 檔案實際上是一種特殊的 BOM 檔案,能夠在載入圖片時直接獲取 rendition、renditionKey 以及 attribute 這些資訊,不同於從資料夾 (bundle) 中讀取,需要執行耗時的 -[CUIMutableStrucetedThemeStore canGetRenditionWithKey:] 操作來讀取 rendition 和 renditionKey

除了文章帶給我們的結論,以及我們今後可以做的事情 (將常規資原始檔都遷移到 xcassets 中) 之外,兩位作者對問題的探尋和思考的方式也是非常值得學習借鑑的。

? ? Let’s write Swift code to intercept SSL Pinning HTTPS Requests

@含笑飲砒霜:現在幾乎絕大部分的 iOS App 都使用了 HTTPS 請求,這極大提升了我們使用的安全性,但也不意味著這就是絕對安全的。

如果想檢查 iOS 應用中的 HTTPS 請求,最常用的方法就是中間人(MITM)攻擊,這種技術需要使用某臺主機作為代理伺服器,為客戶端提供服務。為了保證攻擊成功,客戶端需要將代理伺服器的證書安裝到裝置的全域性信任儲存區中。這樣處理後,客戶端就會將證書新增到白名單中,允許與代理伺服器之間的 HTTPS 通訊。

如果想保護應用免受 MITM 攻擊影響,可以使用 SSL 校驗證書繫結,此時受信任伺服器的證書副本會打包到 iOS 應用中,還有一些附加程式碼可以確保應用只與使用特定證書的伺服器通訊。當 SSL 證書繫結處於啟用狀態時,應用不會將任何請求傳送到不受信任的伺服器上。

即便如此,也依然可以繞過 SSL 證書繫結。也就是在具體請求通過受保護的 HTTPS 通道傳送之前,嘗試攔截這個請求,這需要將程式碼植入到應用中,這裡會用到程式碼注入的相關知識。

如果想更細緻的瞭解如何攔截 HTTPS 請求,本文不可錯過,絕對深度好文。

? ? 乾貨 | 近萬字長文詳述攜程大規模應用RN的工程化實踐

@Damonwong: 如果談起 React Native 在國內的業務落地,我可能第一個會想起的就是攜程和趙辛貴老師。在上次聽完趙興貴老師分享的專題《攜程無線持續交付平臺工程實踐》之後,意猶未盡,一直想更加深入瞭解一下攜程在 RN 方面的技術探索。今天終於等到了攜程的 RN 建設及他們設計的 CRN 的分享。這篇文章主要講了下面幾個事情:

  1. RN 在攜程中的使用情況
  2. 攜程基於 RN 優化的 CRN 框架的設計及使用
  3. CRN 做了哪些效能優化及實際效果比較
  4. 如何釋出及運維

比較可惜的是沒有看到這套系統相比較於原生開發,對業務增長,開發效率有哪些優化,所以比較期待後續能有這方面的分享。

最後,在文中提到將要開源的 CRN,也已經開源了,感興趣的同學移步 攜程開源RN開發框架CRN 檢視。

? JSON as configuration files: please don’t

@olddonkey:這是一篇 2016 年的老文章,但是其中的觀點直到今天依然具有參考價值。

很多公司,很多團隊使用 JSON 檔案作為 App 的配置檔案,不論是從遠端下發,還是本地載入。

但是,在實際的專案中,用 JSON 來作為配置檔案解決方案並不是個完美的方案,它存在的很多問題,這些問題會在實際中逐漸暴露。

文章作者圍繞這他心中的幾個缺點展開論述:

  1. 註釋容易缺失。
  2. 可讀性差。
  3. 過分嚴格的格式。
  4. 缺乏可程式設計性。

本文雖本意是針對 Web 開發提出觀點,但是對 Mobile 開發也一樣適用。

? 基於多重替換方式的 iOS 程式碼混淆方案

@含笑飲砒霜:程式碼混淆,是將計算機程式程式碼轉換成難於閱讀和理解但是功能上等價的行為。可用於原始碼,也可用於編譯而成的中間程式碼。混淆程式碼可以有效保護我們的原始碼,阻止逆向工程,因為逆向可能會帶來一些諸如程式漏洞等不可預知的問題。

目前常用的幾種方法,像打亂程式碼格式,將程式碼中的元素,如變數、函式等改寫成無意義的名字,甚至是重寫程式碼的部分邏輯等,都或多或少的存在問題。比如對於支援反射的語言,程式碼混淆可能與反射發生衝突,被混淆的程式碼難於理解,而且也不能真正阻止逆向,只能增大逆向的難度。

對安全性要求很高的場景,這些常規的混淆方式,並不能保證原始碼的安全。鑑於此,TalkingData 團隊最終決定,自研一套能夠完美整合到打包流程中實現自動化的無侵入的混淆工具。由於不同業務線的要求並不一致,所以 TalkingData 自研的這套混淆工具未必適用所有業務線。但文中提到的一些自研過程中可能會遇到的一些問題,值得我們去借鑑和思考。

? Swift 5 Frozen enums

@沒故事的卓同學:在 Swift 5.0 中編譯器針對使用 C style 列舉增加了一類提醒(即使 switch 已經覆蓋了所有的 case 依然會有這樣的警告):

Switch covers known cases, but 'XXXXX' may have additional unknown values,Handle unknown values using "@unknown default"

提醒使用者雖然現在你已經覆蓋了所有的 case,但是未來這個列舉值有可能會增加新的值,我建議你還是處理一下這樣的情況。

不過有的列舉值作者可以保證未來不會新增值,針對這個場景蘋果增加了 NS_CLOSED_ENUM。如果列舉用 NS_CLOSED_ENUM 宣告而不是 NS_ENUM,Swift 使用這個列舉編譯器就不會產生建議使用 @unknown default 的警告。

? Asynchronous completion handlers with Result type

@邦Ben:Swift 5 中的標準庫中加入了 Result Enum (success / failure),該文作者通過一個 URLSession 的請求例子,演示了使用 Result Enum 改造過程。使用 Enum 會讓你的程式看上去更為簡潔以及意思明確,詳細請看文章內容。

? Improve your iOS team’s productivity by building features as frameworks

@老峰:如果你使用 Swift 開發過大一點的專案,那麼你可能會有這樣的感受,明明只是修改了一行程式碼,但卻把整個 App 重新編譯了一次,花費了很多時間。

本文作者針對這一痛點提出一種優化方案,通過把功能獨立的業務程式碼改為 Framework 動態庫,這樣就不會每次重新編譯整個 Project,從而減少編譯時間,文中結合示例程式碼給出了詳細的優化過程。

儘管作者這一方案可以縮短編譯時間,但如果 Framework 粒度太小,太多動態庫反而會引起其他問題如增加 APP 啟動時間、App 安裝包變大;粒度太大,每次修改程式碼又會涉及多個 Framework ,編譯時間優化又不會很明顯,感興趣的讀者可以借鑑這一思路,做些有益的嘗試。

? How to deploy a Swift backend on Amazon AWS

@小非86:目前 Swift 的後端框架主要有 Perfect、Vapor、Kitura 和 Zewo 等。往期週報 推薦過使用 Perfect 開發後端的經驗。本期推薦大家這篇使用 Kitura 開發後端的另一種嘗試。

? Disjoint-set union in C++ and Swift

本文使用 C++ 與 Swift 實現了簡單的並查集。大家可以藉此對比同一個資料架構在不同語言的實現。

工具

Accio

Accio 是一個基於 SwiftPM 和 Carthage 的包管理工具,其有以下特點:

  • 依賴預編譯,也就是二進位制化。
  • 自動整合到專案檔案裡,不像 Carthage 那樣需要手動整合,這也解決了 Carthage 專案中最麻煩的部分。
  • 基於 SwiftPM 的依賴管理系統,只要第三方庫使用 Package.swift 宣告即可,不需要去跟 xcodeproj 和 Cartfile 打交道。
  • 基於 SwiftPM 的快取管理,可以減少不必要的重複的下載和編譯。

程式碼

Markdown Playgrounds for Swift

@蓮叔:Markdown Playgrounds for Swift 是 objc.io 基於 Swift5 開發的一款 markdown 編輯器,最大的特性就是在你 markdown 中的 Swift 程式碼可以被執行。對比傳統 markdown 編輯器,核心就是實現了 Swift 語法的高亮以及將 Swift 程式碼提取出來後用 Swift REPL 程式去執行並拿到返回的結果(Swift REPL 程式就是終端中的 Swift 命令)。整個工具是開源的,並且 objc.io 有一整套配套的教學視訊(第一章是免費的)一步步的教你如何寫一個類似的工具出來,從工具的屬性可以看出從中可以學到各種高階的字串處理(如符號高亮、程式碼提取等),算是非常不錯的 Swift 學習材料。

音視訊

? 深入瞭解 Flutter 的高效能圖形渲染

@CrazyCoderShi:本視訊為 Google Flutter 團隊的軟體工程師 Yuqian Li 在 2018 谷歌開發者大會做的演講,內容包含 Flutter 介紹,Flutter 的工作原理(對比原生開發和其他跨平臺框架),Skia 介紹,分析常見的效能瓶頸等,通過解決 Flutter 樣例 App - Flutter Gallery 的效能問題(Issue #13736),與大家分享如何通過 Flutter 工具定位、除錯和解決效能問題。

視訊主要討論點:

  • Flutter 為何能夠擁有媲美原生的高效能圖形渲染
  • 如何通過 Skia 除錯來分析 Flitter 應用
  • 關於 saveLayer 和 clipPath 的注意點
  • 使用 flutter screenshot 擷取 skp 來單步除錯繪圖指令

ggtalk | 向架構進發

@J_Knight_:本期 ggtalk 邀請的嘉賓是 Casa Taloyum,他所寫的 iOS 架構系列文章在社群非常受歡迎。本期主要圍繞“架構”這一主題,主要討論了以下幾點:

  • 做架構到底是在做什麼
  • 架構師和工程價值觀
  • 架構師和高階工程師的區別在哪裡
  • 如何定義真正的問題
  • 如何看待新技術和舊技術

除此之外,Casa 還分享了對跨平臺技術以及區塊鏈的一些看法。

推薦閱讀:

內推

老司機週報團隊聯合知識小集和 SwiftGG 翻譯組收錄了一份靠譜的內推職位。

如果你想找工作,點這裡:www.yuque.com/iosalliance…

如果你想招人,點這裡:www.yuque.com/iosalliance…

當然,也歡迎你關注我們每一期的週報,我們會在每期週報底部及時更新編輯內推崗位。

關注我們

我們開通了公眾號,每期釋出時公眾號(OldDriverWeekly)會推送訊息,歡迎關注。

老司機 iOS 週報 #64 | 2019-04-22

同時也支援了 RSS 訂閱:github.com/SwiftOldDri…

說明

? 表示需翻牆,? 表示編輯推薦

預計閱讀時間:? 很快就能讀完(1 - 10 mins);? 中等 (10 - 20 mins);? 慢(20+ mins)

相關文章