iOS組件化實(shí)戰(zhàn)


最近在研究組件化,發(fā)現(xiàn)網(wǎng)上的資料有很多尊浪,很詳細(xì)匣屡,可是看的越多感覺越懵??封救,我現(xiàn)在需要的是盡量簡(jiǎn)單化,于是就有了這一篇實(shí)戰(zhàn)貼捣作,簡(jiǎn)單實(shí)用誉结!

一、簡(jiǎn)介

定義

簡(jiǎn)單來說券躁,組件化就是將一個(gè)APP中的代碼進(jìn)行抽取惩坑,分成若干個(gè)項(xiàng)目,然后按照cocoapods的方式進(jìn)行組織也拜,形成一個(gè)擁有完整業(yè)務(wù)邏輯的工程以舒。也就是說一個(gè)組件就是一個(gè)可以獨(dú)立運(yùn)行的項(xiàng)目。它就是用來解耦的慢哈,當(dāng)你的APP業(yè)務(wù)越來越龐大的時(shí)候蔓钟,就需要將業(yè)務(wù)隔離獨(dú)立開發(fā)卵贱。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 組件的獨(dú)立性滥沫,各組件獨(dú)立開發(fā),互不影響艰赞,可以減少提交代碼時(shí)的沖突
  • 資源重用佣谐,將于業(yè)務(wù)無關(guān)的代碼抽離出來放在一個(gè)基礎(chǔ)組件中
  • 高效迭代
  • 配合二進(jìn)制,可以加快項(xiàng)目的編譯速度

缺點(diǎn)

  • 開發(fā)起來步驟要復(fù)雜些方妖,代碼的抽離也不是很容易

二狭魂、組件的劃分

每一個(gè)組件都是一個(gè)獨(dú)立的pod庫,我們把組件化的代碼放在Git上托管党觅,制作成私有pod,然后通過cocoapods就可以連接各個(gè)組件雌澄,最后把它們合在一起,變成一個(gè)完整的項(xiàng)目

原則

  1. 基礎(chǔ)代碼杯瞻;基礎(chǔ)配置(宏定義镐牺、常量)、分類魁莉、網(wǎng)絡(luò)請(qǐng)求睬涧、其它的一些工具類
  2. 功能代碼;自定義的一些UI控件旗唁;一些功能類畦浓,如音頻處理、斷點(diǎn)續(xù)傳等
  3. 業(yè)務(wù)代碼检疫;具體的業(yè)務(wù)讶请,如首頁模塊、個(gè)人中心模塊等

三屎媳、組件的創(chuàng)建

pod 的原理

當(dāng)我們執(zhí)行 pod install 把代碼集到項(xiàng)目中夺溢,這個(gè)過程會(huì)發(fā)生一些什么事情论巍?
AFNetworking為例,當(dāng)它的源碼提交到Git上的時(shí)候,里面會(huì)有一個(gè).spec的文件风响,這個(gè)文件是描述框架信息的嘉汰,比如框架的名稱、版本號(hào)钞诡、真實(shí)源碼地址等郑现。
Git上有專門的一個(gè)遠(yuǎn)程倉庫用來存放所有的 .spec 文件,我們執(zhí)行pod install的時(shí)候荧降,會(huì)先去本地找這個(gè)庫對(duì)應(yīng)的.spec文件接箫,這個(gè)文件是當(dāng)你在安裝pod執(zhí)行pod setup的時(shí)候或者更新pod的時(shí)候,就會(huì)把遠(yuǎn)程倉庫里的.spec文件拉取到本地朵诫。那如果本地找不到這個(gè)描述文件辛友,那么它就會(huì)去把遠(yuǎn)程倉庫的spec文件拉取到本地,然后再去找剪返,找到了之后废累,就能夠得到描述文件里的真實(shí)源碼地址,通過Git把它拉取下來

制作一個(gè)私有pod庫(重難點(diǎn))

步驟

首先脱盲,打開終端邑滨,進(jìn)入項(xiàng)目主目錄中

cd ~ 
cd desktop
mkdir 組件化項(xiàng)目
cd 組件化項(xiàng)目
1. 組件工程(用來發(fā)布的組件,開發(fā)時(shí)用的工程)
  • 思路:新建一個(gè)空白工程钱反,在工程中進(jìn)行業(yè)務(wù)代碼的開發(fā)掖看,比如首頁;開發(fā)完畢后將代碼提交到Git
  • 具體步驟
  • 碼云上新建一個(gè)私有倉庫(為了代碼安全面哥,搞成私有的哎壳!)
  • clone 到本地,進(jìn)行業(yè)務(wù)代碼的開發(fā)(所有的代碼都放在一個(gè)主目錄文件夾中如 ExamComponent)尚卫,可多人開發(fā)归榕,使用 Git 做版本控制
  • 開發(fā)完畢后,上到到Git上吱涉,把ExamComponent文件夾拷貝出來
2. 私有pod庫
  • 創(chuàng)建本地pod庫

    • 進(jìn)入項(xiàng)目目錄中刹泄,執(zhí)行以下命令

      cd 組件化項(xiàng)目   
      pod lib create CXComponentBasic
      

      這個(gè)是pod提供的一個(gè)模板命令,可以創(chuàng)建一個(gè)標(biāo)準(zhǔn)的pod庫怎爵,我們只需要把拷貝過來的業(yè)務(wù)代碼放在 Classes 文件夾中循签,然后修改.spec文件,就可以發(fā)布了疙咸,稍候?qū)⒃敿?xì)介紹

  • 創(chuàng)建私有索引庫
    通過上面介紹的pod的原理,我們知道每個(gè)開源庫都對(duì)應(yīng)一個(gè).spec文件风科,這個(gè).spec文件默認(rèn)是放在開源的pod索引庫里的撒轮,別人都可以搜索到乞旦,我們?nèi)绻枰獎(jiǎng)?chuàng)建私有pod庫,就不能把.spec文件放在默認(rèn)開源索引庫里题山,我們需要把它放在自己的私有索引庫中兰粉。

  1. 碼云上新建一個(gè)私有庫,用來存放spec文件顶瞳,這個(gè)庫也可稱為索引庫
  2. 回到終端玖姑,將這個(gè)索引庫關(guān)聯(lián)到本地,命令如下
pod repo add CXGiteePrivateRepo https://git.oschina.net/baiyingqiu/CXGiteePrivateRepo.git

CXGiteePrivateRepo 是私有索引庫的名稱
可通過命令pod repo可查看本地有哪些索引庫

  • 關(guān)聯(lián)pod庫的遠(yuǎn)程倉庫
    前面兩步已經(jīng)把本地pod庫私有索引庫創(chuàng)建好了,下面就不要把pod庫的.spec文件,上傳到私有索引庫中就行了慨菱。

  • 關(guān)聯(lián)本地pod庫

    • 碼云上新建一個(gè)私有庫焰络,名稱和本地pod庫一樣,用來和它進(jìn)行關(guān)聯(lián),命令如下
    git remote add origin https://gitee.com/sunnoryChen/CXComponentBasic.git
    
  • 修改.spec文件
    修改版本號(hào)和路徑等

  • 發(fā)布

    • 打開本地私有pod庫的示例項(xiàng)目
    cd xx  
    pod install
    clean
    

    先執(zhí)行下安裝符喝,看看pod庫是否報(bào)錯(cuò)闪彼,如果報(bào)錯(cuò)說明你的業(yè)務(wù)代碼有問題沪饺,得改燕侠!

    • 返回上一級(jí)目錄
      確保你的業(yè)務(wù)代碼正常后,就可以返回到上級(jí)目錄橘券,準(zhǔn)備發(fā)布啦

      • 關(guān)聯(lián)遠(yuǎn)程倉庫
      git remote add origin https://gitee.com/sunnoryChen/CXComponentBasic.git
      

      git remote -v 可查看關(guān)聯(lián)了哪些遠(yuǎn)程倉庫

      • 上傳到遠(yuǎn)程倉庫
      git add .
      git commit -m “0.1.2”
      git tag 0.1.2
      git push origin master --tags -f 
      

      注意 tag 值需要和pod的版本號(hào)保持一致

      • 驗(yàn)證.spec文件是否可用
         pod spec lint --sources='https://gitee.com/sunnoryChen/CXGiteePrivateRepo.git,https://github.com/CocoaPods/Specs' --allow-warnings
      

      這兩個(gè)路徑一個(gè)是我們的私有索引庫地址茉稠,一個(gè)是pod的公共索引庫地址

      • 發(fā)布到私有索引庫中
        驗(yàn)證通過后描馅,驗(yàn)證不通過,那就看哪報(bào)錯(cuò)就改哪兒吧而线,反正有不少坑的??
        發(fā)布的命令如下:
      pod repo push CXGiteePrivateRepo CXComponentBasic.podspec --sources='https://gitee.com/sunnoryChen/CXGiteePrivateRepo.git,https://github.com/CocoaPods/Specs' --allow-warnings
      

      CXGiteePrivateRepo 是我們之前創(chuàng)建的本地索引庫名
      CXComponentBasic.podspec 就是我們要發(fā)布庫的索引庫

3. 組件的使用

修改 podfile 文件铭污,如下

# 使用私人pod庫的需要在Podflie中添加這句話,指明你的版本庫地址
source 'https://gitee.com/sunnoryChen/CXGiteePrivateRepo.git'
source 'https://github.com/CocoaPods/Specs.git'

platform :ios, ‘8.0’

pod 'CXComponentBasic', '~> 0.1.2'

Tips

  1. 組件項(xiàng)目中怎么使用 .pch 預(yù)編譯文件

找到pod的目錄 “Support Files - RDZJComponentLogin-prefix.pch” ,這個(gè)相當(dāng)于實(shí)際項(xiàng)目中的pch文件吞获,防止一些預(yù)編譯的命令况凉,可全局調(diào)用的

  1. 組件內(nèi)怎么分層級(jí)的

修改 .spec文件

#頭文件
s.public_header_files = 'Pod/Classes/Category/UIKit/CXUIKit.h'

s.subspec 'Category' do |vdr|
    vdr.subspec 'Foundation' do |vd|
    vd.source_files = "CXComponentPublic/Classes/Category/Foundation/**/*"
    end
  vdr.subspec 'UIKit' do |vd|
    vd.source_files = "CXComponentPublic/Classes/Category/UIKit/**/*"
   end
end
  1. 組件怎么依賴三方庫

    s.dependency 'MBProgressHUD', '~> 1.0.0'

  2. 組件怎么使用自己活三方的 framework 或者 .a 文件

    s.ios.vendored_frameworks = "xxx//.framework"
    s.ios.vendored_libraries = "xxx/
    /.a”

  3. 組件內(nèi)部相互依賴?

s.subspec 'BaseClass' do |bsc|
bsc.source_files = "TestPod/Classes/BaseClass/*"
# 字庫BaseClass中用到了字庫Controls中的東西各拷,需要添加依賴
bsc.dependency "TestPod/Controls"
end

TestPod 是你的組件名刁绒,這個(gè)命令的意思是 TestPod 組件里的 BaseClass 子庫依賴了 的 TestPod 組件中的 Controls子庫

  1. 組件中怎么使用資源文件比如圖片Xib烤黍、txt文檔,因?yàn)榻M件中圖片不是放在默認(rèn) Main Bundle中的知市,所以是不能使用ImageNamed 方法獲取圖片的,需要知道當(dāng)前圖片所在的 Bundle , 例如

圖片

+ (instancetype)cx_imagePathWithName:(NSString *)imageName bundle:(NSString *)bundle targetClass:(Class)targetClass {
        NSInteger scale = [[UIScreen mainScreen] scale];
        NSBundle *currentBundle = [NSBundle bundleForClass:targetClass];
        NSString *name = [NSString stringWithFormat:@"%@@%zdx",imageName,scale];
        NSString *dir = [NSString stringWithFormat:@"%@.bundle",bundle];
        NSString *path = [currentBundle pathForResource:name ofType:@"png" inDirectory:dir];
        return path ? [UIImage imageWithContentsOfFile:path] : nil;
}

Xib

+ (instancetype)base_mainView {
    NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];
    CXBaseXibView *view = (CXBaseXibView *)[currentBundle loadNibNamed:@"CXBaseXibView" owner:nil options:nil].lastObject;
    view.frame = CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, 128);
    return view;
}

txt

NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];
NSLog(@"text_currentBundle = %@",currentBundle);
NSString *dir = [NSString stringWithFormat:@"%@.bundle",@"RDZJComponentLogin"];
NSString *plistPath = [currentBundle pathForResource:@"userDeal" ofType:@"txt" inDirectory:dir];
NSLog(@"plistPath = %@",plistPath);

Questions

  1. pod發(fā)布命令不可用
    需要先注冊(cè)一下pod 才能有發(fā)布庫的權(quán)限 eg.

pod trunk register 2235037295@qq.com "georry"

  1. 發(fā)布庫時(shí)速蕊,報(bào) Swift 版本錯(cuò)誤

在 podspec中添加 s.swift_version = '4.0'

  1. 更新私有庫版本時(shí),出現(xiàn)
    [!] The repo MySpecs at ../../../../.cocoapods/repos/MySpecs is not clean
    需要更新一下我們的索引庫
    執(zhí)行命令pod repo update 本地私有索引庫名稱(MySpecs)

執(zhí)行命令 pod repo update 本地私有索引庫名稱(MySpecs)

  1. 在組件內(nèi)部使用三方庫時(shí)嫂丙,要這樣導(dǎo)入 Masonry/Masonry.h
  2. OC、Swift 混編包规哲,怎么做組件

不使用8 !!

四隅肥、組件的通訊

采用 CTmediator 的路由解決方案竿奏,將需要暴露的接口放在它的分類方法中,具體使用方法可參考上篇文章

參考資料

1
2
3

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腥放,一起剝皮案震驚了整個(gè)濱河市泛啸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秃症,老刑警劉巖候址,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異种柑,居然都是意外死亡岗仑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門莹规,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赔蒲,“玉大人,你說我怎么就攤上這事良漱∥枋” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵母市,是天一觀的道長(zhǎng)矾兜。 經(jīng)常有香客問我,道長(zhǎng)患久,這世上最難降的妖魔是什么椅寺? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮蒋失,結(jié)果婚禮上返帕,老公的妹妹穿的比我還像新娘。我一直安慰自己篙挽,他們只是感情好荆萤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著铣卡,像睡著了一般链韭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上煮落,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天敞峭,我揣著相機(jī)與錄音,去河邊找鬼蝉仇。 笑死旋讹,一個(gè)胖子當(dāng)著我的面吹牛殖蚕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骗村,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嫌褪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了胚股?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤裙秋,失蹤者是張志新(化名)和其女友劉穎琅拌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摘刑,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡进宝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了枷恕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片党晋。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖徐块,靈堂內(nèi)的尸體忽然破棺而出未玻,到底是詐尸還是另有隱情,我是刑警寧澤胡控,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布扳剿,位于F島的核電站,受9級(jí)特大地震影響昼激,放射性物質(zhì)發(fā)生泄漏庇绽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一橙困、第九天 我趴在偏房一處隱蔽的房頂上張望瞧掺。 院中可真熱鬧,春花似錦凡傅、人聲如沸辟狈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽上陕。三九已至,卻和暖如春拓春,著一層夾襖步出監(jiān)牢的瞬間释簿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工硼莽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留庶溶,地道東北人煮纵。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像偏螺,于是被迫代替她去往敵國和親行疏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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