快速搭建“優(yōu)雅”的App----現(xiàn)在開(kāi)始做一些有價(jià)值的積累

引子:14天上線一款A(yù)pp?

14天上線一款A(yù)pp,相信為App應(yīng)用開(kāi)發(fā)的你一定類似的話不陌生。

有些老板,尤其是創(chuàng)業(yè)公司的老板,給出2、30個(gè)頁(yè)面的設(shè)計(jì)原型,然后會(huì)用這樣的言論加以鼓勵(lì)”:“14天上一款A(yù)pp,別人可以,我們一定也可以!加油!” 而且,不太了解技術(shù)的他們期望的不是首次上線,而是每次更新都可以保持這樣的速度——當(dāng)然,還不能有bug,用戶體驗(yàn)要優(yōu)良……

a. 有幸 我看過(guò)幾款這樣短期上線的App:
Demo1:這款A(yù)pp14天完成開(kāi)發(fā)上線,只有H5版,每次進(jìn)行頁(yè)面跳轉(zhuǎn),無(wú)論進(jìn)入新頁(yè)面還是點(diǎn)擊返回,都是頁(yè)面從右邊推進(jìn)來(lái)的切換效果……
Demo2:這款A(yù)pp快速上線,并經(jīng)過(guò)了1年半時(shí)間的維護(hù),接收到我們團(tuán)隊(duì)的時(shí)候,發(fā)現(xiàn)使用的是 “標(biāo)準(zhǔn)的MVC” 設(shè)計(jì)模式,隨便找一個(gè)VC,容納著2000多行的代碼……
DemoN:………………

b. 不幸 我暫時(shí)沒(méi)有看到過(guò)一款“優(yōu)雅”的快速上線的App。
“速度”與“優(yōu)雅”并存不可能實(shí)現(xiàn)么?
大公司可以實(shí)現(xiàn),因?yàn)橛小胺e累”。
小公司、個(gè)體戶,也可以實(shí)現(xiàn),如果去“積累”。

一、問(wèn)題:關(guān)于“積累”

1.1 怎樣才算“有積累”?

舉例來(lái)說(shuō),一個(gè)工作幾年的App開(kāi)發(fā),隨便寫幾個(gè)頁(yè)面,不應(yīng)該發(fā)生類似“數(shù)組越界”,“向數(shù)組添加空數(shù)據(jù)”這種低級(jí)原因而造成的應(yīng)用崩潰(若發(fā)生,他至少應(yīng)該感到內(nèi)疚);而且,他應(yīng)該可以提供出來(lái)一套方案,讓類似的問(wèn)題在別人做開(kāi)發(fā)的時(shí)候也不會(huì)發(fā)生。

1.2 可以從哪些方便的“積累”?

開(kāi)發(fā)經(jīng)驗(yàn)、技術(shù)選型、技術(shù)難點(diǎn)解決方案……方向很多。而我們今天想說(shuō)的,是從基礎(chǔ)支持模塊積累的角度,并期望提供一個(gè)能快速開(kāi)發(fā)一款新的App的積累方向。

二、 直入主題:App應(yīng)用框架

App應(yīng)用框架.png

如果基于應(yīng)用層面,你對(duì)此結(jié)構(gòu)表示認(rèn)同,那我們可以繼續(xù)進(jìn)行下去。首先 從底至頂 進(jìn)行簡(jiǎn)單的解釋:

2.1 第三方模塊

第三方模塊既然稱之為模塊,即它們是可以獨(dú)立存在的,即兩個(gè)第三方模塊間一般沒(méi)有必要的關(guān)聯(lián)(排除模塊聲明的庫(kù)間依賴)。所以將其放置到最底層,以被上層模塊依賴和調(diào)用。

第三方模塊的集成方式一般包含:sourceCode(源代碼),lib,framwork,cocoaPod
當(dāng)然,時(shí)下最流行和推崇的集成方式是cocoaPod。

2.2 基礎(chǔ)工具

我們姑且將工具分為 視圖工具支持工具
我們期望支持工具不依賴視圖工具。

支持工具:常見(jiàn)的如 防越界的取數(shù)組元素的方法支持(category)、屏幕大小獲?。ê甓x)、網(wǎng)絡(luò)請(qǐng)求(模塊)等。

控件工具:比如 Alert、Toast、網(wǎng)絡(luò)加載控件等。沒(méi)有“全局”概念的控件不建議放到這邊(比如兩個(gè)Vc的某個(gè)子視圖“長(zhǎng)相一樣”不建議將它當(dāng)做“控件工具”,太業(yè)務(wù)了)。

P.S. 我會(huì)建議將大多數(shù)的支持工具封裝成一個(gè)獨(dú)立的工具庫(kù),并支持pod導(dǎo)入。

2.3 應(yīng)用配置

應(yīng)用相關(guān)的配置信息隨著維護(hù)迭代會(huì)變得很多,我們給出的建議分類可以cover其中的大部分內(nèi)容:
xxxAppConfig:應(yīng)用啟動(dòng)配置
xxxAppContext:應(yīng)用運(yùn)行上下文支持
xxxYyyDefinitions:應(yīng)用宏定義,比如網(wǎng)絡(luò)接口、H5鏈接等

2.4 應(yīng)用頁(yè)面

我們耳熟能詳?shù)?MVC / MVP / MVVM / VIPER 等設(shè)計(jì)模式即是應(yīng)用在這邊的每一個(gè)VC(頁(yè)面)中。
無(wú)論是頁(yè)面的布局,還是數(shù)據(jù)的操作,他們會(huì)大量運(yùn)用 “基礎(chǔ)工具”,“第三方模塊”的支持。

頁(yè)面間,基于業(yè)務(wù)需求一般會(huì)有一些相互跳轉(zhuǎn)的依賴耦合(比如頁(yè)面A知道自己可能會(huì)跳轉(zhuǎn)到B或C),這是合理的,沒(méi)必要苦思冥想去解耦。(我見(jiàn)過(guò)有同學(xué)盲目“解耦”,用字符串的方式去獲取Vc類名,因不用再引入對(duì)應(yīng)Vc頭文件,美名曰“解耦”……根本沒(méi)有解耦好嘛!徒增代碼維護(hù)復(fù)雜性?。?/p>

但針對(duì)跳轉(zhuǎn)方法,進(jìn)行抽象統(tǒng)一,做一個(gè)路由模塊,則可以思考的方向(能實(shí)現(xiàn)什么呢?比如服務(wù)端修改一個(gè)配置,你的某個(gè)任何一個(gè)原生頁(yè)面可以動(dòng)態(tài)更改為一個(gè)H5頁(yè)面),非本文重點(diǎn),就不贅述了。

2.5 應(yīng)用控制

Appdelegate負(fù)責(zé)了整個(gè)應(yīng)用層面的關(guān)鍵消息處理,比如 應(yīng)用啟動(dòng)、最小化、接收推送 等。

那么,其實(shí)每一個(gè)處理流程,都會(huì)根據(jù)具體需求的復(fù)雜性抽象出一或多個(gè)模塊,比如啟動(dòng)流程管理、配置初始化等。

三、框架分析

3.1 支持模塊:第三方支持 & 應(yīng)用支持

常用模塊.png

我們依然 自底向上 依次說(shuō)起

3.1.1 建議的第三方工具庫(kù)

建議各個(gè)App開(kāi)發(fā)的同學(xué)根據(jù)具體業(yè)務(wù)需求參考集成下面 建議的第三方工具庫(kù)。針對(duì)建議的第三方工具庫(kù),都已經(jīng)支持了cocoaPod集成方式,下面是對(duì)應(yīng)的pod集成代碼參考。(一般建議先不加版本號(hào)集成最新版本,調(diào)通后再將版本限定死,防止不期望的更新)

pod 'AFNetworking', '~> 3.2.1'                      # AF網(wǎng)絡(luò)庫(kù)
pod 'WebViewJavascriptBridge', '6.0.3'              # H5 & 原生 交互支持
pod 'MBProgressHUD', '0.9.2'                        # “轉(zhuǎn)菊花”加載支持
pod 'MJRefresh', '3.1.12'                           # 處理scrollView頭部刷新
pod 'lottie-ios', '2.5.0'                           # 處理json動(dòng)畫
pod 'Masonry', '1.0.2'                              # Masonry 視圖自動(dòng)布局支持
pod 'YYCategories', '1.0.4'                         # YY 應(yīng)用基礎(chǔ)工具庫(kù)
pod 'SDWebImage', '4.0.0'                           # SD 圖片緩存加載支持
pod 'MLeaksFinder', '0.2.1'                         # 輕量級(jí)內(nèi)存泄露檢查工具
pod 'tingyunApp', '2.7.0'                           # [收費(fèi)] 聽(tīng)云App,應(yīng)用全面監(jiān)控分析
pod 'Qiniu', '7.1.8'                                # [收費(fèi)] 七牛暈存儲(chǔ),大文件存儲(chǔ)訪問(wèn)支持

pod 'UMCCommon', '1.5.1'                            # 友盟基礎(chǔ)組件
pod 'UMCPush', '3.2.1'                              # 友盟推送
pod 'UMCSecurityPlugins', '1.0.6'                   # 友盟安全插件
pod 'UMCAnalytics'                                  # 友盟分析
pod 'UMCErrorCatch'                                 # 友盟異常捕獲

3.1.2 建議積累的支持工具庫(kù)

xxx是指你的,或你的公司的縮寫,作為庫(kù)的前綴,一般用大寫,在3個(gè)字符長(zhǎng)度內(nèi)為益。

xxxToolkit

類似于上面提到的YYCategories,但我們總會(huì)有一些基本工具支持是YYCategories提供不完全的,我們可以在xxxToolkit中進(jìn)行補(bǔ)充。當(dāng)然,除了category之外,一些獨(dú)立的小工具模塊也可以考慮集成在xxxToolkit當(dāng)中。

xxxShare

分享永遠(yuǎn)用直接使用友盟支持么?不一定,基于第三方基礎(chǔ)支持封裝我們的自己的一層,是常見(jiàn)的做法。同時(shí),我們可以參考加入一些其他支持,比如你們公司的分享控件的展示效果(如果有統(tǒng)一的話)。

xxxNetwork

列舉一下常見(jiàn)的功能吧,看看你的網(wǎng)絡(luò)模塊是否已經(jīng)支持。
同步/異步 請(qǐng)求支持

Get/Post 請(qǐng)求支持
請(qǐng)求/答復(fù) 數(shù)據(jù)格式設(shè)置支持
公共請(qǐng)求頭/公共請(qǐng)求參數(shù) 設(shè)置支持
請(qǐng)求參數(shù)鑒權(quán)處理 回調(diào)支持
不持有請(qǐng)求對(duì)象發(fā)送請(qǐng)求支持
多個(gè)請(qǐng)求同時(shí)發(fā)起,并等待所有請(qǐng)求結(jié)束的支持(期望能捕獲失敗的請(qǐng)求)
多個(gè)請(qǐng)求順序發(fā)起,并等待最后一個(gè)請(qǐng)求結(jié)束的支持(期望中間請(qǐng)求失敗的時(shí)候可以結(jié)束請(qǐng)求)
網(wǎng)絡(luò)請(qǐng)求短期自動(dòng)緩存策略
快捷請(qǐng)求方法的封裝
請(qǐng)求答復(fù)的公共層自動(dòng)解析的 解析方法回調(diào)設(shè)定
請(qǐng)求錯(cuò)誤碼與提示信息的約定設(shè)計(jì)
等 O(∩_∩)O~

所以,或許你的網(wǎng)絡(luò)模塊還有很大的潛力呦!

xxxFeedback

用戶問(wèn)題反饋也是常見(jiàn)的功能模塊,當(dāng)然,這個(gè)模塊會(huì)需要一些產(chǎn)品設(shè)計(jì)甚至后臺(tái)的支持。當(dāng)前潮流會(huì)比較推崇截屏反饋。

xxxRouter

a. 為基本的頁(yè)面跳轉(zhuǎn)操作進(jìn)行約定封裝;
b. 實(shí)現(xiàn)頁(yè)面基于路由約定規(guī)范的跳轉(zhuǎn)(比如H5頁(yè)面向原生發(fā)一個(gè)符合約定的消息就可以打開(kāi)對(duì)應(yīng)原生頁(yè)面);
c. 實(shí)現(xiàn)目標(biāo)頁(yè)面的形式替換(比如通過(guò)在線修改一個(gè)配置就可以實(shí)現(xiàn)將App的某個(gè)原生頁(yè)面替換成對(duì)應(yīng)的H5頁(yè)面)。

3.1.3 建議積累的視圖工具庫(kù)

xxxCustomControl

包含一些基礎(chǔ)小控件(如toast,刷新icon)和自定義的系統(tǒng)控件(如 userdefTabbar, userdefNavbar, userdefPageControl, userdefSegmentControl 等)

TestEnvSwitch

需求說(shuō)明
測(cè)試同學(xué)根據(jù)測(cè)試進(jìn)度常常會(huì)需要不同環(huán)境的測(cè)試包(比如功能測(cè)試環(huán)境,集成測(cè)試環(huán)境,預(yù)發(fā)布環(huán)境,正式環(huán)境等),而我們的后臺(tái)針對(duì)不同的環(huán)境,往往請(qǐng)求的主機(jī)IP 或 域名是有差異的。為此,我們每次修改了代碼再打包給測(cè)試雖然不復(fù)雜,但次數(shù)多了,很是麻煩(我們自己切換環(huán)境調(diào)試也麻煩)。

所以,我們會(huì)期望針對(duì)App的測(cè)試包,集成一個(gè) 環(huán)境切換的頁(yè)面一個(gè)當(dāng)前環(huán)境的標(biāo)識(shí)(環(huán)境角標(biāo)),這樣,通過(guò)某種的方式打開(kāi)環(huán)境切換頁(yè)面(比如baseWindow懸浮一個(gè)功能按鈕,又或點(diǎn)擊5次tabbar首頁(yè)按鈕等),我們就可以在測(cè)試階段,永遠(yuǎn)都只提供一個(gè)測(cè)試包。只在最終打包上線的時(shí)候,修改一個(gè)類似buildForPublish概念的BOOL變量值,將環(huán)境切換等測(cè)試支持功能全部隱藏。

TestEnvSwitch模塊就是要提供一個(gè) 環(huán)境切換頁(yè)面,和一個(gè) 環(huán)境角標(biāo)控件

下面是一種 實(shí)現(xiàn)了基本功能,但異常丑陋 的環(huán)境切換頁(yè)面的參考。

環(huán)境切換頁(yè)面-簡(jiǎn)單丑陋版.png

根據(jù)各個(gè)公司實(shí)際情況,頁(yè)面可能支持更多的訊息或變得更美觀,甚至加入一些設(shè)計(jì)元素的支持,比如下面:

環(huán)境切換頁(yè)面-中級(jí)版.png

Vc Container

我們常常會(huì)用到Vc容器,即類似Tabbar這樣的包含多個(gè)子視圖的視圖容器。但切換效果上,我們或許會(huì)期望一些非系統(tǒng)默認(rèn)的,比如通過(guò)手勢(shì)左右滑動(dòng)可以滾動(dòng)視圖切換Tab,上下滑動(dòng)可以切換上下頁(yè)面等。 具體效果大家可以參考 【麥子金服財(cái)富】投資tab頁(yè)(左右切換容器子視圖),點(diǎn)擊一款投資產(chǎn)品進(jìn)入的 投資產(chǎn)品詳情頁(yè)面(上下切換容器)。

它們的實(shí)現(xiàn)一般是一個(gè)容器Vc包含多個(gè)子Vc,并將子Vc的視圖依次放置在一個(gè)ScrollView上面。這樣做的時(shí)候,交互方面還存在著不少脫離業(yè)務(wù)細(xì)節(jié)處理邏輯存在,所以建議能夠?qū)⑺鼈兂橄蟪鰜?lái),封裝對(duì)應(yīng)的Vc容器以便復(fù)用。

Share

這邊的分享指分享的頁(yè)面視圖了,積累一個(gè)常見(jiàn)的吧!你會(huì)發(fā)現(xiàn)尤其是創(chuàng)業(yè)公司,他們最喜歡現(xiàn)成的!

分享控件.png

Banner

感念就不解釋,建議可以約定一個(gè)BannerItem的數(shù)據(jù)結(jié)構(gòu),并提供pageControl的 顯示/隱藏/替換支持。

3.2 應(yīng)用配置

應(yīng)用配置.png

3.2.1 AppConfig

它可以包含:
a. App啟動(dòng)時(shí)需要更新的配置信息(一般運(yùn)行過(guò)程中不需要改變)
b. 第三方對(duì)接的固定配置信息(比如各平臺(tái)的AppId獲取)
c. 一些info.plist常用信息的獲取支持(也屬于配置)
d. 基于 測(cè)試/正式環(huán)境 獲取 測(cè)試/正式配置信息 的支持(比如請(qǐng)求主機(jī)地址/域名)

AppContext
應(yīng)用運(yùn)行過(guò)程中有一些屬性要頻繁使用并有可能改變,那么建議放在這邊,比如登錄賬號(hào)的緩存(加密根據(jù)需求考慮)、登錄狀態(tài)的記錄等。
注:如果只是局部場(chǎng)景的臨時(shí)變量,不要放在這邊,這邊的概念是全局

Definition
應(yīng)用不同概念模塊的宏定義,比如 網(wǎng)絡(luò)請(qǐng)求業(yè)務(wù)地址的統(tǒng)一定義、H5跳轉(zhuǎn)鏈接的統(tǒng)一定義 等。

3.3 應(yīng)用頁(yè)面

每款A(yù)pp具體的業(yè)務(wù)場(chǎng)景不同,但我們還是可以抽象出來(lái)一些公共的頁(yè)面概念,如下:

應(yīng)用頁(yè)面簡(jiǎn)單分類.png

3.3.1 頁(yè)面支持

3.3.1.1 BaseVc or VC AOP

BaseVc不用過(guò)多贅述,即每個(gè)ViewController都要繼承的Vc。但我們也可以考慮用另一種方式完成BaseVc的功能,即添加UIViewController的AOP(切面編程)。簡(jiǎn)單來(lái)說(shuō):
a. 寫一個(gè)UIViewController的分類
b. 使用runTime,在UIViewController中在一些方法中(比如viewDidLoad:)添加一些公共的代碼段。

3.3.1.2 測(cè)試引導(dǎo)頁(yè)

招聘流程上我們常??吹街T如“精通xCode的單元測(cè)試”的要求,但我想問(wèn)一下有過(guò)幾年iOS UI開(kāi)發(fā)經(jīng)驗(yàn)的同學(xué),你們有多少人真正在使用這樣的功能?使用的同學(xué)中,又有多少感到它的性價(jià)比很高?(比如3個(gè)月后是否還可以順利方便地使用)

單元測(cè)試(unit testing),本意是指對(duì)軟件中的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證。 然而,我們想想一下,互聯(lián)網(wǎng)時(shí)代一款頻繁迭代的App,我們對(duì)代碼中每一個(gè)函數(shù)去寫一個(gè)測(cè)試代碼的話……或許你維護(hù)測(cè)試代碼的時(shí)間都比它產(chǎn)出的效果多了!

這里,我們不繼續(xù)深入糾結(jié)“單元測(cè)試”本身,而是直接提出一種更適用于App的建議的測(cè)試方案——測(cè)試引導(dǎo)頁(yè)。

測(cè)試引導(dǎo)頁(yè)主功能示例.png

簡(jiǎn)單說(shuō)明下期中的關(guān)鍵功能模塊

1) 主測(cè)試頁(yè)面

包括 用例測(cè)試頁(yè)面按鈕、環(huán)境切換頁(yè)面按鈕、正常啟動(dòng)按鈕、臨時(shí)測(cè)試按鈕組、當(dāng)前環(huán)境角標(biāo)

2)用例測(cè)試頁(yè)面

這邊的用例一般建議分為 啟動(dòng)、功能、頁(yè)面 三個(gè)模塊。

  • 啟動(dòng) 是因?yàn)锳pp可能基于不同的場(chǎng)景有多套啟動(dòng)流程(咳咳,不過(guò)多說(shuō)明);
  • 功能 指一些獨(dú)立的功能模塊,比如H5 JSBridge回調(diào)接口的測(cè)試,網(wǎng)絡(luò)接口的測(cè)試等;
  • 頁(yè)面,App的重中之重,期望 每個(gè)頁(yè)面都可以有約定好的輸入信息,可以獨(dú)立打開(kāi),最起碼保證不會(huì)崩潰吧!同時(shí)也可以針對(duì)頁(yè)面的一些異常狀態(tài)進(jìn)行測(cè)試。
3)切換測(cè)試環(huán)境頁(yè)面 & 環(huán)境角標(biāo)

切換當(dāng)前的測(cè)試環(huán)境,一般是和后臺(tái)提供的服務(wù)環(huán)境支持相匹配的。

我們前面已經(jīng)在【TestEnvSwitch】一節(jié)簡(jiǎn)單聊過(guò)測(cè)試環(huán)境切換背景需求。那么,當(dāng)我們有了【測(cè)試引導(dǎo)頁(yè)】的時(shí)候,就可以不太關(guān)注開(kāi)啟環(huán)境切換頁(yè)的功能 的位置了。因?yàn)椋瑴y(cè)試引導(dǎo)頁(yè) 就是環(huán)境切換功能 最好的存在位置!

4)正常啟動(dòng)

上線的應(yīng)用包是怎樣的啟動(dòng)流程,它就是怎樣的。

5)臨時(shí)測(cè)試按鈕

不知道大家的習(xí)慣如何,我在擬寫一個(gè) 新頁(yè)面 或者 功能模塊 的時(shí)候,進(jìn)行簡(jiǎn)單的分析設(shè)計(jì)后,會(huì)把頁(yè)面或者模塊拆分成子頁(yè)面、子模塊,然后先從子頁(yè)面、子模塊開(kāi)始依次實(shí)現(xiàn),最后再進(jìn)行組合。
那么,在組合之前(子頁(yè)面、子模塊還沒(méi)有一個(gè)容器去測(cè)試的時(shí)候),臨時(shí)的測(cè)試按鈕就發(fā)揮了它們的功能,對(duì)應(yīng)的實(shí)現(xiàn)中寫一個(gè)視圖或視圖的操作方法(驗(yàn)證一些動(dòng)畫效果),進(jìn)行測(cè)試。

P.S. 設(shè)計(jì)

這樣的測(cè)試引導(dǎo)頁(yè)的劃分只是簡(jiǎn)單通用的一種實(shí)現(xiàn)形式。根據(jù)大家公司的具體需求和資源分配的可能,它完全可以采用其他的概念劃分方式,當(dāng)然,也可以更好看!

3.3.2 標(biāo)配頁(yè)面

時(shí)下流行的App都常常使用的頁(yè)面,比如 首次啟動(dòng)引導(dǎo)頁(yè);每次啟動(dòng)廣告頁(yè),后臺(tái)切換前臺(tái) 廣告頁(yè);封裝了 進(jìn)度條 和 一些支持 的網(wǎng)頁(yè)容器頁(yè) 等。

3.3.3 業(yè)務(wù)頁(yè)面

不是本文的重點(diǎn),而且基于每個(gè)應(yīng)用業(yè)務(wù)場(chǎng)景的不同,其業(yè)務(wù)頁(yè)面的具體劃分方式都不盡相同。

3.4 應(yīng)用控制

應(yīng)用控制層.png

3.4.1 AppDelegate

我們知道,AppDelegete掌管整個(gè)應(yīng)用生命周期的回調(diào)處理,它要處理的內(nèi)容還是很多的。所以,我們有必要進(jìn)行一些關(guān)鍵的概念模塊抽象。讓AppDelegate本身變得清爽一些。

說(shuō)明:
我們期望借由AppDelegate知道在應(yīng)用的生命周期,我們都做了哪些事情,而不是這些事情的細(xì)節(jié)。即:關(guān)注接口,不關(guān)注實(shí)現(xiàn)。

3.4.2 LaunchConfig

application:didFinishLaunchingWithOptions:方法中,我們App要做很多基礎(chǔ)配置的事情。比如 配置網(wǎng)絡(luò)主機(jī)域名,公共請(qǐng)求頭、公共請(qǐng)求參數(shù)、友盟對(duì)接、分享配置、客服配置、應(yīng)用安全配置、第三方登錄配置 等,這些配置的具體設(shè)置可以抽象一批方法。

3.4.3 VcLaunchManager

應(yīng)用啟動(dòng)過(guò)程中,常常涉及多個(gè)頁(yè)面,比如 首次啟動(dòng)引導(dǎo)頁(yè),廣告頁(yè),登錄頁(yè),手勢(shì)密碼頁(yè),指紋密碼頁(yè) 等。對(duì)啟動(dòng)流程相關(guān)的頁(yè)面加以管理,可以讓 啟動(dòng)流程進(jìn)行變化和調(diào)整的時(shí)候,修改起來(lái)更方便。

3.4.4 ExternalMessageHandler

外部消息處理。App可能不是通過(guò)正常方式啟動(dòng)的,比如推送啟動(dòng),3Dtouch啟動(dòng),又或被其他App調(diào)起。這些場(chǎng)景經(jīng)常會(huì)附帶一些額外的信息以期望額外進(jìn)行一些操作行為。這部分也建議抽象一個(gè)模塊將數(shù)據(jù)解析以及具體的操作行為進(jìn)行封裝。

4 總結(jié)

前面的內(nèi)容雖然簡(jiǎn)單,但信息量也不少,這邊,將我認(rèn)為最有價(jià)值的思路 & 亮點(diǎn)總結(jié)分享給大家,希望大家可以關(guān)注:

4.1 思路

4.1.1 時(shí)刻記得要分層

公司組織架構(gòu)要分層,代碼架構(gòu)一樣要分層,分層的思路如此經(jīng)久不衰,那么就自然有它的實(shí)踐的有效性!上層依賴下層,下層不關(guān)心上層——我們?cè)趯?shí)踐中或許會(huì)結(jié)合時(shí)間、資源等因素有一些靈活的調(diào)整,但我們要時(shí)刻在腦海中守住那個(gè)我們約定好的層次關(guān)系,知道調(diào)整只是Patch??蚣芊€(wěn)健才能有有效地豐富內(nèi)容、擴(kuò)展功能。

4.1.2 支持 & 配置概念要分開(kāi)

代碼支持應(yīng)用配置 都有“公共”的概念,但我會(huì)建議將其分開(kāi)。所謂“應(yīng)用配置”,是針對(duì)該應(yīng)用的,根據(jù)應(yīng)用的迭代更新,它是更容易發(fā)生改變(添加屬性、支持方法)的;而基本的支持(如Category),我們是期望可以抽象成庫(kù)(期望Pod支持)的。

4.1.3 將"支持模塊"封裝成庫(kù)

業(yè)務(wù)層面,公司規(guī)模不到,不要輕易嘗試抽庫(kù)去做所謂的“解耦”;
但針對(duì)公共支持,無(wú)論網(wǎng)絡(luò)、分享還是基本工具,建議我們有一套和業(yè)務(wù)無(wú)關(guān)的功能庫(kù)。

4.1.4 一定要使用CocoaPod

Pod集成方式統(tǒng)一,集成速度快,版本更新快捷方便,支持多種版本選擇方式,設(shè)置支持簡(jiǎn)單,而且主流的第三方代碼庫(kù)都已經(jīng)支持了Pod……這么好用的工具,給我一個(gè)理由不去使用!對(duì)應(yīng)的庫(kù)不支持Pod,好吧,這是個(gè)例外!

4.1.5 自定制你的App框架

關(guān)于我建議的App框架中包含的內(nèi)容,是最基礎(chǔ)和通用的內(nèi)容,我們?cè)诰唧w的開(kāi)發(fā)中,想要做到極致,會(huì)涉及到更多開(kāi)發(fā)模塊的需求,比如“日志模塊”,比如“音頻視頻模塊”,比如“測(cè)試浮層管理模塊”,比如“應(yīng)用數(shù)據(jù)收集模塊”……
他們都將成為屬于你們公司的積累、財(cái)富!當(dāng)然,也是屬于你的!

4.1.6 積累模塊就積累精致的

我們積累的模塊要極盡可能地精致合理(*效果理想,接口簡(jiǎn)單清晰8),如果我們積累的模塊是文章開(kāi)頭那種頁(yè)面切換無(wú)論進(jìn)入還是返回都是從右邊推進(jìn)來(lái)的效果的模塊(引子-Demo1,效果很不理想),我就只能翻個(gè)小小的白眼咯??……

4.2 亮點(diǎn)

4.2.1 環(huán)境切換功能(頁(yè)面+角標(biāo))

如果你們公司的后臺(tái)測(cè)試環(huán)境有多個(gè),還要針對(duì)每個(gè)環(huán)境打?qū)?yīng)的App包的話,建議考慮下環(huán)境動(dòng)態(tài)切換功能的集成,方便下測(cè)試同學(xué)吧!當(dāng)然,也方便了產(chǎn)品、運(yùn)營(yíng)包括我們開(kāi)發(fā)自己。
詳情參考【3.1.3-TestEnvSwitch】

4.2.2 測(cè)試引導(dǎo)頁(yè)

最早我只是寫了個(gè)獨(dú)立的頁(yè)面,在進(jìn)行新頁(yè)面開(kāi)發(fā)的時(shí)候可以進(jìn)行通過(guò)替換啟動(dòng)頁(yè)的方式方便小模塊的測(cè)試(真實(shí)的頁(yè)面場(chǎng)景太復(fù)雜,不方便簡(jiǎn)單功能的測(cè)試);后來(lái),用得多了,就進(jìn)行了進(jìn)一步的設(shè)計(jì):
a. 非線上包環(huán)境跳轉(zhuǎn)到測(cè)試引導(dǎo)頁(yè)面;
b. 線上包(只需要代碼中修改一個(gè)YES / NO)跳轉(zhuǎn)到正式頁(yè)面;
c. 同時(shí)測(cè)試引導(dǎo)頁(yè)包含 模塊測(cè)試入口、簡(jiǎn)單測(cè)試預(yù)留按鈕、線上包頁(yè)面的跳轉(zhuǎn)功能 等支持。

我不知道這種方式是不是全行業(yè)的首創(chuàng),但在我認(rèn)識(shí)的人中絕對(duì)是首創(chuàng)了,而且,用了的人都感覺(jué):嗯…不錯(cuò)!

正式/測(cè)試包啟動(dòng)邏輯.png

結(jié)語(yǔ)

小公司的第一版App真的無(wú)法集開(kāi)發(fā)快速、穩(wěn)定、可維護(hù)、可擴(kuò)展于一體么?不然,只要從現(xiàn)在開(kāi)始做一些有價(jià)值的積累就行!我們換到Android、后臺(tái)呢?其思路也是一樣的!
理清框架層次,積累關(guān)鍵模塊!

快嘗試一下吧!
遇到任何細(xì)節(jié)問(wèn)題,也歡迎在評(píng)論區(qū)與我討論:)

參考彩蛋

如果你還沒(méi)有自己完成一些基類庫(kù),下面的支持可以參考使用,有問(wèn)題可以評(píng)論留言,感覺(jué)方便的話別忘記star一下哦!

1 cyToolkit(xxxToolkit)

/* gitHub地址 */
https://github.com/chrisYooh/CYToolkit

/* pod參考 */
pod 'YYCategories', '1.0.4'
pod 'CYToolkit', :git => 'https://github.com/chrisYooh/CYToolkit.git', :commit => 'a43f808'

/* 說(shuō)明 */
以YYCategory為基礎(chǔ),封裝了一系列YYCategory沒(méi)有支持的
輕量級(jí)擴(kuò)展,建議和YYCategory搭配使用(沒(méi)有對(duì)YYCategory
直接依賴)。更新頻率不確定(看心情)。

2 CYNetworking
1 cyToolkit(xxxToolkit)

/* gitHub地址 */
https://github.com/chrisYooh/CYNetworking

/* pod參考 */
pod 'CYNetworking', :git => 'https://github.com/chrisYooh/CYNetworking.git', :commit => '6cb7f4e'

/* 說(shuō)明 */
以AFNetworking為基礎(chǔ),抽象了配置、請(qǐng)求、答復(fù)數(shù)據(jù)結(jié)構(gòu),
迎合當(dāng)前應(yīng)用場(chǎng)景常見(jiàn)請(qǐng)求的使用需求。更新頻率不確定(看心情)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容