最近想了解一些組件化的知識,去看了Casa寫的iOS應用架構談 組件化方案這篇文章,Casa在文中針對蘑菇街的組件化方案提出了一些不一樣的觀點,陳述了本身的組件化方案。html
大神們討論具體的實施方案,是對理論的描述,在架構層面來分析利弊,我看過以後感受仍是有點晦澀,具體的方案異同之處咱們先不說,今天咱們先從應用着手,在本身當前的工程實施組件化。ios
固然了,咱們選擇使用的方案是Casa的CTMediator。git
首先咱們得先了解組件化這個概念,其實通俗的講,就是把咱們的項目拆解成一個一個的小組件分別管理。咱們平時使用cocoapods繼承的三方的庫,能夠理解成是一個公有的組件。咱們項目中,也能夠把一些模塊拆解出來,使用cocoapods來集成。這樣拆解成一個個的組件的好處有不少,好比說業務模塊之間解耦,複用模塊,節省編譯時間等等。github
因此咱們要先學會建立cocoapods私有庫。json
這裏多說一句,Casa的組件化方案在實施的時候,每獨立出來一個組件,就會相應的建立一個Category工程,做爲中間的調度,因此說,咱們每作一個組件,就要建立兩個私有的pod工程。緩存
咱們結合Casa這篇在現有工程中實施基於CTMediator的組件化方案,來作一下補充或者說是註解吧,本文中的流程取自於上文。架構
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
能夠看到目錄是這樣子的
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裏面變成下面這樣子。
咱們要修改一下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文件。
咱們須要把這個文件拖拽到咱們的項目中
而後咱們這個PayComponents組件的文件就所有放到這個路徑下。咱們的私有庫暫時就先寫到這裏。下面建立咱們的Category工程
由於篇幅緣由,這裏我把建立Category工程略過一下,不一一展現了。
其實按道理說在實際項目中,這個Category工程也要作成私有庫的,就像咱們上面說的步驟,先建立本地工程,建立遠程的repo,而後建立本地私有庫(pod repo add ...),在用腳本關聯本地和遠程的庫,而後修改Podfile和upload.sh等等這一整套步驟。
最終Category項目的結構是下面這樣的。(包含爲CTMediator添加的分類)
咱們調用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文件來作間接的調用。
這裏的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...