項目 組件化

背景

最近公司主App3.0大升級 , 基本框架及大部分功能會參照另一個已有App, 為了方便升級以及后續兩個App的開發 , 經過開發與產品討論, 決定將已有App進行組件化

方案

組件化其實并不是一件全程明朗的事情, 在最開始定下使用cocoapods作為組件化的工具時, 開發只能根據目前App的功能點及功能間相關邏輯進行了一個簡單的分類 , 并且按照這個分類大致分為3個階段進行提測


image.png
image.png


組件化操作(參考之前寫過的工具類組件化步驟, 可以跳過)

  1. 創建一個測試的iOS工程


    image.png
  2. 在該目錄下創建一個 文件夾MeishaPod


    image.png
  3. 用命令行cd入MeishaPod中 并執行命令pod lib create MeishaTools

    image.png

    得到該文件
    image.png

  4. 把自已弄好的庫扔進這個弄好的容器中 ,Classes中的replace文件可以刪除掉


    image.png
  5. 在命令行中進入Example目錄下pod install;然后打開Example中的工程 ,發現庫已經全部進來了,并且是跟剛剛復制進Classes中的文件是一個源的。(既修改這里會改到Classes中的文件)

    image.png

  6. 修改這個庫中的信息->打開MieshaTools.podspec。


    image.png
  7. 要提交上gitlab上面,在我們寫的MeishaTools下面開始進行git操作

git init
git add .
git commit -m '描述'
git remote add origin https://gitlab.meishakeji.com/daniel/meishatools.git
git push origin master
image.png
  1. 接下來進入打tag環節,為什么要打tag呢?因為cocoapods要找到你這個庫必須是通過tag來找的,并且在MieshaTools.podspec中的信息中要更新你的tag;如果不寫,cocoapods發布你的庫時候會找不到你在git上的庫。
    可以這么理解 MieshaTools.podspec文件中的s.version就是 cocoapods要發布的你的庫的git上面的版本 一一對應
git tag 1.0.3
git push --tag
image.png
  1. 這時候我們要上傳到cocoapods了;用命令行進入MeishaTools,然后執行命令pod lib lint --verbose --use-libraries --allow-warnings
  • --verbose是查看打印的日志信息
  • --use-libraries 如果庫中使用到framework就需要加上
  • --allow-warnings 是忽略警告
  1. 如果顯示passed validation 就是證明編譯通過 那么就可以執行發布了 執行命令 pod trunk push MeishaTools.podspec --verbose --use-libraries --allow-warnings
    提交成功后那么這個庫就存在cocoapod上面了

  2. 使用這個庫 要cd進iOS測試工程根目錄中pod init 然后在podfile中導入這個庫
    然后繼續再執行命令pod install就可以再我們工程中使用這個基礎工具類的庫了

    image.png

image.png


組件化過程

第一階段

  1. 根據預定目標 , 首先進行項目主框架的組件化 , 這一過程涉及三個點: 1. 項目的基礎工具類 2. 項目的基礎UI類 3.項目的框架結構類為了增加組件的通用性, 把工具類和基礎UI類另外抽成了兩個組件
    image.png

    在這一過程中, 由于視頻上傳和視頻轉場工具涉及到FFmpeg, 在進行組件化時, 這兩部分暫時沒有封進組件中(此過程相對比較順利, 因為底層組件及控件一般不涉及業務, 組件化也就簡單得多)
  2. 學生列表模塊/登錄模塊/微主頁模塊的組件化, 這三個模塊除了登錄模塊為了迎合兩個App不同的彈窗邏輯, 做了較大改動, 另外的兩個模塊則十分順利的完成了

第二階段

  1. 營期相冊/班級課表/班級空間 這三個模塊組件化時, 因為模塊內部沒有與其他模塊的關聯邏輯, 也沒有跳轉邏輯, 因為組件化十分快速順利
  2. 在班級動態組件化時, 由于第一階段的視頻上傳模塊沒有完成, 因此大部分時都在處理FFmpeg及視頻上傳模塊的組件化
  3. 成長記錄的數據結構大部分是跟其他組件相關聯, 并且有些處理邏輯也和對應組件有聯動, 因此把成長記錄的組件化放到最后, 等所有的其他模塊組件化完成再考慮這個模塊
此外, 由于成長手冊中使用的轉場工具類是Swift與OC混編, 而在組件內不支持swift類轉oc頭文件使用, 因此在該模塊浪費了大量時間之后決定暫不進行組件化, 直接復制到兩個項目中使用
image.png

第三階段

  1. 通訊錄及聊天模塊處理時, 考慮到聊天的表情包處理相對較獨立, 所以把它獨立成一個小組件, 并且后面發現除了通訊錄模塊需要依賴這個小組件, 在消息首頁的顯示也需要, 剛好減少了后期重新再次拆分的工作量


    image.png
  2. 班級通知/學生作業/課程直播, 單個模塊組件化基本按照前面的步驟進行, 把關聯其他模塊的邏輯釋和/耦合嚴重的代碼暫時注釋掉

到這個階段, 基本上大部分的模塊已經組件化完成, 除了消息模塊中涉及大量其他模塊的消息類型, 還有成長記錄涉及其他模塊的入口管理和記錄顯示問題


第四階段(在提測后繼續進行)

  1. 在成長記錄頁面上, 頂部控件顯示管理著其他各個模塊入口 , 底部列表顯示各種其他模塊類型的記錄數據 , 因此跟其他模塊會有很大的耦合性


    image.png

    為了解決這個問題, 參考之前看過的路由實現模式, 最后決定采用注冊組件的方式 , 由App進行管理注冊顯示的模塊入口


    image.png
在App啟動完成后, 第一時間注冊應用入口, 并且配置相關信息, 包括組件的入口/標題/圖標和應用Id, 同時注冊一個初始化時特殊處理的回調, 方便一些組件的特殊配置; 注冊完成后, 在成長記錄組件內請求接口獲取應用列表時就可以根據注冊的組件map來匹配并展示模塊入口以及跳轉進組件內部
image.png
  1. 在處理底部展示的數據列表時, 由于之前已經考慮過多模塊的情況, 因此成長記錄的數據模型會通過一層中間層把各種模塊的數據模型處理為統一的數據結構,再進行展示; 因此在組件化時, 把中間處理層也封裝為注冊管理對象, 在獲取數據后通過回調, 交給外界來處理


    image.png
  2. 除了成長記錄關聯性高, 首頁消息模塊的關聯性也高(班級通知/學生請假/直播通知/教學反饋/作業通知), 并且有更多的組件間跳轉邏輯; 為了統一組件邏輯, 這里也同樣用了跟成長記錄一樣的方式, 通過注冊來管理各種消息類型


    image.png

    同樣為了解耦和靈活性, 也有一個進入消息詳情時的回調


    image.png
  3. 最后一步, 處理每一個組件內部需要跳轉到其他組件的耦合邏輯; 這里有考慮過市場上已經成熟的一些路由第三方庫, 但是大部分都比較復雜并且除了模塊路由還有scheme路由/URI路由等等, 對于我們的項目來說, 只需要用到模塊路由, 因此決定不使用這些庫, 而是自己寫一個路由管理組件之間的邏輯


    image.png
  4. 首先在每一個模塊的頭文件中定義好模塊內部需要跳轉其他模塊的跳轉唯一Id


    image.png
  5. 然后同樣在app啟動后, 注冊該跳轉Id對應的實際跳轉的位置


    image.png
  6. 最后在模塊內部通過跳轉id 跳轉的對應的頁面并傳遞必要數據


    image.png
通過這種注冊跳轉Id的方式, 模塊內部只需要告訴外界內部有這么一個跳轉事件, 而不需要知道具體要跳轉的頁面是哪里, 完全交給外界來控制, 從而達到解耦

其他遇到的問題

1. 多架構問題

組件化時經常驗證組件有效性時無法通過, 查看verbose相關信息后, 發現是編譯鏈接i386架構時報錯, i386是mac上32位模擬器的支持架構, 因此直接在.podSpec中配置指定驗證的架構, 去掉i386 s.pod_target_xcconfig = { 'VALID_ARCHS' => 'x86_64 arm64 arm64e armv7' }

2.FFmpeg的取巧組件化

在封裝FFmpeg作為底層組件時, 由于源代碼包含.c .m , 而在組件內不支持引入C++系統模塊, 因此一直會報錯, 最終想出了一個比較繞彎路的方法: 首先新建一個靜態庫工程, 將FFmpeg中包含的.a文件, fdk-aac-ios插件, x264-iOS插件都拖入工程內


image.png

再將FFmpeg的工具處理源代碼以及OC管理工具加入工程中


image.png

根據報錯信息處理ffmpeg_filter.c中的相關代碼后, 將該工程編譯成一個x86_64架構的模擬器靜態庫, 以及一個arm64架構的真機靜態庫, 并用 lipo工具將它們合并成一個.a多架構靜態庫, 最終放到VSBaseFFmpeg組件中, 完成FFmpeg的組件化

3. 調試與代碼同步

前面也說過, 之所以決定將已有App組件化, 是為了方便梅沙教育的升級以及后續兩個App的開發, 但是cocoapods組件化時 , 如果通過私有索引庫來鏈接到每一個組件的話, 每一個組件都是一個靜態庫, 對于靜態庫內部的代碼是無法修改和調試的; 并且對于組件內部的每一次修改都需要重新提交上傳打Tag, 再發布到索引庫中, 然后才能更新, 不管是多人還是單人開發時都十分麻煩

  1. 為了解決這兩個問題, 首先采用cocoaPods的本地引用方式來引用模塊, 這樣就可以直接調試組件內部代碼
    image.png
  2. 查閱資料時發現git本身有子模塊管理邏輯, 并且能做到僅引用子模塊而不需全部下載, 某個子模塊的提交有更新也可以及時提醒并更新該子模塊, 基本上完全能解決現有問題, 所以最后決定不使用cocoapods的三方庫管理模式, 采用git子模塊管理

將兩個以及組件文件夾放到同一個目錄下, 以統一引用組件的的相對路徑 , 然后通過git命令產生子模塊關聯git submodule add [子模塊的git地址] [子模塊名]
image.png
最終git父模塊將會依賴于各個git子模塊, .gitmodules 文件會有如下配置信息
image.png
在多人開發時, 直接拉取git父模塊就可以擁有兩個項目及關聯的組件庫
  1. 第一種拉取方式
    git clone xxx.git
    這樣拉取下來的項目只有目錄, 目錄里面都是空的, 只有配置文件和依賴關系, 需要另外一部子模塊操作
    git submodule init
    git submodule update

    image.png

  2. 第二種拉取方式
    git clone xx.git --recurse-submodules #遞歸拉取子模塊

  3. 我們的項目中有一些文件比較大, 而gitlab服務端的設置有限制, 可能會導致一些組件拉取失敗, 這時候可以用下面這個命令, 讓每一個子模塊執行checkout命令
    git submodule foreach git checkout master



最終項目組件結構如下:

image.png

項目組件化進行到這里已經基本上成功了, 剩下的是一些比較小的耦合邏輯, 會在之后的版本開發時慢慢解決

總結

  1. 完成組件化后, 對于之后的版本, 開發起來會變得更加巴適, 代碼管理也會規范, 業務邏輯同樣會更加清晰;
  2. 組件化過程最大的收獲是對于耦合邏輯的解耦思考, 代碼也變得更加健壯了;
  3. 這次項目組件化, 是對個人能力的一次巨大提升, 在以后編寫代碼時也會更加多的注意耦合及靈活性;
  4. 希望能找時間把教師端也組件化了(造福后人)。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容

  • 一、背景 隨著APP版本不斷的迭代,新功能的不斷增加,業務也會變的越來越復雜,APP業務模塊的數量有可能還會繼續增...
    please邊去閱讀 553評論 0 1
  • 1、為什么要項目組件化 隨著 APP 版本不斷的迭代,新功能的不斷增加,業務也會變的越來越復雜,APP 業務模塊 ...
    dashu52閱讀 1,539評論 0 3
  • via --- EyreFree 零. 前言 “蜂鳥配送商家版”是一款針對商家打造的專業配送軟件,有了這款應用,您...
    其實也沒有閱讀 1,414評論 0 7
  • 單項目結構: 將程序的所有功能以及依賴庫都集中在一個項目下進行管理,不同業務或非業務通過包名區分,使得項目結構清晰...
    _Sisyphus閱讀 939評論 0 2
  • 需求前提:希望App由多個業務組件組裝起來,每個業務模塊都可單獨成為子App。解耦,快速開發! 流程 創建遠程私有...
    Baffin閱讀 1,055評論 0 7