CocoaPods 能夠說是 iOS 開發應用最普遍的包管理工具,本篇文章主要介紹 CocoaPods 的第三方庫是怎樣從網絡集成到咱們本地的項目當中,也是製做私有庫、開源庫和 iOS 項目組件化的一個知識鋪墊。html
讓咱們從一張圖片開始:ios
CocoaPods 工做流程 |
---|
遠程索引庫裏存放的是各類框架的描述信息,這個庫託管在 Github 上,地址以下:git
github.com/CocoaPods/S…github
每一個框架下有數個版本,每一個版本有一個 json
格式的描述信息,以下:json
{
"name": "CAIStatusBar",
"version": "0.0.1",
"summary": "A simple indicator",
"homepage": "https://github.com/apple5566/CAIStatusBar.git",
"license": "MIT",
"authors": {
"apple5566": "zaijiank110@sohu.com"
},
"platforms": {
"ios": "6.0"
},
"source": {
"git": "https://github.com/apple5566/CAIStatusBar.git",
"tag": "0.0.1"
},
"source_files": "CAIStatusBar/**/*.{h,m}",
"resources": "CAIStatusBar/CAIStatusBar.bundle",
"requires_arc": true
}
複製代碼
其中 git
字段表示該框架的託管地址,也就是上面時序圖中的 遠程框架庫
。swift
在 install cocoapods
命令後,須要執行 pod setup
這個命令,pod setup
命令就是將遠程索引庫克隆到本地來,本地索引庫的路徑以下:xcode
~/.cocoapods/repos/master
複製代碼
本地索引庫和遠程索引庫的目錄一致,結構以下:ruby
本地索引庫 |
---|
當執行 pod search
命令時,若是本地索引文件不存在,會建立這個文件。bash
tianziyaodeMacBook-Air:~ Tian$ pod search afn
Creating search index for spec repo 'master'..
複製代碼
若是這個文件存在,則會在此文件中進行索引,確認所須要的框架是否存在,本地索引文件的路徑以下:網絡
~/資源庫/Caches/CocoaPods
複製代碼
上面的流程清楚之後,製做 CocoaPods 庫相信應該不會太難了,大體分爲如下幾步:
https://github.com/CocoaPods/Specs
;pod setup
, 建立本地索引庫;pod install
,將框架集成到項目中;如今開始動手吧!首先在桌面新建一個 testLib
目錄,在該目錄下新建一個 Classes
目錄,用來存放框架源碼,而後將 testLib
託管到 Git。
你能夠給 Classes 目錄任意的命名,Classes 只是一種約定俗稱的命名。
pod spec
命令用於建立框架的描述信息文件,文檔以下:
guides.cocoapods.org/syntax/pods…
如今在 testLib
目錄下執行:
pod spec create testLib
複製代碼
目錄下會建立一個 testLib.podspec
文件,而後編輯這個文件,主要有如下幾個字段:
releases
與此對應;根據上面的步驟,如今你須要將生成的 testLib.podspec
文件上傳到遠程索引庫,在此以前,你須要註冊一個 Trunk 帳號,文檔以下:
guides.cocoapods.org/making/gett…
如今執行下面的命令,記得修改郵箱暱稱描述等:
pod trunk register ziyao.tian@gmail.com 'Tian' --description='macbook air'
複製代碼
你的郵箱會收到一封郵件,打開郵件裏面的連接,會有相似 you can back termainal
的提示,如今回到終端。
pod lib lint
複製代碼
檢查 testLib.podspec
的合法性,根據錯誤提示修復問題,當顯示 passed validation
後,執行下面的命令:
pod trunk push testLib.podspec
複製代碼
提示信息以下:
Updating spec repo `master`
--------------------------------------------------------------------------------
🎉 Congrats
🚀 testLib (0.0.7) successfully published
📅 October 17th, 00:38
🌎 https://cocoapods.org/pods/testLib
👍 Tell your friends!
--------------------------------------------------------------------------------
複製代碼
此時你的 testLib.podspec
就會 pull request
到遠程索引庫,CocoaPods 官方審覈經過後,就能夠出如今遠程索引庫中,當遠程索引庫收錄後:
pod setup
複製代碼
這時你的本地索引庫,會新加入 testLib.podspec
這條記錄,可是本地索引文件還未更新,所以刪除掉如下路徑的本地索引文件:
~/資源庫/Caches/CocoaPods/search_index.json
複製代碼
執行 pod search testLib
命令,當 search_index.json
文件重建完畢後,就能夠在使用這個遠程框架庫了。
有了公開庫,固然也就有私有庫,私有庫主要分爲遠程和本地兩種,何時會用到私用庫呢?也就是須要將源碼封裝成庫,但又不但願將源碼公開,通常的使用場景是公司內部的組件化開發。
本地私有庫就是建立一個倉庫,將其存儲在本地,在本地的其餘工程中直接使用。首先在桌面新建一個庫,路徑以下:
LocalLib/NetWork/Classes/Test.swift
複製代碼
接着建立一個殼工程,如今你的目標是使用 pod
的方式,將 NetWork
這個庫集成到殼工程中。
將 NetWork
加入到 Git,命令以下:
git init
git add.
git commit -m 'x'
複製代碼
和公開庫同樣,咱們須要先建立一個 spec
文件,命令以下:
pod spec create LocalLib
複製代碼
編輯 NetWork.podspec
文件,修改爲下面這樣:
Pod::Spec.new do |s|
s.name = "NetWork"
s.version = "0.0.1"
s.summary = "A short description of NetWork."
s.description = "A short description of NetWork.xxxxxxxxxxxxxxxxxx"
s.homepage = "http://EXAMPLE/NetWork"
s.license = "MIT"
s.author = { "tianziyao" => "ziyao.tian@gmail.com" }
s.source = { :git => "", :tag => "#{s.version}" }
s.source_files = "Classes", "Classes/**/*.{h,m,swift}"
end
複製代碼
如今你的本地庫已經準備完畢了,下面就可使用這個庫了。
如今進入到殼工程目錄下,執行命令:
pod init
複製代碼
編輯 Podfile
文件,以下:
target 'Test' do
use_frameworks!
pod 'NetWork', :path => '../NetWork'
target 'TestTests' do
inherit! :search_paths
end
target 'TestUITests' do
inherit! :search_paths
end
end
複製代碼
這裏有一個 path
關鍵字,它表示在 pod install
執行時,在指定的路徑下尋找 NetWork.podspec
文件。
下面執行 pod install
命令,提示信息以下:
Analyzing dependencies
Fetching podspec for `NetWork` from `../NetWork`
Downloading dependencies
Installing NetWork (0.0.1)
Generating Pods project
Integrating client project
複製代碼
如今 NetWork
這個庫就集成到了殼工程中。
與使用遠程庫不一樣,本地庫的源文件會在 Development Pods
這個目錄下,而不是 Pods
目錄,順便一提,CocoaPods 的庫開發,通常也是這樣搭建環境的,開發完成後再修改 spec
文件,將其 pull request
到遠程索引庫。
本地私有庫這個方式還存在如下問題:
podspec
文件;假設咱們有一個基礎組件,裏面所有是擴展文件,沒法單獨運行,若是依託殼工程運行,只有這一個組件,那麼這個殼工程實際跟測試工程是同樣的,但殼工程內有多個組件呢?
咱們在殼工程中進行測試的話,不但要對其餘的組件進行編譯,並且本身負責的組件也可能會收到其餘組件的影響,這樣也就失去了組件化開發的本意,那麼怎麼優化呢?
首先在 LocalLib/NetWork/
路徑下建立一個測試工程 Example
,而後將 Classes
拖到這個測試工程中,這裏須要注意的是,Example
和 Classes
是引用關係,不要 Copy。
簡單粗暴的拖拽,如今 Example
工程就可使用 NetWork
庫了。
另一種方式是將 NetWork
經過 CocoaPods 安裝在 Example
中,和安裝在殼工程同樣。
看到這裏,是否是感受很煩?就是想作個測試而已,還要拖來拖去,那麼繁瑣。
不要着急下面來介紹一種更快捷高效的方式,執行下面的命令:
pod lib create BaseMoudle
////////////////////////////////////////////////////////////////////////
What language do you want to use?? [ Swift / ObjC ]
> Swift
Would you like to include a demo application with your library? [ Yes / No ]
> Yes
Which testing frameworks will you use? [ Quick / None ]
> None
Would you like to do view based testing? [ Yes / No ]
> Yes
複製代碼
如今咱們就有了一個 CocoaPods 的模板工程,它的結構是這樣的:
.
├── BaseMoudle
│ ├── Assets
│ └── Classes
│ └── ReplaceMe.swift
├── BaseMoudle.podspec
├── Example
│ ├── BaseMoudle
│ ├── BaseMoudle.xcodeproj
│ ├── BaseMoudle.xcworkspace
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Pods
├── LICENSE
├── README.md
└── _Pods.xcodeproj -> Example/Pods/Pods.xcodeproj
複製代碼
看吧,把源碼拖到 ReplaceMe.swift
的同級目錄,執行 pod install
,就完成了本地私有庫和其測試工程。
這一步可能會有 Swift 語言版本的問題,保持測試工程和私有庫源碼語言版本一致就能夠。
遠程私有庫工做流程 |
---|
如今使用 pod lib create
就能夠方便的生成一個本地私有庫了,可是本地私有庫有必定的侷限性,例如:
Podfile
文件中主動指明路徑;遠程私有庫就能夠方便的解決以上的問題,製做遠程私有庫分爲如下幾個步驟:
podspec
描述文件;podspec
描述文件;Git 倉庫的建立在此就不在贅述了,本文中我使用碼市作示例,私有 CocoaPods 遠程索引庫實際上也是一個 Git 倉庫,如今咱們有兩個私有庫,一個用來存放 Pod 庫的源碼,一個用來存放 Pod 庫的描述文件。
添加私有索引庫須要使用 SSH 受權,也是和 Git 倉庫同樣的,瞭解的同窗能夠跳過這一步驟,首先建立公鑰:
ssh-keygen
複製代碼
而後找到下面的文件:
~/.ssh/id_rsa.pub
複製代碼
裏面存放的字符就是公鑰了,而後將公鑰添加碼市,連接以下:
https://coding.net/user/account/setting/keys
複製代碼
如今執行 pod repo
,能夠看到下面的信息:
master
- Type: git (master)
- URL: https://github.com/CocoaPods/Specs.git
- Path: /Users/Tian/.cocoapods/repos/master
複製代碼
如今咱們只有一個 CocoaPods 遠程索引庫,也是官方的索引庫,下面執行:
pod repo add TZYSpecs git@git.coding.net:tianziyao/TZYSpecs.git
複製代碼
此時咱們的 CocoaPods 遠程索引庫就安裝好了,到下面的路徑去看一下:
~/.cocoapods/repos
複製代碼
還記得 pod lib create
命令嗎?前面咱們使用它來製做了本地私有庫,如今它又排上用場了,執行:
pod lib create BaseComponent
複製代碼
源碼拖到 ReplaceMe.swift
的同級目錄,它如今看起來應該是這個樣子:
.
├── BaseComponent
│ ├── Assets
│ └── Classes
│ ├── Extension
│ │ ├── Array+Safe.swift
│ │ ├── CALayer+PauseAimate.swift
│ │ ├── UIImage+.swift
│ │ └── UIView+Property.swift
├── BaseComponent.podspec
├── Example
├── LICENSE
├── README.md
└── _Pods.xcodeproj -> Example/Pods/Pods.xcodeproj
複製代碼
執行 pod install
,就完成了本地私有庫和其測試工程,經過測試以後,咱們就能夠把這個本地私有庫製做成遠程私有庫了。
首先修改 BaseComponent.podspec
文件:
Pod::Spec.new do |s|
s.name = 'BaseComponent'
s.version = '0.1.0'
s.summary = '基礎組價'
s.description = '包括基本配置,常量,擴展,工具類等'
s.homepage = 'https://coding.net/u/tianziyao/p/BaseComponent'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'tianziyao' => 'ziyao.tian@gmail.com' }
s.source = { :git => 'https://git.coding.net/tianziyao/BaseComponent.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'BaseComponent/Classes/**/*'
end
複製代碼
而後使用質量檢查工具驗證一下,保證在 BaseComponent.podspec
路徑下,執行:
pod lib lint
複製代碼
若是你使用 Swift,會獲得一個提示:
-> BaseComponent (0.1.0)
- WARN | [iOS] swift_version: The validator for Swift projects uses Swift 3.0 by default, if you are using a different version of swift you can use a `.swift-version` file to set the version for your Pod. For example to use Swift 2.3, run:
`echo "2.3" > .swift-version`
[!] BaseComponent did not pass validation, due to 1 warning (but you can use `--allow-warnings` to ignore it).
You can use the `--no-clean` option to inspect any issue.
複製代碼
根據提示修復就行了,在這裏你可能會遇到不少 Swift 語言版本的問題,善用搜索引擎吧,經過檢驗之後提示以下:
-> BaseComponent (0.1.0)
BaseComponent passed validation.
複製代碼
下面執行:
git add .
git commit -m 'x'
複製代碼
而後和遠程倉庫進行關聯:
git remote add origin https://git.coding.net/tianziyao/BaseComponent.git
git pull origin master
git push origin master
複製代碼
首先執行下面的命令:
pod spec lint
複製代碼
提示以下:
-> BaseComponent (0.1.0)
- ERROR | [iOS] unknown: Encountered an unknown error ([!] /usr/local/bin/git clone https://git.coding.net/tianziyao/BaseComponent.git /var/folders/2v/qkx5m4sx4dg86x4c82yfyjdc0000gn/T/d20171021-69604-1bekfgk --template= --single-branch --depth 1 --branch 0.1.0
Cloning into '/var/folders/2v/qkx5m4sx4dg86x4c82yfyjdc0000gn/T/d20171021-69604-1bekfgk'...
warning: Could not find remote branch 0.1.0 to clone.
fatal: Remote branch 0.1.0 not found in upstream origin
) during validation.
Analyzed 1 podspec.
[!] The spec did not pass validation, due to 1 error.
複製代碼
根據提示,咱們須要先創建一個 Tag:
git tag '0.1.0'
git push --tags
pod spec lint
複製代碼
檢驗經過後,提示以下:
-> BaseComponent (0.1.0)
Analyzed 1 podspec.
BaseComponent.podspec passed validation.
複製代碼
而後將 podspec
文件推到遠程私有索引庫:
pod repo push TZYSpecs BaseComponent.podspec
複製代碼
如今看一下本地索引庫中是否已經添加成功:
~/.cocoapods/repos
複製代碼
再看一看你的遠程索引庫中是否添加成功,如今搜索一下本地索引文件試試:
-> BaseComponent (0.1.0)
基礎組價
pod 'BaseComponent', '~> 0.1.0'
- Homepage: https://coding.net/u/tianziyao/p/BaseComponent
- Source: https://git.coding.net/tianziyao/BaseComponent.git
- Versions: 0.1.0 [TZYSpecs repo]
複製代碼
如今咱們能夠找到本身的遠程私有庫了,下面將 Podfile
文件改爲這樣:
project 'Ting.xcodeproj'
source 'https://github.com/CocoaPods/Specs.git'
source 'git@git.coding.net:tianziyao/TZYSpecs.git'
target 'Ting' do
use_frameworks!
pod 'BaseComponent'
pod 'Alamofire'
target 'TingTests' do
inherit! :search_paths
end
target 'TingUITests' do
inherit! :search_paths
end
end
複製代碼
執行 pod install
,整個遠程私有庫的搭建和使用就完成了。
咱們使用遠程私有庫的目的就是爲了版本升級和多人開發,那麼遠程私有庫如何進行升級,升級後其餘人又如何使用呢?如今咱們給 BaseComponent
進行升級,給它再增長一些功能:
.
├── BaseComponent
│ ├── Assets
│ └── Classes
│ ├── Const
│ │ └── Const.swift
│ ├── Extension
│ │ ├── Array+Safe.swift
│ │ ├── CALayer+PauseAimate.swift
│ │ ├── UIImage+.swift
│ │ └── UIView+Property.swift
│ └── Tool
│ ├── AlertTool.swift
│ ├── CacheTool.swift
│ ├── DeviceMessage.swift
│ └── NoticeLocalTool.swift
├── BaseComponent.podspec
├── Example
├── LICENSE
├── README.md
└── _Pods.xcodeproj -> Example/Pods/Pods.xcodeproj
複製代碼
在 BaseComponent
的測試工程中測試無誤後,將 BaseComponent.podspec
的 version
修改一下:
Pod::Spec.new do |s|
s.name = 'BaseComponent'
s.version = '0.2.0'
s.summary = '基礎組價'
s.description = '包括基本配置,常量,擴展,工具類等'
s.homepage = 'https://coding.net/u/tianziyao/p/BaseComponent'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'tianziyao' => 'ziyao.tian@gmail.com' }
s.source = { :git => 'https://git.coding.net/tianziyao/BaseComponent.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'BaseComponent/Classes/**/*'
end
複製代碼
如今檢查一下私有庫是否有錯誤:
pod lib lint
複製代碼
檢查經過後就能夠將 BaseComponent
的 0.2.0
版本推到遠程私有庫中,同時創建 0.2.0
的 Tag。
而後檢查一下 spec
文件:
pod spec lint
複製代碼
檢查經過後,執行:
pod repo push TZYSpecs BaseComponent.podspec
複製代碼
若是存在警告,能夠執行:
pod repo push xxx xx.podspec --verbose --allow-warnings
複製代碼
遠程私有庫和遠程私有索引庫所有更新完畢,如今咱們回到使用者的視角,這個庫可使用了嗎?還不行。
由於本地的索引文件尚未更新,這個源還找不到,如今進入殼工程,執行:
pod update --no-repo-update
pod install
複製代碼
BaseComponent
的 0.2.0
版本就乖乖的進入了殼工程。
在上面的殼工程中,咱們引入了 Alamofire
這個框架,可是若是用着用着忽然以爲不爽了,要換框架,這時 Alamofire
的引用在工程中已經無處再也不了,這樣換的話是否是很痛苦?
因此咱們通常在開發中都會封裝網絡請求,作到分層解耦,這樣若是換框架,只修改網絡請求這層的封裝就能夠了,那麼如今咱們須要將 Alamofire
封裝成 Network
,再把 Network
弄到咱們的 BaseComponent
裏面去,怎麼作呢?
如今先將 Network
拖到 BaseComponent
的 Classes
目錄中,由於 BaseComponent
的測試工程沒有 Alamofire
,因此 Network
確定是會報錯了,不要慌,下面咱們修改 spec
文件:
Pod::Spec.new do |s|
s.name = 'BaseComponent'
s.version = '0.2.0'
s.summary = '基礎組價'
s.description = '包括基本配置,常量,擴展,工具類等'
s.homepage = 'https://coding.net/u/tianziyao/p/BaseComponent'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'tianziyao' => 'ziyao.tian@gmail.com' }
s.source = { :git => 'https://git.coding.net/tianziyao/BaseComponent.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'BaseComponent/Classes/**/*'
s.dependency 'Alamofire'
s.dependency 'SDWebImage'
end
複製代碼
dependency
指明瞭這個庫的依賴,改好以後 pod install
,Alamofire
就安裝到了 BaseComponent
的測試工程中,如今就可使用 Alamofire
進行網絡請求封裝,直接 import
就能夠了:
import Foundation
import Alamofire
import SDWebImage
open class Network {
open class func request(url: String, parameters: [String:Any]?) {
Alamofire.request(url, method: .get, parameters: parameters).responseJSON { (response) in
guard let JSON = response.result.value else { return }
print(JSON)
}
}
}
extension UIImageView {
public func image(with url: URL?) {
self.sd_setImage(with: url)
}
}
複製代碼
如今再進行一次遠程私有庫升級,整個依賴就作好了,須要注意的是,已經作了依賴的話,相關的庫就能夠從 Podfile
文件中去掉了:
project 'Ting.xcodeproj'
source 'https://github.com/CocoaPods/Specs.git'
source 'git@git.coding.net:tianziyao/TZYSpecs.git'
target 'Ting' do
use_frameworks!
pod 'BaseComponent'
# pod 'Alamofire'
target 'TingTests' do
inherit! :search_paths
end
target 'TingUITests' do
inherit! :search_paths
end
end
複製代碼
如今是咱們依賴的是公開庫,直接升級 CocoaPods 私有庫就能夠,可是若是依賴的是另一個私有庫,這個依賴關係最終還要上傳到私有索引庫中,這樣其餘人在使用的時候纔會知道這個依賴關係,如今走一下升級的流程,你會獲得相似這個報錯:
[!] The `TargetComponent.podspec` specification does not validate.
複製代碼
這個報錯是由於 TargetComponent
這個庫沒有在官方的索引庫當中,忽略就能夠了,固然,在使用的時候,TargetComponent
這個庫能夠在你的本地索引文件中找到,不然沒法使用。 保險起見,你也能夠在驗證和提交時使用 --sources
命令,例如:
pod repo push TZYSpecs TargetComponent.podspec --sources=git@git.coding.net:tianziyao/TZYSpecs.git,master
複製代碼
如今咱們可讓一個庫依賴另一個庫,可是看下面這段代碼:
/// 獲取中間的視圖
open class func tabBarMiddleView() -> TZYTabBarMiddleView {
let view = Bundle.main.loadNibNamed("TZYTabBarMiddleView", owner: nil, options: nil)?.first
return (view as? TZYTabBarMiddleView) ?? TZYTabBarMiddleView()
}
複製代碼
這段代碼讀取了一個 XIB 文件,這個庫的結構是這樣的:
.
├── Assets
└── Classes
└── MainModule
├── Controller
│ ├── TZYNavBarC.swift
│ └── TZYTabBarC.swift
└── View
├── TZYNavBar.swift
├── TZYTabBar.swift
├── TZYTabBarMiddleView.swift
└── TZYTabBarMiddleView.xib
複製代碼
咱們能夠成功調用這個方法嗎?不能,由於 TZYTabBarMiddleView.xib
這個文件的 Target 是 MainModule
,使用 CocoaPods 把這個庫安裝到咱們項目後,XIB 文件即便在,也是在 Pods 這個工程裏,而咱們在殼工程中使用 TZYTabBarMiddleView.xib
,也是必然找不到的。
下面咱們把模板庫的測試工程編譯一下,打開 Products 目錄下的 .app
文件,看一下文件結構:
.
├── Base.lproj
│ ├── LaunchScreen.nib
│ └── Main.storyboardc
├── Frameworks
│ ├── Alamofire.framework
│ │ ├── Alamofire
│ │ ├── Info.plist
│ │ └── _CodeSignature
│ │ └── CodeResources
│ ├── BaseComponent.framework
│ │ ├── BaseComponent
│ │ ├── Info.plist
│ │ └── _CodeSignature
│ │ └── CodeResources
│ ├── SDWebImage.framework
│ │ ├── Info.plist
│ │ ├── SDWebImage
│ │ └── _CodeSignature
│ │ └── CodeResources
│ ├── TargetComponent.framework
│ │ ├── Info.plist
│ │ ├── TZYTabBarMiddleView.nib
│ │ ├── TargetComponent
│ │ └── _CodeSignature
│ │ └── CodeResources
├── Info.plist
├── PkgInfo
├── TargetComponent_Example
├── _CodeSignature
│ └── CodeResources
└── libswiftRemoteMirror.dylib
複製代碼
經過路徑能夠看到,TZYTabBarMiddleView.nib
是在:
mainBundle/Frameworks/TargetComponent.framework
複製代碼
這個路徑下面,所以 mainBundle.loadXIb
確定是找不到資源文件的,那麼該如何修改呢?
open class func tabBarMiddleView() -> TZYTabBarMiddleView {
let view = Bundle(for: TZYTabBarMiddleView.self).loadNibNamed("TZYTabBarMiddleView", owner: nil, options: nil)?.first
//let view = Bundle.main.loadNibNamed("TZYTabBarMiddleView", owner: nil, options: nil)?.first
return (view as? TZYTabBarMiddleView) ?? TZYTabBarMiddleView()
}
複製代碼
這部分的重點就是 Bundle(for aClass: Swift.AnyClass)
這個方法。
上面咱們講到了怎樣使用 Pod 庫裏面的 XIB 文件,可是還有其餘資源文件,例如圖片、音頻、視頻,圖片咱們通常是放在 Assets.xcassets
,可是 Pod 庫並無對應的路徑,那麼它所須要的圖片放在哪裏,已經如何使用呢?如今使用 pod lib create
命令建立一個 Pod 庫,進入如下路徑:
組件名/Assets
複製代碼
把一些圖片拖入到 Assets
文件夾內,而後在 podspec
文件中加入如下代碼:
s.resource_bundles = {
'組件名' => ['組件名/Assets/*.png'] //只加載 png 文件
# '組件名' => ['組件名/Assets/*'] //加載全部文件
}
複製代碼
而後執行 pod install
,Pod 庫中就出現了以前拖入 Assets
文件夾的圖片,可是如今還不能使用,咱們先來看一下打包之後這些圖片的路徑:
.
├── Base.lproj
│ ├── LaunchScreen.nib
│ └── Main.storyboardc
│ ├── Info.plist
│ ├── UIViewController-vXZ-lx-hvc.nib
│ └── vXZ-lx-hvc-view-kh9-bI-dsS.nib
├── Frameworks
│ ├── TargetComponent.framework
│ │ ├── Info.plist
│ │ ├── TZYTabBarMiddleView.nib
│ │ ├── TargetComponent
│ │ ├── TargetComponent.bundle
│ │ │ ├── Info.plist
│ │ │ ├── tabbar_bg_320x49_@3x.png
│ │ │ └── zxy_icon_48x48_@2x.png
│ │ └── _CodeSignature
│ │ └── CodeResources
│ └── libswiftUIKit.dylib
├── Info.plist
├── PkgInfo
├── TargetComponent_Example
├── _CodeSignature
│ └── CodeResources
├── embedded.mobileprovision
└── libswiftRemoteMirror.dylib
複製代碼
能夠看到,打包後的路徑在:
mainBundle/Frameworks/TargetComponent.framework/TargetComponent.bundle
複製代碼
這個路徑下面,而代碼中的 UIImage(named: "tabbar_bg")
讀取的是 mainBundle
下的資源文件,所以仍是找不到的,那麼這時使用圖片,應該將代碼改爲這樣:
backgroundImage = UIImage.image(withName: "tabbar_bg_320x49_@3x.png")
extension UIImage {
public class func image(withName name: String) -> UIImage? {
let bundle = Bundle(for: UIImage.self)
guard let path = bundle.path(forResource: name, ofType: nil, inDirectory: "TargetComponent.bundle") else {
return nil
}
return UIImage(contentsOfFile: path)
}
}
複製代碼
這裏須要注意的是,文件名須要完整。以上是在代碼中加載圖片,若是是在 XIB 中加載圖片,應該怎樣作呢?那麼再看一下上面的目錄結構,TZYTabBarMiddleView.nib
和 TargetComponent.bundle
處於同一個目錄,咱們能夠在 TZYTabBarMiddleView.xib
中經過相對路徑,使用 TargetComponent.bundle
裏面的圖片,所以在 XIB 中,圖片名應該是這樣的:
TargetComponent.bundle/tabbar_bg_320x49_@3x
複製代碼
如今咱們實現了一個完整的遠程私有庫,能夠升級,依賴其餘的庫,提供給其餘人使用,可是如今還有一點問題,其餘人若是要用咱們的庫,就須要把 BaseComponent
完整的克隆過來,可是他可能只須要 BaseComponent
裏面的 Network
,其餘的擴展、工具等並不想使用,也不想導入過來,怎麼辦?有兩種方案:
Network
剝離出來,再單獨建一個遠程私有庫;Network
;第一種方案你們已經知道了,就是上面的一大篇,麻煩不說,並且東西一多起來,這裏一個庫,那裏一個庫,也不容易管理,因此,下面就有請子庫隆重登場。
在開始以前,咱們先來開一個東西,下面是 pod search AFN
中的一條記錄:
-> AFNetworking (3.1.0)
A delightful iOS and OS X networking framework.
pod 'AFNetworking', '~> 3.1.0'
- Homepage: https://github.com/AFNetworking/AFNetworking
- Source: https://github.com/AFNetworking/AFNetworking.git
- Versions: 3.1.0, 3.0.4, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 3.0.0-beta.3, 3.0.0-beta.2, 3.0.0-beta.1, 2.6.3, 2.6.2, 2.6.1, 2.6.0, 2.5.4, 2.5.3, 2.5.2, 2.5.1, 2.5.0, 2.4.1,
2.4.0, 2.3.1, 2.3.0, 2.2.4, 2.2.3, 2.2.2, 2.2.1, 2.2.0, 2.1.0, 2.0.3, 2.0.2, 2.0.1, 2.0.0, 2.0.0-RC3, 2.0.0-RC2, 2.0.0-RC1, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0, 1.2.1,
1.2.0, 1.1.0, 1.0.1, 1.0, 1.0RC3, 1.0RC2, 1.0RC1, 0.10.1, 0.10.0, 0.9.2, 0.9.1, 0.9.0, 0.7.0, 0.5.1 [master repo]
- Subspecs:
- AFNetworking/Serialization (3.1.0)
- AFNetworking/Security (3.1.0)
- AFNetworking/Reachability (3.1.0)
- AFNetworking/NSURLSession (3.1.0)
- AFNetworking/UIKit (3.1.0)
複製代碼
注意 Subspecs
這裏,它就是本節要講的東西,首先將 spec
改爲下面這樣:
Pod::Spec.new do |s|
s.name = 'BaseComponent'
s.version = '0.4.0'
s.summary = '基礎組價'
s.description = '包括基本配置,常量,擴展,工具類等'
s.homepage = 'https://coding.net/u/tianziyao/p/BaseComponent'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'tianziyao' => 'ziyao.tian@gmail.com' }
s.source = { :git => 'https://git.coding.net/tianziyao/BaseComponent.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
# s.source_files = 'BaseComponent/Classes/**/*'
s.subspec 'Network' do |n|
n.source_files = 'BaseComponent/Classes/Network/**/*'
n.dependency 'Alamofire'
n.dependency 'SDWebImage'
end
s.subspec 'Const' do |c|
c.source_files = 'BaseComponent/Classes/Const/**/*'
end
s.subspec 'Extension' do |e|
e.source_files = 'BaseComponent/Classes/Extension/**/*'
end
s.subspec 'Tool' do |t|
t.source_files = 'BaseComponent/Classes/Tool/**/*'
end
end
複製代碼
在這裏要注意 source_files
和 dependency
以及版本的變化,修改完成推到遠程索引庫,並打好 0.4.0
的分支,執行:
pod spec lint
pod repo push TZYSpecs BaseComponent.podspec
pod update --no-repo-update
pod search Base
複製代碼
如今就能夠找到了:
-> BaseComponent (0.4.0)
基礎組價
pod 'BaseComponent', '~> 0.4.0'
- Homepage: https://coding.net/u/tianziyao/p/BaseComponent
- Source: https://git.coding.net/tianziyao/BaseComponent.git
- Versions: 0.4.0, 0.3.0, 0.2.0, 0.1.0 [TZYSpecs repo]
- Subspecs:
- BaseComponent/Network (0.4.0)
- BaseComponent/Const (0.4.0)
- BaseComponent/Extension (0.4.0)
- BaseComponent/Tool (0.4.0)
複製代碼
那麼如何使用呢?把 Podfile
改爲這樣:
project 'Ting.xcodeproj'
source 'https://github.com/CocoaPods/Specs.git'
source 'git@git.coding.net:tianziyao/TZYSpecs.git'
target 'Ting' do
use_frameworks!
pod 'BaseComponent/Network'
# 也能夠用下面的寫法
# pod 'BaseComponent', :subspecs => ['Network', 'Extension']
target 'TingTests' do
inherit! :search_paths
end
target 'TingUITests' do
inherit! :search_paths
end
end
複製代碼
如今 pod install
,就完成了子庫的建立和使用。
這篇文章斷斷續續寫了快一週,其實通常咱們用不到 CocoaPods 這些功能,不過了解一下 CocoaPods 的工做原理也是沒有壞處的。
這篇文章主要是爲了使用 CocoaPods 進行組件化開發,關於組件化開發的思想,能夠看下面這篇文章: