目录
- 环境
- TL;DR(步骤概述)
-
- 1、创建示例工程
- 2、编写 Pod 库
- 3、Build 项目后,在 Demo 工程中调用
- 4、提交代码到远程仓库
- 5、修改 podspec 文件
- 6、本地校验
pod lib lint
- 7、为项目打上tag,并推送远端
- 8、联网校验
pod spec lint
- 9、创建私有的 Spec 索引库
- 10、将创建的私有 Spec 索引库添加到CocoaPods的目录下
- 11、添加 Podspec 到私有 Spec 索引库中
- More: 私有库升级,添加库依赖,图片依赖,私有库子库
-
- 一、在CocoaPods的指令帮助下创建一个示例工程
-
- 1、Pod Lib Create生成的模版
- 2、生成的Workspace结构
- 3、Development Pods文件夹
-
- 二、实际编写 Pod 库(类库代码仅作参考)
-
- 1、在XGLib中编写一个文件
- 2、Build 项目后,在 Demo 工程中调用
- 3、提交代码到远程仓库
- 4、修改 podspec 文件
- 5、如果类库使用了 Swift 语言,需要指定 Swift 版本
- 6、校验私有库
-
- 三、通过私有的 Spec 索引库管理使用私有库
-
- 1、创建私有的 Spec 库
- 2、将第1步创建的私有SpecRepo添加到CocoaPods的目录下
- 3、添加 Podspec 到私有 Spec 索引库中
- 4、使用私有库
-
- 四、Other
-
- 1、私有库升级
- 2、CocoaPods 库依赖
- 3、CocoaPods 图片依赖
- 4、CocoaPods 子库
-
环境
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
的方式引入头文件。
注意:
因为 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' => '[email protected]' }
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'
的命令来直接引用子库了。