組件化實踐

最近想了解一些組件化的知識,去看了Casa寫的iOS應用架構談 組件化方案這篇文章,Casa在文中針對蘑菇街的組件化方案提出了一些不一樣的觀點,陳述了本身的組件化方案。html

大神們討論具體的實施方案,是對理論的描述,在架構層面來分析利弊,我看過以後感受仍是有點晦澀,具體的方案異同之處咱們先不說,今天咱們先從應用着手,在本身當前的工程實施組件化。ios

固然了,咱們選擇使用的方案是Casa的CTMediatorgit

準備

首先咱們得先了解組件化這個概念,其實通俗的講,就是把咱們的項目拆解成一個一個的小組件分別管理。咱們平時使用cocoapods繼承的三方的庫,能夠理解成是一個公有的組件。咱們項目中,也能夠把一些模塊拆解出來,使用cocoapods來集成。這樣拆解成一個個的組件的好處有不少,好比說業務模塊之間解耦,複用模塊,節省編譯時間等等。github

因此咱們要先學會建立cocoapods私有庫。json

這裏多說一句,Casa的組件化方案在實施的時候,每獨立出來一個組件,就會相應的建立一個Category工程,做爲中間的調度,因此說,咱們每作一個組件,就要建立兩個私有的pod工程。緩存

咱們結合Casa這篇在現有工程中實施基於CTMediator的組件化方案,來作一下補充或者說是註解吧,本文中的流程取自於上文。架構

建立私有Pod工程

1. 先去開一個repo,這個repo就是咱們私有Pod源倉庫
2. pod repo add [私有Pod源倉庫名字] [私有Pod源的repo地址]
3. 創立一個文件夾,例如Project。把咱們的主工程文件夾放到Project下:~/Project/MainProject
4. 在~/Project下clone快速配置私有源的腳本repo:git clone git@github.com:casatwy/ConfigPrivatePod.git
5. 將ConfigPrivatePod的template文件夾下Podfile中source 'https://github.com/ModulizationDemo/PrivatePods.git'改爲第一步裏面你本身的私有Pod源倉庫的repo地址
6. 將ConfigPrivatePod的template文件夾下upload.sh中PrivatePods改爲第二步裏面你本身的私有Pod源倉庫的名字

首先咱們先建立一個名爲Project的文件,而後把咱們項目的主程序,咱們叫作MainProject放到Project路徑下,而後在Project路徑下clone出咱們須要的腳本(Casa提供)組件化

在~/Project下clone快速配置私有源的腳本:
git clone git@github.com:casatwy/ConfigPrivatePod.git

如今咱們的文件目錄結構是這樣的。this

Project
├── ConfigPrivatePod(腳本文件)
└── MainProject

在Project路徑下建立咱們的組件工程(一個普通的iOS工程),咱們把這個工程名字叫PayComponents (模擬抽取項目中的支付模塊)。spa

當前目錄結構

Project
├── ConfigPrivatePod
├── MainProject
└── PayComponents

有了本地的工程以後,咱們如今須要建立一個repo,做爲咱們的私有pod源倉庫。也就是在github,或者gitee(碼雲)上面建立一個項目,放咱們的項目代碼,命名PayComponents。

而後呢,咱們還須要建立一個東西,就是私有Pod源倉庫名字。

pod repo add [私有Pod源倉庫名字] [私有Pod源的repo地址]

落實到咱們這個項目中,咱們應該這樣寫。

pod repo add PayComponents https://gitee.com/LittleBin/PayComponents.git

那這到底表明着咱們建立了什麼?

咱們打開finder->前往->前往文件夾,而後輸入~/.cocoapods/repos

能夠看到目錄是這樣子的

1.png

repos路徑下面有一個master,一個payComponents。這兩個文件夾咱們能夠粗略的認爲他和pod search還有install有關。

打個比方就拿search來講,咱們查詢一個庫的時候會用下面這個命令

pod search AFNetworking

而後會從master路徑下找到AFNetworking,而後列出來他有哪些版本什麼的。咱們有的時候會發現一個庫其實已經跟新到2.x.x版本,可是咱們search出來只有1.x.x,這也多是咱們的cocoapods沒有更新,咱們的master路徑下沒有新的版本。

這個PayComponents文件夾,就表明咱們本地有一個私有的pod庫。咱們search的時候,也會查這些本地的私有庫。

下面把遠程的這個repo和咱們本地建立的項目關聯到一塊兒,這個工做Casa給咱們提供的腳本就能夠完成,順便還會幫咱們生成.podspec的文件,具體這個文件的做用咱們後面再說,還會初始化podfile。

咱們進到ConfigPrivatePod文件中,執行config.sh腳本,而後在終端根據提示輸入就好了。

[localhost:ConfigPrivatePod sunxiaobin$ ./config.sh 


Enter Project Name: PayComponents
Enter HTTPS Repo URL: https://gitee.com/LittleBin/PayComponents.git
Enter SSH Repo URL: git@gitee.com:LittleBin/PayComponents.git
Enter Home Page URL: https://gitee.com/LittleBin/PayComponents

================================================
  Project Name  :  PayComponents
  HTTPS Repo    :  https://gitee.com/LittleBin/PayComponents.git
  SSH Repo      :  git@gitee.com:LittleBin/PayComponents.git
  Home Page URL :  https://gitee.com/LittleBin/PayComponents
================================================

confirm? (y/n):y
copy to ../PayComponents/FILE_LICENSE
copy to ../PayComponents/.gitignore
copy to ../PayComponents/PayComponents.podspec
copy to ../PayComponents/readme.md
copy to ../PayComponents/upload.sh
copy to ../PayComponents/Podfile
editing...
edit finished
cleaning...
Initialized empty Git repository in /Users/fmb/Documents/LEARN/Project_test/PayComponents/.git/
clean finished
finished
localhost:ConfigPrivatePod sunxiaobin$

Enter Project Name:的時候,後面的名字必定要跟咱們建立的PayComponents工程同樣,要否則腳本找不到文件,就配置不了。

腳本跑完以後PayComponents裏面變成下面這樣子。

2.png

咱們要修改一下Podfile文件和upload.sh。下面是生成的Podfile文件裏面的內容

# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'

source 'https://github.com/ModulizationDemo/PrivatePods.git'
source 'https://github.com/CocoaPods/Specs.git'

use_frameworks!

target 'PayComponents' do
 
end

由於腳本都是照着模板來生成的這些文件,上面是podfile文件裏面的內容,咱們要把第一個source後面的'https://github.com/ModulizationDemo/PrivatePods.git'改爲咱們這個庫的地址,https://gitee.com/LittleBin/PayComponents.git

而後在upload.sh中,最後一行

pod repo push PrivatePods PayComponents.podspec --verbose --allow-warnings --use-libraries --use-modular-headers

把PrivatePods替換爲咱們上面的私有pod庫名稱。
也就是咱們以前執行的下面這個命令中的PayComponents。

//不用重複執行
pod repo add PayComponents https://gitee.com/LittleBin/PayComponents.git

咱們在看一下PayComponents項目文件的結構,腳本給咱們生成了一個空的PayComponents文件。

3.png

咱們須要把這個文件拖拽到咱們的項目中

4.png

而後咱們這個PayComponents組件的文件就所有放到這個路徑下。咱們的私有庫暫時就先寫到這裏。下面建立咱們的Category工程

建立Category工程

由於篇幅緣由,這裏我把建立Category工程略過一下,不一一展現了。

其實按道理說在實際項目中,這個Category工程也要作成私有庫的,就像咱們上面說的步驟,先建立本地工程,建立遠程的repo,而後建立本地私有庫(pod repo add ...),在用腳本關聯本地和遠程的庫,而後修改Podfile和upload.sh等等這一整套步驟。

最終Category項目的結構是下面這樣的。(包含爲CTMediator添加的分類)

5.png

咱們調用PayComponents組件裏面的vc都是經過這個category來調用的。因此說咱們的這個Pay_category工程應該在Podfile文件中加上pod 'CTMediator',而後執行pod install

咱們以前有遇到過這種狀況,咱們在使用A庫的時候,pod install以後,會自動幫咱們導入A庫依賴的B庫,回到咱們的項目也就是說當咱們在主工程裏面集成Pay_Category這一組件的時候,應該默認幫咱們把CTMediator庫和PayComponents組件也集成進工程。這就要修改Pay_Category.podspec文件。

在文件的最底部,end以前加上下面兩句

s.dependency "CTMediator"
s.dependency "PayComponents"

說回咱們新建的這個CTMediator+pay文件,咱們要在主工程MainProject跳轉到PayComponents裏面的VC,因此CTMediator+pay應該提供一個返回vc的方法,以下:

- (UIViewController *)PayViewController {
  
    return [self performTarget:@"PayManager" action:@"pay" params:nil shouldCacheTarget:NO];
}

咱們想不去管return後面的代碼是什麼意思,只要他是返回了vc給咱們就能夠。

而後在MainProject裏面的跳轉代碼就以下:

// 導入CTMediator+pay頭文件
UIViewController * viewController = [[CTMediator sharedInstance] PayViewController];
[self.navigationController pushViewController:viewController animated:YES];

下面咱們再來講return [self performTarget:@"PayManager" action:@"pay" params:nil shouldCacheTarget:NO];是什麼意思。

咱們能夠從CTMediator的源碼中,看一下- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget這個方法。

那這裏我就不繞圈子裏,直接說結論,其實在上述的方法中是找到了一個叫Target_PayManager的類,調用了它裏面的Action_pay方法,這個前綴Target_和Action_是在方法內部拼接的,因此說咱們能夠得出,CTMediator是經過反射拿到類名和方法名,而後調用,獲得目標vc的。因此說在PayComponents工程中,咱們還得建立Taregt文件來作間接的調用。

6.png

這裏的Target_PayManager文件的文件名後半部分PayManager要跟- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget裏面的targetName對應起來,而後類裏面的方法名字也得對應。(PayViewController就是咱們的目標文件)

- (UIViewController *)Action_pay:(NSDictionary *)param {
    
    PayViewController *viewController = [[PayViewController alloc] init];
    viewController.param = param;
    return viewController;

}

最後咱們在MainProject的Podfile文件中引入Pay_Category庫就好了。這個時候咱們的私有庫可能尚未徹底建立成,因此咱們能夠用這種導入本地的方法

pod "Pay_Category", :path => "../Pay_Category"

固然若是私有庫作好了,就只須要pod "Pay_Category"就好了。

完善私有庫

在Casa的博客中說到,可使用他的upload.sh腳原本更新私有庫代碼,我用過它的腳本,老是有錯無,並且庫的版本號也是依次+1的形式,版本號我喜歡x.x.x這種,因此我選擇本身提交代碼,更新私有庫。

針對於每一個工程來講,首先是一些基本的提交代碼操做,

git add .
git commit -m 「新版本號「
git tag 新版本號
git push origin master —tags

要更新私有庫,咱們拿PayComponents這個項目來講,執行下面的指令

//私有庫升級
pod repo push PayComponents  PayComponents.podspec

這個PayComponents就是咱們pod repo add時候起得名字,後面是.podspec文件,這操做等於把咱們的私有庫更新推到咱們本地的庫裏面。注意.podspec裏面的版本號要記得更新,與tag一致。

那這種私有庫咱們項目的其餘成員,仍是拿PayComponents這個來講,首先在代碼管理庫上面得給他們下載代碼的權限,而後執行下面:

//待覈實~ 
pod repo add PayComponents https://gitee.com/LittleBin/PayComponents.git

公有庫

補充一點,那若是想作成公有庫,讓你們均可以使用要怎麼搞?
執行下面操做:

pod trunk push PayComponents.podspec

就能夠把組件推到Cocoapods主倉庫。別人就能夠經過pod search來查找你的庫了。

pod trunk push 可能失敗,由於首次使用trunk須要註冊本身的電腦。

pod trunk register [E-mail] [User Name]

執行完成以後,會受到一封驗證郵件,按郵件提示完成驗證便可。

所有都完成了以後pod search也可能會搜不到本身的庫,這時候能夠嘗試把緩存刪掉

使用命令:rm ~/Library/Caches/CocoaPods/search_index.json

清除後,再從新搜索,此時CocoaPod會從新建立搜索索引。

這只是一些可能的緣由,具體的問題須要具體針對解決。


參考文章

https://casatwy.com/modulizat...

https://www.jianshu.com/p/59c...

https://www.jianshu.com/p/757...

https://www.jianshu.com/p/1d8...

相關文章
相關標籤/搜索