Cocoapods
是很是好用的一个iOS
依赖管理工具,使用它能够方便的管理和更新项目中所使用到的第三方库,以及将本身的项目中的公共组件交由它去管理。Cocoapods
的介绍及优势本文就不在赘述,我开始使用Cocoapods
仍是在两年前,那个时候它刚刚出现,网上的资料还很是的少,就连他们本身的HomePage
都十分的简单,我就着手尝试着使用了一下,用它管理起第三方库确实是十分的方便顺手。后来它有了更强大的功能就是本身建立podspec
,更能够设置私有的库。html
春节回来上班,一天的工做结束以后,须要充实下本身,正好项目中有一些公共组件须要从庞大的项目体系中剥离出来,并且年前项目终于从SVN
迁移到了Git
,真是喜大普奔,大快人心!这样项目使用Cocoapods
就有了条件,正好学习一下建立私有的podspec
并在项目中部署使用,以及pods
的subspec
的建立及使用。ios
总体先说明一下建立一个私有的podspec
包括以下那么几个步骤:git
Spec Repo
。Pod
的所须要的项目工程文件,而且有可访问的项目版本控制地址。Pod
所对应的podspec
文件。podspec
文件是否可用。Spec Repo
中提交podspec
。Podfile
中增长刚刚制做的好的Pod
并使用。podspec
。在这一系列的步骤中须要建立两个Git仓库
,分别是第一步和第二步(第二步不必定非要是Git仓库
,只要是能够获取到相关代码文件就能够,也能够是SVN
的,也能够说zip包
,区别就是在podspec
中的source
项填写的内容不一样),而且第一步只是在初次建立私有podspec
时才须要,以后在建立其余的只须要从第二步开始就能够。本文只介绍在Git
环境下的操做,其余环境其余方式暂不说明。github
Spec Repo
先来讲第一步,什么是Spec Repo
?他是全部的Pods
的一个索引,就是一个容器,全部公开的Pods
都在这个里面,他实际是一个Git仓库
remote端
在GitHub
上,可是当你使用了Cocoapods
后他会被clone
到本地的~/.cocoapods/repos
目录下,能够进入到这个目录看到master
文件夹就是这个官方的Spec Repo
了。这个master
目录的结构是这个样子的xcode
1
2 3 4 5 |
. ├── Specs └── [SPEC_NAME] └── [VERSION] └── [SPEC_NAME].podspec |
所以咱们须要建立一个相似于master
的私有Spec Repo
,这里咱们能够fork
官方的Repo
,也能够本身建立,我的建议不fork
,由于你只是想添加本身的Pods
,没有必要把现有的公开Pods
都copy
一份。因此建立一个 Git仓库
,这个仓库你能够建立私有的也能够建立公开的,不过既然私有的Spec Repo
,仍是建立私有的仓库吧,须要注意的就是若是项目中有其余同事共同开发的话,你还要给他这个Git仓库
的权限。由于GitHub
的私有仓库是收费的,我还不是GitHub
的付费用户,因此我使用了其余Git
服务,我使用的是CODING
,固然还有其余的可供选择开源中国
、Bitbucket
以及CSDN
ruby
建立完成以后在Terminal
中执行以下命令bash
1
2 |
# pod repo add [Private Repo Name] [GitHub HTTPS clone URL] $ pod repo add WTSpecs https://coding.net/wtlucky/WTSpecs.git |
此时若是成功的话进入到~/.cocoapods/repos
目录下就能够看到WTSpecs
这个目录了。至此第一步建立私有Spec Repo
完成。markdown
PS:若是有其余合做人员共同使用这个私有Spec Repo
的话在他有对应Git仓库
的权限的前提下执行相同的命令添加这个Spec Repo
便可。网络
Pod
项目工程文件这个第二步没有什么好介绍的,若是是有现有的组件项目,而且在Git
的版本管理下,那么这一步就算完成了,能够直接进行下一步了。框架
若是你的组件还在你冗余庞大的项目中,须要拆分出来或者须要本身从零开始建立一个组件库,那么我建议你使用Cocoapods
提供的一个工具将第二步与第三步结合起来作。
如今来讲一下这个工具,相关的文档介绍是Using Pod Lib Create 就拿我建立的podTestLibrary
为例子具体讲一下这里是如何操做的,先cd
到要建立项目的目录而后执行
1
|
$ pod lib create podTestLibrary |
以后他会问你四个问题,1.是否须要一个例子工程;2.选择一个测试框架;3.是否基于View测试;4.类的前缀;4个问题的具体介绍能够去看官方文档,我这里选择的是1.yes;2.Specta/Expecta;3.yes;4.PTL。 问完这4个问题他会自动执行pod install
命令建立项目并生成依赖。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ tree PodTestLibrary -L 2 PodTestLibrary ├── Example #demo APP │ ├── PodTestLibrary │ ├── PodTestLibrary.xcodeproj │ ├── PodTestLibrary.xcworkspace │ ├── Podfile #demo APP 的依赖描述文件 │ ├── Podfile.lock │ ├── Pods #demo APP 的依赖文件 │ └── Tests ├── LICENSE #开源协议 默认MIT ├── Pod #组件的目录 │ ├── Assets #资源文件 │ └── Classes #类文件 ├── PodTestLibrary.podspec #第三步要建立的podspec文件 └── README.md #markdown格式的README 9 directories, 5 files |
以上是项目生成的目录结构及相关介绍。
接下来就是向Pod
文件夹中添加库文件和资源,并配置podspec
文件,我把一个网络模块的共有组件放入Pod/Classes
中,而后进入Example
文件夹执行pod update
命令,再打开项目工程能够看到,刚刚添加的组件已经在Pods
子工程下Development Pods/PodTestLibrary
中了,而后编辑demo工程,测试组件,我并无使用提供的测试框架进行测试,这里就先不介绍了。
注:这里须要注意的是每当你向Pod
中添加了新的文件或者之后更新了podspec
的版本都须要从新执行一遍pod update
命令。
测试无误后须要将该项目添加并推送到远端仓库,并编辑podspec
文件。
经过Cocoapods
建立出来的目录自己就在本地的Git
管理下,咱们须要作的就是给它添加远端仓库,一样去GitHub
或其余的Git
服务提供商那里建立一个私有的仓库,拿到SSH
地址,而后cd
到PodTestLibrary
目录
1
2 3 4 |
$ git add . $ git commit -s -m "Initial Commit of Library" $ git remote add origin git@coding.net:wtlucky/podTestLibrary.git #添加远端仓库 $ git push origin master #提交到远端仓库 |
由于podspec
文件中获取Git
版本控制的项目还须要tag
号,因此咱们要打上一个tag
,
1
2 |
$ git tag -m "first release" 0.1.0 $ git push --tags #推送tag到远端仓库 |
作完这些就能够开始编辑podspec
文件了,它是一个Ruby
的文件,把编辑器的格式改为Ruby
就能看到语法高亮,下面我贴上个人podspec
文件,并在后面以注释的形式说明每一个字段的含义,没有涉及到的字段能够去官方文档查阅
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Pod::Spec.new do |s| s.name = "PodTestLibrary" #名称 s.version = "0.1.0" #版本号 s.summary = "Just Testing." #简短介绍,下面是详细介绍 s.description = <<-DESC Testing Private Podspec. * Markdown format. * Don't worry about the indent, we strip it! DESC s.homepage = "https://coding.net/u/wtlucky/p/podTestLibrary" #主页,这里要填写能够访问到的地址,否则验证不经过 # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" #截图 s.license = 'MIT' #开源协议 s.author = { "wtlucky" => "wtlucky@foxmail.com" } #做者信息 s.source = { :git => "https://coding.net/wtlucky/podTestLibrary.git", :tag => "0.1.0" } #项目地址,这里不支持ssh的地址,验证不经过,只支持HTTP和HTTPS,最好使用HTTPS # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' #多媒体介绍地址 s.platform = :ios, '7.0' #支持的平台及版本 s.requires_arc = true #是否使用ARC,若是指定具体文件,则具体的问题使用ARC s.source_files = 'Pod/Classes/**/*' #代码源文件地址,**/*表示Classes目录及其子目录下全部文件,若是有多个目录下则用逗号分开,若是须要在项目中分组显示,这里也要作相应的设置 s.resource_bundles = { 'PodTestLibrary' => ['Pod/Assets/*.png'] } #资源文件地址 s.public_header_files = 'Pod/Classes/**/*.h' #公开头文件地址 s.frameworks = 'UIKit' #所需的framework,多个用逗号隔开 s.dependency 'AFNetworking', '~> 2.3' #依赖关系,该项目所依赖的其余库,若是有多个须要填写多个s.dependency end |
编辑完podspec
文件后,须要验证一下这个文件是否可用,若是有任何WARNING
或者ERROR
都是不能够的,它就不能被添加到Spec Repo
中,不过xcode
的WARNING
是能够存在的,验证须要执行一下命令
1
|
$ pod lib lint |
当你看到
1
2 3 |
-> PodTestLibrary (0.1.0) PodTestLibrary passed validation. |
时,说明验证经过了,不过这只是这个podspec
文件是合格的,不必定说明这个Pod
是能够用的,咱们须要在本地作一下验证,这就是第四步的内容了,第四步在具体说明。
podspec
文件若是从第二步过来,已经有了现成的项目,那么就须要给这个项目建立一个podspec
文件,建立它须要执行Cocoapods
的另一个命令,官方文档在这里
1
|
$ pod spec create PodTestLibrary git@coding.net:wtlucky/podTestLibrary.git |
执行完以后,就建立了一个podspec
文件,他其中会包含不少内容,能够按照我以前介绍的进行编辑,没用的删掉。编辑完成以后使用验证命令验证一下
1
|
$ pod lib lint |
验证无误就能够进入下一步了。
podspec
文件咱们能够建立一个新的项目,在这个项目的Podfile
文件中直接指定刚才建立编辑好的podspec
文件,看是否可用。 在Podfile
中咱们能够这样编辑,有两种方式
1
2 3 4 |
platform :ios, '7.0' pod 'PodTestLibrary', :path => '~/code/Cocoapods/podTest/PodTestLibrary' # 指定路径 pod 'PodTestLibrary', :podspec => '~/code/Cocoapods/podTest/PodTestLibrary/PodTestLibrary.podspec' # 指定podspec文件 |
而后执行pod install
命令安装依赖,打开项目工程,能够看到库文件都被加载到Pods
子项目中了,不过它们并无在Pods
目录下,而是跟测试项目同样存在于Development Pods/PodTestLibrary
中,这是由于咱们是在本地测试,而没有把podspec
文件添加到Spec Repo
中的缘故。
在项目中编写代码,测试库文件无误后就能够开始下一步了,提交podspec
到Spec Repo
中。
Spec Repo
提交podspec
向Spec Repo
提交podspec
须要完成两点一个是podspec
必须经过验证无误,在一个就是删掉无用的注释(这个不是必须的,为了规范仍是删掉吧)。 向咱们的私有Spec Repo
提交podspec
只须要一个命令
1
|
$ pod repo push WTSpecs PodTestLibrary.podspec #前面是本地Repo名字 后面是podspec名字 |
完成以后这个组件库就添加到咱们的私有Spec Repo
中了,能够进入到~/.cocoapods/repos/WTSpecs
目录下查看
1
2 3 4 5 6 |
. ├── LICENSE ├── PodTestLibrary │ └── 0.1.0 │ └── PodTestLibrary.podspec └── README.md |
再去看咱们的Spec Repo
远端仓库,也有了一次提交,这个podspec
也已经被Push
上去了。
至此,咱们的这个组件库就已经制做添加完成了,使用pod search
命令就能够查到咱们本身的库了
1
2 3 4 5 6 7 8 |
$ pod search PodTestLibrary -> PodTestLibrary (0.1.0) Just Testing. pod 'PodTestLibrary', '~> 0.1.0' - Homepage: https://coding.net/u/wtlucky/p/podTestLibrary - Source: https://coding.net/wtlucky/podTestLibrary.git - Versions: 0.1.0 [WTSpecs repo] |
这里说的是添加到私有的Repo
,若是要添加到Cocoapods
的官方库了,可使用trunk
工具,具体能够查看官方文档
Pod
在完成这一系列步骤以后,咱们就能够在正式项目中使用这个私有的Pod
了只须要在项目的Podfile
里增长如下一行代码便可
1
|
$ pod 'PodTestLibrary', '~> 0.1.0' |
而后执行pod update
,更新库依赖,而后打卡项目能够看到,咱们本身的库文件已经出如今Pods
子项目中的Pods
子目录下了,而再也不是Development Pods
。
podspec
最后再来讲一下制做好的podspec
文件后续的更新维护工做,好比如何添加新的版本,如何删除Pod
。
我已经制做好了PodTestLibrary
的0.1.0
版本,如今我对他进行升级工做,此次我添加了更多的模块到PodTestLibrary
之中,包括工具类,底层Model
及UIKit
扩展等,这里又尝试了一下subspec
功能,给PodTestLibrary
建立了多个子分支。
具体作法是先将源文件添加到Pod/Classes
中,而后按照不一样的模块对文件目录进行整理,由于我有四个模块,因此在Pod/Classes
下有建立了四个子目录,完成以后继续编辑以前的PodTestLibrary.podspec
,此次增长了subspec
特性
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
Pod::Spec.new do |s| s.name = "PodTestLibrary" s.version = "1.0.0" s.summary = "Just Testing." s.description = <<-DESC Testing Private Podspec. * Markdown format. * Don't worry about the indent, we strip it! DESC s.homepage = "https://coding.net/u/wtlucky/p/podTestLibrary" # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" s.license = 'MIT' s.author = { "wtlucky" => "wtlucky@foxmail.com" } s.source = { :git => "https://coding.net/wtlucky/podTestLibrary.git", :tag => "1.0.0" } # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' s.platform = :ios, '7.0' s.requires_arc = true #s.source_files = 'Pod/Classes/**/*' #s.resource_bundles = { # 'PodTestLibrary' => ['Pod/Assets/*.png'] #} #s.public_header_files = 'Pod/Classes/**/*.h' s.subspec 'NetWorkEngine' do |networkEngine| networkEngine.source_files = 'Pod/Classes/NetworkEngine/**/*' networkEngine.public_header_files = 'Pod/Classes/NetworkEngine/**/*.h' networkEngine.dependency 'AFNetworking', '~> 2.3' end s.subspec 'DataModel' do |dataModel| dataModel.source_files = 'Pod/Classes/DataModel/**/*' dataModel.public_header_files = 'Pod/Classes/DataModel/**/*.h' end s.subspec 'CommonTools' do |commonTools| commonTools.source_files = 'Pod/Classes/CommonTools/**/*' commonTools.public_header_files = 'Pod/Classes/CommonTools/**/*.h' commonTools.dependency 'OpenUDID', '~> 1.0.0' end s.subspec 'UIKitAddition' do |ui| ui.source_files = 'Pod/Classes/UIKitAddition/**/*' ui.public_header_files = 'Pod/Classes/UIKitAddition/**/*.h' ui.resource = "Pod/Assets/MLSUIKitResource.bundle" ui.dependency 'PodTestLibrary/CommonTools' end s.frameworks = 'UIKit' #s.dependency 'AFNetworking', '~> 2.3' #s.dependency 'OpenUDID', '~> 1.0.0' end |
由于咱们建立了subspec
因此项目总体的依赖dependency
,源文件source_files
,头文件public_header_files
,资源文件resource
等都移动到了各自的subspec
中,每一个subspec
之间也能够有相互的依赖关系,好比UIKitAddition
就依赖于CommonTools
。
编辑完成以后,在测试项目里pod update
一下,几个子项目都被加进项目工程了,写代码验证无误以后,就能够将这个工程push
到远端仓库,并打上新的tag
->1.0.0
。
最后再次使用pod lib lint
验证编辑好的podsepc
文件,没有自身的WARNING
或者ERROR
以后,就能够再次提交到Spec Repo
中了,命令跟以前是同样的
1
|
$ pod repo push WTSpecs PodTestLibrary.podspec |
以后再次到~/.cocoapods/repos/WTSpecs
目录下查看
1
2 3 4 5 6 7 8 9 10 |
. ├── LICENSE ├── PodTestLibrary │ ├── 0.1.0 │ │ └── PodTestLibrary.podspec │ └── 1.0.0 │ └── PodTestLibrary.podspec └── README.md 3 directories, 4 files |
已经有两个版本了,使用pod search
查找获得的结果为
1
2 3 4 5 6 7 8 9 10 11 12 13 |
$ pod search PodTestLibrary -> PodTestLibrary (1.0.0) Just Testing. pod 'PodTestLibrary', '~> 1.0.0' - Homepage: https://coding.net/u/wtlucky/p/podTestLibrary - Source: https://coding.net/wtlucky/podTestLibrary.git - Versions: 1.0.0, 0.1.0 [WTSpecs repo] - Sub specs: - PodTestLibrary/NetWorkEngine (1.0.0) - PodTestLibrary/DataModel (1.0.0) - PodTestLibrary/CommonTools (1.0.0) - PodTestLibrary/UIKitAddition (1.0.0) |
完成这些以后,在实际项目中咱们就能够选择使用整个组件库或者是组件库的某一个部分了,对应的Podfile
中添加的内容为
1
2 3 4 5 6 7 8 |
source 'https://github.com/CocoaPods/Specs.git' # 官方库 source 'https://git.coding.net/wtlucky/WTSpecs.git' # 私有库 platform :ios, '7.0' pod 'PodTestLibrary/NetWorkEngine', '1.0.0' #使用某一个部分 pod 'PodTestLibrary/UIKitAddition', '1.0.0' pod 'PodTestLibrary', '1.0.0' #使用整个库 |
最后介绍一下如何删除一个私有Spec Repo
,只须要执行一条命令便可
1
|
$ pod repo remove WTSpecs |
这样这个Spec Repo
就在本地删除了,咱们还能够经过
1
|
$ pod repo add WTSpecs git@coding.net:wtlucky/WTSpecs.git |
再把它给加回来。
若是咱们要删除私有Spec Repo
下的某一个podspec
怎么操做呢,此时无需借助Cocoapods
,只须要cd
到~/.cocoapods/repos/WTSpecs
目录下,删掉库目录
1
|
wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ rm -Rf PodTestLibrary |
而后在将Git
的变更push
到远端仓库便可
1
2 3 |
wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ git add --all . wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ git ci -m "remove unuseful pods" wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ git push origin master |
Developing Private In-House Libraries with CocoaPods
http://blog.wtlucky.com/blog/2015/02/26/create-private-podspec/