iOS CTMediator組件化實(shí)踐

3篇文章帶你學(xué)會(huì)組件化??????
1.iOS 創(chuàng)建遠(yuǎn)程cocoapods 私有庫
2.iOS Pod 私有庫創(chuàng)建(自定義的組件)
3.iOS CTMediator組件化實(shí)踐

首先你要懂得組件化的整體思想杈湾,如下圖,就是通過一個(gè)中間者傳遞信息攘须,用來降低模塊間的耦合度, 從而達(dá)到高內(nèi)聚低耦合的目的.

組件化思想

提到的中間層就是CTMediator, GitHub上面介紹的非常詳細(xì), 還有使用文章推薦.

廢話不多說, 開始實(shí)踐:

  • 目的: 項(xiàng)目的ViewController 的touchesBegan方法push 新界面(AViewController); 分解成通過CTMediator 和組件通信獲取aVc , 來達(dá)到相同功能.
    普通->組件

步驟詳解

1. 創(chuàng)建組件A_Section, 可參考前一篇文章自定義組件

  1. GitHub 上創(chuàng)建A_Section組件遠(yuǎn)程倉庫
  2. 創(chuàng)建本地項(xiàng)目 (pod lib create A_Section)
  3. 修改.podspec 文件中的homepage 和source 和version
#發(fā)版版本號(hào)漆撞,每更新一次代碼就改變一次版本號(hào)
s.version      = "0.0.1"
#你的 git 倉庫首頁的網(wǎng)頁 url,注意并不是 https/ssh這種代碼倉庫地址
s.homepage     = "https://xxxxxxxxx/A_Section"
#這里就是你 git 倉庫的 https/ssh 地址了
s.source       = { :git => "git@gitxxxxxxxx/A_Section.git", :tag => "#{s.version}" }
  1. 創(chuàng)建AViewController 和 Target_A 文件, 在選擇文件夾的時(shí)候記得選classes
    組件內(nèi)添加內(nèi)容

    : 一個(gè)組件對(duì)應(yīng)一個(gè) Target_A, 這里要特殊記憶下Target_AAAction_viewControllerviewController ;
// Target_A.h文件
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Target_A : NSObject

/// 獲取該組件的AViewController 的實(shí)例化對(duì)象
- (UIViewController *)Action_viewController:(NSDictionary *)params;

@end

// Target_A.m 文件
#import "Target_A.h"
#import "AViewController.h"

@implementation Target_A

- (UIViewController *)Action_viewController:(NSDictionary *)params
{
    AViewController *viewController = [[AViewController alloc] init];
    return viewController;
}

@end
  1. 這時(shí)的A_Section工程目錄應(yīng)該是這樣的:
    當(dāng)前工程目錄
  2. 提交組件項(xiàng)目更新內(nèi)容, 組件發(fā)版打tag, 將repo源添加到自己的私有repo索引庫中.可參考自定義組件5~8步驟

2. 創(chuàng)建中間件A_Category(CTMediator 的Category)

  1. 同一業(yè)務(wù)模塊使用同一中間件就可以, 這里只是文件夾名稱, 可隨意, 這里使用A_Category
  2. 創(chuàng)建遠(yuǎn)程倉庫A_Category
  3. 修改.podspec 文件, 依賴CTMediator 第三方庫
  4. cd /A_Section/Example 目錄下, 更新(pod update --no-repo-update)
  5. 創(chuàng)建CTMediator 的分類CTMediator+A
  6. CTMediator (A)內(nèi)部實(shí)現(xiàn)如下:
// CTMediator+A.h 內(nèi)容
#import <CTMediator/CTMediator.h>
@interface CTMediator (A)
- (UIViewController *)getAViewController;
@end

// CTMediator+A.m 內(nèi)容
#import "CTMediator+A.h"
@implementation CTMediator (A)
- (UIViewController *)getAViewController
{
    /*
        AViewController *viewController = [[AViewController alloc] init];
     */
    // 這個(gè)方法就牛逼了, CTMediator 會(huì)自動(dòng)去找Target_A 的類, 并且去尋找是否存在viewController 方法, 存在就去實(shí)現(xiàn)
    return [self performTarget:@"A" action:@"viewController" params:nil shouldCacheTarget:NO];
}
@end

: 還記得步驟一第四小步需要特殊記憶的Target_AAAction_viewControllerviewController嗎? 其實(shí)對(duì)應(yīng)的就是performTarget:@"A"中的Aaction:@"viewController"中的viewController , 名字都可以隨便起, 但是必須是在對(duì)應(yīng)的前提下;

  1. 配置之后的文件結(jié)構(gòu):
    A_Category結(jié)構(gòu)目錄
  2. 提交組件項(xiàng)目更新內(nèi)容, 組件發(fā)版打tag, 將repo源添加到自己的私有repo索引庫中.可參考自定義組件5~8步驟

3. 本地創(chuàng)建主工程MainProject

  1. 就是創(chuàng)建個(gè)名字為MainProject(名稱可隨意) 的Xcode項(xiàng)目, pod init -> pod install 操作完成即可.
  2. 盡量保證A_Section 和A_Category 和MainProject 在同一文件夾下或同級(jí)目錄下, 方便后續(xù)操作.
    我的文件位置, 都在桌面上了

4. 本地組件測試

  1. cd至MainProject目錄下, 修改profile 文件:
target 'ManiProject' do
  use_frameworks!

    #組件化依賴
    pod 'CTMediator'
  
    #本地測試
    pod 'A_Category', :path => '../A_Category'
    pod 'A_Section',  :path => '../A_Section'

end

: pod 'A_Category', :path => '../A_Category'代表在當(dāng)前的podfile目錄下, (../)返回上一級(jí)目錄, 找到A_Category文件, 拉取其中A_Category.podspec文件.

  1. 更新庫文件( pod install)
  2. 測試組件是否能正常使用, MainProject中的ViewController 類中測試push 功能
// ViewController.m文件內(nèi)容
#import "ViewController.h"

// 引入中間件頭文件
#import <A_Category/CTMediator+A.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // aVc 其實(shí)就是AViewController
    UIViewController *aVc = [[CTMediator sharedInstance] getAViewController];
    [self.navigationController pushViewController:aVc animated:YES];
}
@end

: 引入A_Category的頭文件, 通過[[CTMediator sharedInstance] getAViewController]獲取組件提供的東西.

這個(gè)時(shí)候能正常實(shí)現(xiàn)push 功能, 就算本地的組價(jià)可以正常使用了.

4. 遠(yuǎn)程倉庫的組件的使用測試

  1. 修改podfile 文件, 添加私有源repo索引庫.不會(huì)的話可參考創(chuàng)建遠(yuǎn)程cocoapods 私有庫
  2. 添加需要使用組件的依賴
    podfile 文件大致為:
#這是GitHub的源索引庫
source 'https://github.com/CocoaPods/Specs.git'
#這是我自己的組件的源索引庫
source 'git@github.com:LiHe0308/PrivateSpecs.git'

target 'ManiProject' do
  use_frameworks!

    #組件化依賴
    pod 'CTMediator'
  
    #組件
    pod 'A_Category'
    pod 'A_Section'

end
  1. 主工程pod install 更新庫文件
  2. 測試push 功能, 代碼一點(diǎn)不需要變

這時(shí)候功能正常, 就代表遠(yuǎn)程組件可以正常使用了.

總結(jié)注意點(diǎn):

  • 主工程、組件浮驳、之間的關(guān)系

 1. 組件A_Section: 將相當(dāng)于正常開發(fā)的一個(gè)文件夾, 但是多了一個(gè)Target_A類, Target_A中對(duì)外(CTMediator 的分類)開放整個(gè)組件的功能,所以整個(gè)組件的功能都寫在Target_xName中.例:
 - (UIViewController *)Action_viewController:(NSDictionary *)params;
 
 2. A_Category: 主要是使用CTMediator 的分類,CTMediator (A), 重點(diǎn)就是命名, 一定要和組建中Target后面的名稱相同, 也就是A.
    通過方法return [self performTarget:@"A" action:@"viewController" params:nil shouldCacheTarget:NO];實(shí)現(xiàn)和組件通信, 獲取自動(dòng)尋找Target_A 文件中的viewController 來執(zhí)行
    然后封裝方法 - (UIViewController *)getAViewController; 供外界使用.
 
 3. 主工程ManiProject: 就是你所做的項(xiàng)目, 它只與CTMediator (A)通訊, 引入頭文件,
    通過分類中自定義的方法[[CTMediator sharedInstance] getAViewController]; 獲取到組件
  • 代碼的提交順序, 嚴(yán)格遵守!!!

 1. 一定要先提交所有變更信息
 git remote add origin git@github.com:xxx.git
 git add .
 git commit -a -m "提交變更信息"
 git push -u origin HEAD
 
 2. 修改xxxxx.podspec 文件中homepage 和 source, 一定要準(zhǔn)確
    s.homepage   ->  你的 git 倉庫首頁的網(wǎng)頁 url悍汛,注意并不是 https/ssh這種代碼倉庫地址
    s.source     ->  這里就是你 git 倉庫的 https/ssh 地址了
 
 3. 修改s.version
    s.version = 0.2.0
 
 4. 發(fā)版 -> 一定要與.podspec 文件中s.version 相同
 git tag 0.2.0
 git push origin 0.2.0
 
 5. 將組建repo 地址推到私有源索引庫中 (只做一次就可以, 且必須在.podspec同級(jí)目錄下操作)
 pod repo push [私有源名稱] 組件名稱.podspec --allow-warnings
  • 關(guān)于 xib 和圖片

組件中若用到了圖片,或者 xib 資源至会,要指定資源的文件路徑离咐,否則不會(huì)把圖片打包到你的組件中:

s.resource_bundles = {
    'A_Section' => ['A_Section/AImages/**/*.{png}', 'A_Section/Classes/*.{xib}']  
}
或者
s.resources = ['A_Section/AImages/**/*.{png}', 'A_Section/Classes/*.{xib}']

如果使用 Xocde 工程自帶的 Assets 那個(gè)文件夾的話,圖片也無法打包到組件中奉件,最好自己重新創(chuàng)建一個(gè)新的文件夾用來存放圖片資源;
然后代碼中獲取 xib, png 等 resource 時(shí)宵蛀,bundle 重新設(shè)置,這樣就保證了無論在組件中县貌,還是在 MainProject 工程中术陶,都可以配置到正確的 Bundle,如果你使用 s.resource_bundles={},配置了自定義的 bundle名稱煤痕,那么 [bundle pathForResource:@"A_Section" ofType:@"bundle"]中就要替換成相應(yīng)的名稱.

//mainBundle
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *bundlePath = [bundle pathForResource:@"A_Section" ofType:@"bundle"];
    if (bundlePath)
    {
       //組件資源所在的 bundle     
       bundle = [NSBundle bundleWithPath:bundlePath];
    }

.End

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梧宫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子摆碉,更是在濱河造成了極大的恐慌塘匣,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巷帝,死亡現(xiàn)場離奇詭異馆铁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锅睛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門埠巨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人现拒,你說我怎么就攤上這事辣垒。” “怎么了印蔬?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵勋桶,是天一觀的道長。 經(jīng)常有香客問我侥猬,道長例驹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任退唠,我火速辦了婚禮鹃锈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞧预。我一直安慰自己屎债,他們只是感情好仅政,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盆驹,像睡著了一般圆丹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躯喇,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天辫封,我揣著相機(jī)與錄音,去河邊找鬼廉丽。 笑死倦微,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雅倒。 我是一名探鬼主播璃诀,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼弧可,長吁一口氣:“原來是場噩夢啊……” “哼蔑匣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棕诵,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤裁良,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后校套,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體价脾,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年笛匙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侨把。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妹孙,死狀恐怖秋柄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蠢正,我是刑警寧澤骇笔,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站嚣崭,受9級(jí)特大地震影響笨触,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜雹舀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一芦劣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧说榆,春花似錦持寄、人聲如沸源梭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽废麻。三九已至,卻和暖如春模庐,著一層夾襖步出監(jiān)牢的瞬間烛愧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工掂碱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怜姿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓疼燥,卻偏偏與公主長得像沧卢,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子醉者,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容