開發一個 iOS 應用你所需要做些什麼呢?
從 07 年到現在,iOS 開發也近乎 10 年的時間了,隨著 iOS 版本的一步步更新, Xcode 慢慢的穩定,社群的力量也隨之變的越來越大,有很多工具可以幫助我們快速去搭建一個 App。
但是 一個 App 想要穩紮穩打,不畏懼任何版本迭代和業務變化,那麼需要做的事情還是很多的,良好的 App 架構和前期的程式碼規範,以及效率工具的使用會使得整個 App 的迭代變的有條不紊,這也避免了後續大的迭代和更新的時候導致程式碼變的散亂。接下來我簡單介紹一下這方面的內容,下面是一個腦圖,裡面的內容我將一一展開解釋。
前期準備
程式碼規範
程式碼規範的重要性是重中之重,這也是筆者最為看中的一點。這裡有 Code Rivew
機制,指定一些紅線標準來一步步落地。切記:能跑起來不是目的
Git 程式碼管理
- 這裡推薦使用 Git 來管理自己的專案,可以使用
- 平時編碼的時候可以使用 SourceTree 這個軟體來進行程式碼的 push, commit, merge 等操作。當然了,筆者還是習慣使用命令列來做這些事情,因為 SourceTree 偶爾也會抽風,已經不只一次的出現過了。
- Git-flow 的工作流程,這篇文章詳細的說明的 git-flow 的使用方法。在多人團隊開發的時候非常受益!建立自己的
master
,develop
,feature
release
等程式碼分支,以便可以在各個分支之間切換自如。 - 在 Git 提交時可以使用
[新增]
,[修改]
,[刪除]
,[修復]
,[更新]
等字首詞語來表明當前的 Commit 資訊,規範化的 commit 資訊能夠一瞬間的告訴別人你幹了些什麼,防止自己忘記,避免團隊成員看不懂。具體參見這裡 - 程式碼 Review。可以使用 github 或 gitlab 自帶的Merge Request 來進行程式碼 Review。同時還可以使用 Phacility,這裡就不做過多的闡述。
Jenkins 持續整合
持續整合完美的解決了開發者的一個痛點,那就是避免 QA 同學頻繁的找你打包。那麼 Jenkins 將會是一個很好的選擇,它可以同時支援 iOS 和 Android 平臺。持續整合的複雜性也足夠用幾篇文章來描述了,Google 一下會有很多教程。這裡介紹一篇博文供參考:手把手教你利用 Jenkins 持續整合 iOS 專案
Crash 收集平臺
- iOS 日常的 Crash 問題收集我們可以採用一條龍服務的: Fabric,騰訊 Bugly , 友盟,或者是開源系列的:KSCrash。可以自己搭建一套收集 Crash 的平臺來滿足日常的 Crash 收集問題。
- 蘋果 Crash 收集服務。通過 iTunes Connect 獲取使用者的 Crash 日誌。在 XCode 中 Window->Organizer->Crashes也可以看到同樣的 crash 日誌。收集 Crash 功能需要使用者設定->隱私->診斷與用量->診斷與用量資料選擇自動傳送,並與開發者共享即可。這個成本太高,不推薦使用。
中場實戰
好了,至此前期準備內容做完後,可以建立自己的專案工程了,我們的工程中 Podfile 裡應該有一定的內容了,什麼??Pod 各種出問題?那麼我們可以使用這篇教程來搭建 Pod。好了,接下來我介紹一些日常開發所需要的內容。
工程結構
現階段的 iOS 工程基本可以分為 All-In-One
(指的是業務程式碼) 和 模組化
這兩種工程結構。小專案筆者認為暫時沒有必要使用模組化,因為每次的 pod install
和 pod update
成本其實也不低。對於 All-In-One
的專案工程,筆者更不建議把所有工具類,通用類等都放入到 .pch
檔案裡,因為這會使編譯速度變慢,另外如果你的工程以後有可能 模組化
,那這以後將是一個巨大的災難。
脫離業務邏輯的工具類(Category)
工具類能夠幫助我們快速的實現我們想要的內容,並且保證程式的健壯性和程式碼的全域性性,比如我們常見的 NSArray
的安全訪問或安全新增所有資料的方法,這個方法可以有效的抑制我們所出現的陣列越界或者添加了一個 nil 物件所引起的閃退問題。
|
|
諸如上面對 iOS 中 Foundation 和 UIKit 的擴充套件和工具類有很多,可以選用 YYCategories 或者 JKCategories 來作為我們的工具類,並且最好以 CocoaPods 的形式引入。並且在程式碼 Review 的時候注意開發者的使用是否合理和規範,避免重複造輪子。
第三方庫的使用
第三方庫能夠幫你大大的提升開發效率,比如 Objective-C 中著名的 AFNetworking,SDWebimage,Swift 中著名的 Alamofire,Kingfisher 等開源庫。那麼我的建議是這些脫離業務邏輯的庫最好不要拿來直接用,我們可以對它進行自己的封裝。比如 YTKNetwork 就是對 AFNetworking 的一個很好的封裝。當然瞭如果你的 App 沒有那麼的複雜,其實也可以自己簡單的封裝一下。
|
|
UI 實現
團隊開發,筆者建議儘量使用程式碼的方式來進行 UI 佈局。如果對滾動幀率和效能有極高的要求,可以選用 AutoresizingMask,具體可以看這篇文章的描述。但是如果需要適配 iPad,或者有轉屏的需求,那麼還是建議使用 AutoLayout 來處理,可以使用 Masonry 這個框架來實現。總之無論是 AutoresizingMask 還是 AutoLayout,只要團隊統一就好,這也利於日後的維護和更新。
設計規範
對於 App 中每個字型的大小,顏色等內容我們可以定義一套 UIFont
,UIColor
的擴充套件來實現,並且我們可以和設計師溝通來使用字型編號,顏色編號進行標註。下圖就是展示這種程式碼式的標註:
另外對於切圖的內容,最好 2x 和 3x 的圖分開切,每個圖片我們還可以使用 TinyPNG 來進行一次壓縮,這樣也可以省一部分的 App 體積。
統計埋點
移動網際網路的時代,大資料的舞臺,埋點也是相當重要的,良好的的埋點 API 設計對程式碼的解耦也是非常有利的。
- 我們可以選用 騰訊 MTA 資料統計 這種第三方統計服務。
- 由於隱私性,我們也可以自己來實現一套埋點方案和設計。如果沒有選用 MTA 服務,那麼筆者建議下載 iOS 的 MTA 框架 並參考標頭檔案中的內容進行自己 API 的設計。切記要
高度解耦
,易擴充套件
,即便是上下文的內容,也可以使用引數的形式來傳遞。 - 無痕埋點,iOS 有 Aspects 這種 AOP 的框架可以實現無痕埋點,比如日常的 ViewController 的生命週期,使用者流轉路徑等等。當然了,如果是點對點的資料統計,還是建議我們使用上述的內容來完成這樣的需求。
配置中心
國內 App 的動態化需求還是非常旺盛的,比如我們經常要根據伺服器返回的資料進行 App 的動態調整。那麼和伺服器下發配置的時候,我們最好按照優先順序且在不影響啟動的情況下進行分佈請求。比如電商系 App :
- 基礎配置:一些基礎的內容比如必須是第一階梯的請求。例如:
伺服器時間
,AccessToken
等等。 - 大促:雙 11 大促來了,首頁要有個彈窗之類的邏輯控制,也會是伺服器下發的配置。那麼諸如此類的可以放到第二階梯的請求中。如果服務端同學強烈要求放在第一階梯的話,我們需要跟他們講清楚啟動時間對使用者體驗的重要性。
- 安全性:無論是什麼配置,我們都需要進行安全性和準確性的校驗,所以在這類的請求中。我們需要一套完善的機制來防止出現各種異常,對於這些配置的下發,App 要有頑強的容錯能力。
- 面板,主題檔案:很多 App 都會有夜間模式,換膚等功能。比如手機 QQ,手機淘寶等。那麼類似這種換膚的功能,筆者建議可以使用
.zip
包的形式來進行資源整合。因為一套面板的圖片可能會比較多,另外加上各種 2G, 3G 等異常網路情況的出現,客戶端批量下載圖片進行完整性和準確性的校驗成本會大大增加。但是一個.zip
包檔案既可以解決資源是否下載完畢的問題,又可以一瞬間切換主題,使用者幾乎是 0 感知,體驗也會非常贊。
Mock 資料
假資料的製造方法有很多種,筆者認為最妙的莫過於是使用 Json-server 來搭建的服務。我們可以把它部署到伺服器,並且只要上傳一段 json 檔案,就可以返回你想要的資料,這也不影響你的開發進度,而且讓這個過程變的很容易。
單元測試
一般小專案幾乎很少會寫單元測試的,因為在當前這個追求快速迭代和堆積業務的環境中,單元測試各種被無視。筆者認為非常重要的業務邏輯可以對資料等內容做單元測試,我們可以使用 Xcode 自帶的測試框架 XCTest 來進行。但是當我們實現時候,不可避免的要去儘可能少的例項化一些具體的元件來保持測試既短又快,但現在的開發中,測試的元件很可能會有幾個依賴的物件,我們需要用創造一些假的 Object 來替代例項化具體的依賴 Class,這時候你可能會使用到 OCMock 這個框架了。這樣也可以快速幫你驗證自己的業務邏輯。
通用的 WebViewController
移動開發的領域難免需要使用 WebView 搞一些事情。那麼 JavaScript 和 native 的互動就顯得十分有必要了。你可以使用 WebViewJavascriptBridge 來實現和 native 的互動。
持久化快取
說到快取,日常開發中我們基本都是在操作記憶體。像諸如圖片這種,SDWebimage 已經幫我們實現了。那麼剛才提到伺服器下發的配置,還有首頁的內容,筆者認為還是有必要快取一份在本地,為什麼呢?因為 App 啟動無網路化是強烈依賴快取的。無網路化可以大大提升啟動效率,並且首頁是有內容可以見的,這並不影響使用者體驗。iOS 的本地持久化方案有很多種,有直接寫檔案,NSKeyedArchiver 歸檔,還可以用 NSUserDefault,FMDB,LevelDB,Realm 等等。選擇適合自己的就可以,記住 database 一定要跟業務解除繫結,它僅僅是為上層 UI 提供資料而已。
服務端異常 Log 上報
很多時候我們會遇見一些因為服務端資料所產生的業務邏輯的問題。這時候運營或者測試同學可能第一個找的就是客戶端研發,因為表現層是在客戶端的(T.T)。針對這個問題,筆者認為客戶端和服務端返回的各種資料異常都應該有一個異常上報的過程。比如我們可以通過如下格式來進行上報:
|
|
如果以上內容上報到伺服器,那麼運營同學和測試同學就可以第一時間排查是否是資料問題引起的使用者介面異常。那麼可能你會說:運營和測試怎麼知道他們的 userId
呢,彆著急,往下看彩蛋的內容。
除錯彩蛋
不知道你是否記得新浪微博有一個線上版本把除錯選項
露出來了。如下圖所示:
功能非常豐富,開發者的除錯利器。其實上述的內容我們就可以指定在一個特殊的網路環境開啟(比如 WiFi 名稱為 “yourcompany-inc”),或者在 debug 模式下開啟。除了上面的內容,我們還可以設定本地資料檢視
,刪除快取
,併發請求測試
,觸發記憶體警告
,流量統計
,網路監聽
,FPS 頁面監聽
等功能。這部分內容可以大大的促進日常開發和 debug 的效率。
A/B Test
良好的資料埋點和 A/B Test 一結合那麼就是現在流行的 Grouth Hacking 的基礎,並且可以達到 灰度釋出
,方案可逆
,資料驅動
的目的。
開花結果
經過了半個月的迭代,好了。App 終於有了它的雛形,那麼後期就等著 App 順利上線了,但是別忘了還有下列事情需要做的:
Bug 統計平臺
測試和研發應該是患難兄弟,有 bug 了我們統計到一個平臺,方便以後的覆盤和總結。你可以使用 Teambition 或者 Tower 來到達這個目的。當然了,重要的是在以後的迭代過程中避免栽倒在一個地方。
App 簽名和自動上傳
前面的準備工作提到過利用 Jenkins 這個神器來進行持續整合的工作,那麼我們同時需要在這個平臺整合自己的 App 重簽名和上傳等機制。我們可以使用 Xcodebuild 指令碼或者 Fastline 來實現。當然了,我們還可以選擇使用 Fir.im 或 蒲公英 這樣的應用託管服務。
灰度釋出
iOS 中的灰度釋出比較受限制。廠內灰度可以使用 TestFlight 來做,或者徵集一批 App 的忠實使用者,可以達到 2000 名的灰度效果,這部分使用者可能只是在幫助我們測試是否有嚴重的 bug 等。但是有些功能我們還是需要釋出到 App Store 後進行灰度的,這種情況下我們只能根據配置來進行了。
好了,以上內容基本是一個 App 所需要做的事情。每個節點的內容都可以深挖許多內容,筆者沒有做過多的解釋。如有出入,還忘指出。