目錄
環境
macOS 10.12.6
Xcode 9.1
CocoaPods 1.3.1
Swift 4.0
TL;DR(步驟概述)
1、創建示例工程
pod lib create XGLib
2、編寫 Pod 庫
如果使用了 Swift,需要指定 Swift 版本:在 Terminal 中的項目目錄下,輸入 echo "4.0" > .swift-version
,會在項目根目錄下生成一個 .swift-version
文件
3、Build 項目后,在 Demo 工程中調用
4、修改 podspec 文件
必須修改字段:
s.version
s.summary
s.source
5、本地校驗pod lib lint
6、提交代碼到遠程倉庫
7、為項目打上tag,并推送遠端
git tag -m "first release v0.0.1" 0.0.1
git push --tags #推送tag到遠端倉庫
8、聯網校驗pod spec lint
9、創建私有的 Spec 索引庫
如果已經創建過,就不需要再創建了
10、將創建的私有 Spec 索引庫添加到CocoaPods的目錄下
如果已經添加過,就不需要再添加了
pod repo add CodingSpecRepo https://coding.net/u/rxg9527/p/SpecRepo
11、添加 Podspec 到私有 Spec 索引庫中
pod repo push CodingSpecRepo XGLib.podspec
More: 私有庫升級,添加庫依賴,圖片依賴,私有庫子庫
一、在CocoaPods的指令幫助下創建一個示例工程
# 指令
pod lib create MyLibrary
# 示例
pod lib create XGLib
之后會有一系列問題:
- 使用語言
- 是否需要為你創建一個Demo應用
- 想要使用哪個測試框架
- 是否需要UI Test
- 使用語言為Objective-C的話,會詢問Objective-C類前綴使用什么
這里在第2個問題中輸入Yes
來創建一個Demo應用,以更好的調試和自測Pods庫代碼。
1、Pod Lib Create生成的模版
XGLib目錄結構
├── .travis.yml
├── _Pods.xcproject
├── Example
│ ├── XGLib
│ ├── XGLib.xcodeproj
│ ├── XGLib.xcworkspace
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Pods
│ └── Tests
├── LICENSE
├── XGLib.podspec
├── Pod
│ ├── Assets
│ └── Classes
│ └── RemoveMe.[swift/m]
└── README.md
文件:
-
.travis.yml
- a setup file for travis-ci. -
_Pods.xcproject
- a symlink to your Pod's project for 支持Carthage -
LICENSE
- 默認MIT License. -
XGLib.podspec
- 該庫的Podspec -
README.md
- 默認README -
RemoveMe.swift/m
- a single file to to ensure compilation works initially.
文件夾:
-
Pod
- 個人Pods庫的所有類 -
Example
- 生成的Demo
2、生成的Workspace結構
- 編輯 Podspec metadata, 更改 README 和 Podspec
- Demo 工程
- 測試
- Pods 開發文件夾,真正修改類的區域。
- Finally the Pods used in setting Up the project.
注意:Swift的Class和function要聲明為
public
,才能在Demo中可用
3、Development Pods文件夾
Development Pods 不同于普通的 CocoaPods,是 symlinked files,所以編輯 這些文件會改變源文件,因此可以在 Xcode 中做更改。Demo 和測試文件需要通過#import <MyLib/XYZ.h>
的方式引入頭文件。
注意:
因為 Development Pods 的實現細節, 當添加文件到Pod/Classes
或Pod/Assets
或 更新podspec
,需要執行pod install
或pod update
。
例如我們創建的XGLib
,在pod lib create XGLib
的過程中已經執行過了pod install
,之后添加文件只需執行pod update
。
二、實際編寫 Pod 庫(類庫代碼僅作參考)
1、在XGLib中編寫一個文件
在 Pod/Classes
目錄下刪除 RemoveMe.swift
,創建一個 UILabel-Extension.swift
,代碼如下:
// Swift4.0代碼(3.0可用)
// UILabel-Extension.swift
// XGLib
import Foundation
extension UILabel {
convenience public init(bgColor: UIColor?,
text: String?,
textColor: UIColor?,
fontSize: CGFloat?,
isBold: Bool?,
textAlignment: NSTextAlignment?,
numberOfLines: Int?) {
self.init()
if let color = bgColor {
backgroundColor = color
}
if let text = text {
self.text = text
}
if let textColor = textColor {
self.textColor = textColor
}
if let fontSize = fontSize {
if let isBold = isBold {
if isBold {
font = UIFont.boldSystemFont(ofSize: fontSize)
} else {
font = UIFont.systemFont(ofSize: fontSize)
}
} else {
font = UIFont.systemFont(ofSize: fontSize)
}
}
if let textAlignment = textAlignment {
self.textAlignment = textAlignment
}
if let numberOfLines = numberOfLines {
self.numberOfLines = numberOfLines
}
}
}
2、Build 項目后,在 Demo 工程中調用
?+B
build項目(不先build的話,沒有代碼提示),之后 import
該項目,在 ViewController
中調用。成功運行項目。
3、修改 podspec 文件
podspec
文件主要有以下幾個字段:
- version:這個 spec 映射的版本,保證 Git 的
releases
與此對應; - homepage:項目主頁;
- source:框架源代碼的托管地址;
- tag:與 version 對應;
- source_files:框架源代碼的目錄、文件、文件類型等規則;
4、如果類庫使用了 Swift 語言,需要指定 Swift 版本
在終端中的項目目錄下,輸入 echo "4.0" > .swift-version
,會在項目根目錄下生成一個 .swift-version
文件,如圖
5、提交代碼到遠程倉庫
這里我個人提交到了國內的代碼托管平臺Coding,網址在rxg9527 - XGLib
同時根據我們輸入的 s.version
版本號,我們要對相應的提交記錄打上Tag,并Push到遠程
git tag -m "first release v0.0.1" 0.0.1
git push --tags #推送tag到遠端倉庫
6、校驗私有庫
我們可以用 pod lib lint
和 pod spec lint
兩條命令來對類庫做驗證。
pod lib lint
本地檢查 Pods,主要校驗 podspec 文件pod spec lint
遠程檢查 Pods,這次 CocoaPods 會根據 podspec 文件里的 source 檢查對應的倉庫里有沒有指定tag的倉庫
這時如果一切順利,Pod庫的編寫就大功告成,通過 CocoaPods
的質檢環節了。
三、通過私有的 Spec 索引庫管理使用私有庫
1、創建私有的 Spec 庫
團隊或個人自建的Pods私有庫編寫完成后,我們需要創建一個私有的Spec庫來存放。而 CocoaPods
所有的公有庫都是存放在 CocoaPods
官方建立的 Spec 索引倉庫中的。
示例中,我使用國內的Coding來存放 Spec 庫。
2、將第1步創建的私有SpecRepo添加到CocoaPods的目錄下
# 指令
pod repo add REPO_NAME SOURCE_URL
# 示例
pod repo add CodingSpecRepo https://coding.net/u/rxg9527/p/SpecRepo
此時添加的「私有SpecRepo」目錄是在~/.cocoapods/repos/
下的
[圖片上傳失敗...(image-1ff75c-1512367322220)]
去檢查一下這步添加操作是否成功
# 指令
cd ~/.cocoapods/repos/REPO_NAME
pod repo lint .
# 示例
cd ~/.cocoapods/repos/CodingSpecRepo
pod repo lint .
3、添加 Podspec 到私有 Spec 索引庫中
首先確認已經為私有庫打過tag
并設置了version
,然后運行
# 指令
pod repo push REPO_NAME SPEC_NAME.podspec
# 示例
pod repo push CodingSpecRepo XGLib.podspec
這條指令默認會執行 pod spec lint
做校驗。
此時 ~/.cocoapods/repos/REPO_NAME
下的目錄結構會是
.
├── Specs
└── [SPEC_NAME]
└── [VERSION]
└── [SPEC_NAME].podspec
4、使用私有庫
現在私有庫就可以在 Podfile
文件中指定使用了,通過 source 目錄
的方式使用私有 Spec 索引庫:
# 指令
source 'URL_TO_REPOSITORY'
# 示例
source 'https://coding.net/u/rxg9527/p/SpecRepo/git'
整個 Podfile
文件:
source 'https://github.com/CocoaPods/Specs.git' # CocoaPods 官方 Spec 索引庫
source 'https://coding.net/u/rxg9527/p/SpecRepo/git'
platform :ios, '8.0'
use_frameworks!
target 'UsePrivatePodDemo' do
pod 'XGLib', '~>0.0.1'
end
在 UsePrivatePodDemo
工程中,?+B
build項目(不先build的話,沒有代碼提示),之后 import
該項目,在 ViewController
中調用。成功運行項目。
四、Other
1、私有庫升級
為 UILabel-Extension.swift
添加方法:
import Foundation
extension UILabel {
……
……
/// 背景透明,不加粗,居中對齊
convenience public init(centerText: String?,
textColor: UIColor?,
fontSize: CGFloat?) {
self.init(bgColor: nil, text: centerText, textColor: textColor, fontSize: fontSize, isBold: false, textAlignment: .center, numberOfLines: nil)
}
/// 背景透明,加粗,居中對齊
convenience public init(centerBoldText: String?,
textColor: UIColor?,
fontSize: CGFloat?) {
self.init(bgColor: nil, text: centerBoldText, textColor: textColor, fontSize: fontSize, isBold: true, textAlignment: .center, numberOfLines: nil)
}
}
然后跟之前一樣:
- 在 Demo 工程中調用確認沒問題
-
pod lib lint
本地校驗 - 修改 podspec 文件,至少要修改提高
version
- 提交代碼到遠程倉庫
- 根據
s.version
版本號,對相應的提交記錄打 tag,并 Push 到遠程 -
pod spec lint
聯網校驗 -
pod repo push REPO_NAME SPEC_NAME.podspec
,即pod repo push CodingSpecRepo XGLib.podspec
Okay, That's it!
遠程私有庫和遠程私有索引庫全部更新完畢,現在這個庫只要更新本地的索引文件就可以使用了
pod update --no-repo-update
pod install
2、CocoaPods 庫依賴
假設我們封裝的私有庫要基于某個公有庫做封裝,比如常見的項目中需要我們基于 Alamofire
做一層業務上的封裝??,那么如何在私有庫的制作中,優雅的導入 Alamofire
呢?
CocoaPods
為我們提供了這種能力,通過修改 podspec
文件中的 s.dependency
字段就可以完成,同時可以像 Podfile 中那樣指定版本號。
dependency
指明了這個庫的依賴,下面我們通過依賴 Kingfisher
來示范:
1、 在 XGLib.podspec
中加入
s.dependency 'Kingfisher', '~> 4.0'
2、 新建 UIImageView-Extension.swift
3、 在 Demo 工程中執行 pod update --no-repo-update
會引入 Kingfisher
和 UIImageView-Extension.swift
4、 完成 UIImageView-Extension.swift
//
// UIImageView-Extension.swift
import Foundation
import Kingfisher
extension UIImageView {
public func setImage(with url: URL?) {
self.kf.setImage(with: url)
}
}
5、?+B
build項目(不先build的話,沒有代碼提示),import
該項目,在 ViewController
中調用。
let iv = UIImageView(frame: CGRect(x: 20, y: 120, width: 280, height: 400))
iv.setImage(with: URL(string: "http://wx3.sinaimg.cn/large/9d0d09ably1fl8ilobp1sj213d1jv7e8.jpg"))
view.addSubview(iv)
6、像上一步私有庫升級
一樣,開始升級流程
3、CocoaPods 圖片依賴
Pod 庫中的圖片、音頻、視頻,一般在路徑組件名/Assets
中。
我們可以把一些圖片拖入到 Assets
文件夾內,然后在 podspec
文件中加入以下代碼:
s.resource_bundles = {
'XGLib' => ['XGLib/Assets/*.png']
}
2、 在 Demo 工程中執行 pod update --no-repo-update
會引入圖片資源
3、 ?+B
build項目(不先build的話,沒有代碼提示),import
該項目,在 ViewController
中調用。
let iv2 = UIImageView(frame: CGRect(x: 120, y: 50, width: 200, height: 200))
let privatePodBundle = Bundle(for: privatePodClass.self)
if let path = privatePodBundle.path(forResource: "eat_full.png", ofType: nil, inDirectory: "XGLib.bundle") {
iv2.image = UIImage(contentsOfFile: path)
}
view.addSubview(iv2)
4、像上一步私有庫升級
一樣,開始升級流程
4、CocoaPods 子庫
CocoaPods 有一個子庫的概念,我們在使用一個庫時,可能只需要里面一部分的功能,這時子庫就起到了作用。作為范例,我們可以看一下 pod search AFNetworking
來看一下:
-> 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
就是 AFNetworking 的子庫了,可以看到為了滿足開發者的不同需求, AFNetworking 作者貼心的為我們制作了子庫供調用。
我們也來實踐一下子庫的操作,首先整理XGLib/Classes
目錄結構
[圖片上傳失敗...(image-889d58-1512367322220)]
其實修改 podsepc
文件,修改后如下
Pod::Spec.new do |s|
s.name = 'XGLib'
s.version = '0.2.0'
s.summary = '創建CocoaPods私有庫教程的示例工程'
s.description = <<-DESC
創建CocoaPods私有庫教程的示例工程,1年半前就想寫了……Orz
升級0.2.0 加入子庫,修改子庫dependency
DESC
s.homepage = 'https://coding.net/u/rxg9527/p/XGLib/git'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'ruanxiaogang' => 'rxg9527@sina.cn' }
s.source = { :git => 'https://git.coding.net/rxg9527/XGLib.git', :tag => s.version.to_s }
s.social_media_url = 'https://weibo.com/rxg9527'
s.ios.deployment_target = '8.0'
s.source_files = 'XGLib/Classes/**/*'
s.resource_bundles = {
'XGLib' => ['XGLib/Assets/*.png']
}
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
s.subspec 'ImageView' do |i|
i.source_files = 'XGLib/Classes/ImageView/**/*'
s.dependency 'Kingfisher', '~> 4.0'
end
s.subspec 'Label' do |l|
l.source_files = 'XGLib/Classes/Label/**/*'
end
end
這里要注意 source_files
和 dependency
的變化,修改好之后,像之前私有庫升級
一樣,開始升級流程。
一切順利的話,現在我們執行 pod search XGLib
后,出來的搜索結果會是這樣:
-> XGLib (0.2.0)
創建CocoaPods私有庫教程的示例工程
pod 'XGLib', '~> 0.2.0'
- Homepage: https://coding.net/u/rxg9527/p/XGLib/git
- Source: https://git.coding.net/rxg9527/XGLib.git
- Versions: 0.2.0, 0.1.2, 0.1.1, 0.1.0, 0.0.2, 0.0.1 [CodingSpecRepo repo]
- Subspecs:
- XGLib/ImageView (0.2.0)
- XGLib/Label (0.2.0)
這時我們就可以通過類似 pod 'XGLib/Label', '~>0.1'
的命令來直接引用子庫了。