iOS 組件化(一) - CocoaPods原理理論篇
iOS 組件化(二) - 遠程/本地管理私有庫
iOS 組件化(三) - 組件化工程介紹
一屁倔、創(chuàng)建組件
在桌面創(chuàng)建一個名為Modules
的文件夾蓄愁,打開終端使用pod命令創(chuàng)建組件工程,取名為WJCommon
cd /Users/xxx/Desktop/Modules
pod lib create WJCommon
創(chuàng)建組件后會自定打開WJCommon
組件工程:
二荔茬、目錄介紹
LICENSE
主要是對該組件的介紹灼芭,需要自己寫(我這里不做演示)
Example
是組件的測試用例有额,可以用于測試WJCommon
組件里的API
。可以寫一些UIView相關類去測試組件代碼的正確巍佑,當然像使用UIView的話需要添加約束茴迁,可以在Podfile文件
中添加該測試用例所依賴的三方庫。
WJCommon
是真正的組件的代碼相關萤衰,下面內容會詳細說明堕义。
WJCommon.podspec
是用來配置組件的版本號、名稱脆栋、描述倦卖、作者信息、遠程倉庫鏈接椿争、依賴三方庫怕膛、開放資源文件等等。
三秦踪、.podspec文件介紹
Pod::Spec.new do |s|
s.name = 'WJCommon' # 庫名稱
s.version = '0.0.1' # 版本號
s.summary = 'Swift 工具類組件' #對組件的簡述
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
#對組件的描述
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
#此處為遠程倉庫地址褐捻,要去掉 /xxx.git
s.homepage = 'https://gitee.com/xxx'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
#作者郵箱
s.author = { 'Steven' => '2448305504@qq.com' }
#遠程倉庫地址、當前的版本號
s.source = { :git => 'https://gitee.com/xxx/WJCommon.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '10.0' # 依賴最低版本
# 開放的庫文件
s.source_files = 'WJCommon/Classes/**/*'
# 開放的庫資源文件 - 有資源則需要打開這里的注釋
# s.resource_bundles = {
# 'WJCommon' => ['WJCommon/Assets/*.png']
# }
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit' # 依賴系統(tǒng)庫
# 組件依賴多個三方庫
s.dependency 'Kingfisher'
s.dependency 'Alamofire', '~> 5.4.4'
# 定義子庫例子
#spec.subspec 'XXChildFramework' do |ss|
#引入XXChildFramework中所有資源文件
# ss.source_files = 'XXChildFramework/Classes/**/*'
#公開XXChildFramework模塊中的頭文件
# ss.public_header_files = 'XXChildFramework/Classes/publicHeader/*.h'
# end
end
相關代碼注釋:
s.name: 名稱
s.version: 版本號
s.ios.deployment_target: 支持的pod最低版本
s.summary: 簡介
s.homepage: 項目主頁地址
s.license: 開源協(xié)議(創(chuàng)建github庫的時候選擇的)
s.author: 作者信息(這里隨便謝謝也可以通過)
s.social_media_url: 社交網(wǎng)址
s.source: 項目的地址
s.source_files: 需要包含的源文件
s.resource: 資源文件,單個
s.resources: 資源文件(含bundle)
s.vendored_frameworks: 包含的framework,也就是我們自己制作的pod
s.requires_arc: 是否支持ARC
s.dependency: 依賴庫椅邓,不能依賴未發(fā)布的庫.如AFNetWorking
s.description: 描述,字數(shù)要比s.summary長
s.screenshots: 截圖
s.exclude_files: 隱藏的文件
s.public_header_files: 公開的頭文件
s.framework: 所需的framework,單個
s.frameworks: 所需的framework,多個用逗號隔開
s.library 引用的靜態(tài)庫
s.libraries 引用的靜態(tài)庫,多個用逗號隔開
s.vendored_libraries: 引用自己生成的.a
s.vendored_frameworks: 引用自己生成的.framework,多個用逗號隔開
s.dependency: 依賴的庫
s.ios.deployment_target iOS部署版本
四柠逞、組件的代碼區(qū)
組件的代碼應該放在名為ReplaceMe
把該文件替換掉。
注意:每次修改組件的內容都需要pod install
去更新一下一下景馁,測試用例才能使用板壮。
$ cd /Users/xxx/Desktop/Modules/WJCommon/Example
$ pod install
五、組件依賴三方庫
1.依賴遠程三方庫的導入
我們在編寫組件的代碼的時候合住,往往用到別的三方庫绰精,比如圖片下載Kingfisher
、比如網(wǎng)絡請求Alamofire
等等聊疲。
這個時候需要修改WJCommon.podspec
文件給組件添加三方依賴
2.Objctive-C三方庫暴露頭文件
像OC的三方庫(Mansonry茬底、AFNetwoing、SDWebImage)則需要在.podspec
末尾添加暴露頭文件頭文件
s.prefix_header_contents = '#import "Masonry.h"', '#import "UIKit+AFNetworking.h"'
再pod install
一下获洲,此時WJCommon-prefix.pch
就有了引入:
ps:倘若編譯工程還報錯阱表,則關閉掉Xcode重新打開項目編譯或者重新pod install贡珊,別說我沒告訴你最爬,經(jīng)常會出現(xiàn)這樣奇奇怪怪的問題。這是因為不斷地對pod進行修改文件门岔,會導致讀取到緩存的問題爱致。
3.依賴本地三方庫的導入
如果我有一個自己寫的組件名為WJMacro
并把它放在和WJCommon
組件工程一個目錄下(都在Modules
目錄)。
WJMacro
主要寫的一些常量寒随,比如 kScreenWidth
糠悯、kScreenHeight
帮坚。
(又或者是從github上下載別的三方框架放在本地,也是可以的)
此時我想要在WJCommon
中引入WJMacro
互艾,則需要在Podfile
文件進行修改:
(記得pod install)
六试和、組件需要的資源文件
倘若WJCommon
組件里需要使用到一些資源,如圖片/plist/json/xib
等等纫普。
1.將資源文件導入到Assets
阅悍,如下目錄:
2.WJCommon.podspec
文件中開放庫資源文件
注意我這里開放的是.xcassets
后綴的文件,因為我在Assets
目錄下添加的是images.xcassets
昨稼。
若需要開放多種格式的文件节视,則在中括號內添加。也可以直接使用這個全部開放出去:
# 開放的庫資源文件 - 有資源則需要打開這里的注釋
s.resource_bundles = {
'WJCommon' => ['WJCommon/Assets/**/*']
}
pod install
后就會在工程中見到資源
3.在工程中讀取資源文件
在組件中讀取資源文件:
注意每次修改組件都得pod install
在組件測試用例中讀取資源文件:
運行測試結果:
let bundlePath = Bundle.init(for: ReplaceMe.self).bundlePath+"/WJCommon.bundle"
print(bundlePath)
let resoure_bundle = Bundle.init(path: bundlePath)
let image = UIImage(named: "share_wechat", in: resoure_bundle, compatibleWith: nil)
print(image as Any)
要是每次嫌麻煩假栓,自己可以寫一個宏定義即可啦寻行。
七、組件之間的通訊
在我們構建組件模塊的時候但指,總會出現(xiàn)模塊之間的相互使用寡痰,導致模塊之間的耦合不獨立的情況,如下
我們構建模塊的初衷是誰的事情誰去做棋凳,要是這么相互引用的話,我們的模塊就會變得很凌亂连躏。
在我們計算機中往往出現(xiàn)兩兩都無法解決耦合的問題的時候剩岳,都可以借助第三者來實現(xiàn)對兩者的解耦。
解決模塊耦合的問題市面上推出了三種方案:
1.URL路由
:MGJRouter蘑菇街入热、 routable-ios拍棕、 JLRoutes、 HHRouter2.target-action
:CTMediator3.protocol匹配(類似微服務)
:阿里的BeeHive
后面出一節(jié)來探討組件通訊勺良。