CocoaPods
是OS X和iOS下的一个第三类库管理工具,通过CocoaPods
工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必须是CocoaPods
本身所支持的),并且可以轻松管理其版本。那么我们能不能通过CocoaPods
来管理我们项目中自己写的工具类,基础类或者说是某个模块的代码呢,答案当然是可以的,下面我们来介绍一下如何使用CocoaPods
来管理自己项目中的工具类。
一、Spec Repo简介
再介绍使用方式之前,我们需要了解Spec Repo
。什么是Spec Repo
呢?它是所有的Pods
的一个索引,相当于是个容器,所有我们可使用的公开的Pods
都存放在这里。我们知道我们目前所用的Pods管理的第三方的源代码基本上都存放于GitHub上
,Spec Repo
实际上就是一个Git
仓库,remote端在GitHub
上。但是当你使用了CocoaPods
之后它会被clone
到本地目录~/.cocoapods/repos
目录下,我们可以进入此目录看到master
文件夹就是官方的Spec Repo
了,其目录结构如下
那么,如果我们需要让自己项目里边的工具类也可以被Pods
管理的话,我们就需要创建一个这样类似master
的私有Spec Repo
。
二、私有库创建步骤
1、创建私有Spec Repo
创建私有的Spec Repo
有两种方法,第一种:我们可以去fork
官方的Repo
,个人不推荐此种方法,因为我们只想要添加自己的Pods
,没有必要把现有的公开的Pods
都copy
一份。第二种:我们自己创建。首先我有一个工具类项目在SVN
服务器上,其结构如下:
那么我们需要将这个工具类项目添加到私有的Spec Repo
里来,命令如下:
$ pod repo add TestTool svn://....../TestTool
复制代码
结果报错如下:
Cloning into 'TestTool'...
fatal: Unable to find remote helper for 'svn'
复制代码
看来这个工具项目SVN服务器不能这么写(暂是没有理会此错误) 那么我们将此工具项目放在Git服务器上,这里我选用的是Coding,然后命令如下:
$ pod repo add TestTool https://git.coding.net/***/TestTool.git
复制代码
此时若成功,则~/.cocoapods/repos
目录如下:
至此,创建私有Spec Repo
完成。 注:如果有其他合作人员共同使用这个私有的Spec Repo,那么在他有对应Git仓库权限的前提下,执行相同的命令添加这个Spec Repo即可
2、创建Pod项目工程文件
这一步就没有什么难点了,就是在工程中添加文件,我们这里工程中已经存在文件Person
类了,所以直接进行下一步。(如果工具类还没有分离出来,那么请看这里)
3、创建podspec文件
如果从第二步过来已经有了现成的项目文件,那么这里我们可以开始创建podspec文件,命令如下:
pod spec create TestTool https://git.coding.net/***/TestTool.git
复制代码
控制台提示:Specification created at TestTool.podspec
则表明文件创建成功。podspec
文件位置如下:
我们使用编辑器打开podspec
文件,编辑器格式修改为Ruby
就可以看到语法高亮,下边是我的podspec
文件的默认内容(删除了注释信息):
Pod::Spec.new do |s|
s.name = "TestTool" #工具库名称
s.version = "0.0.1" #版本号
s.summary = "测试pod使用TestTool工具库" #简单描述信息,下边是详细描述信息
s.description = <<-DESC
TestTool中包含Person类,请在项目中通过pod导入TestTool工具,并使用Person类
DESC
s.homepage = "http://EXAMPLE/TestTool" #主页,可以访问到的地址,不然无法通过验证
s.license = "MIT (example)" #开源协议
s.author = { "用户名" => "邮箱" } #作者信息
s.source = { :git => "http://EXAMPLE/TestTool.git", :tag => "#{s.version}" } #项目地址,git、hg、bzr、svn and http
s.source_files = "Classes", "Classes/**/*.{h,m}" #代码源文件地址,**/*表示Classes目录及其子目录下所有文件,如果有多个目录则用逗号隔开,如果需要在项目中分组显示,请在这里设置
s.exclude_files = "Classes/Exclude"
end
复制代码
将podspec
文件内容根据工具不同做相应修改,然后我们需要验证一下此文件是否可用
***deMini:~ ***$ pod lib lint
-> TestTool (0.0.1)
- ERROR | license: Sample license type.
- WARN | homepage: The homepage has not been updated from default
- ERROR | source: The Git source still contains the example URL.
- WARN | url: There was a problem validating the URL http://EXAMPLE/TestTool.
- ERROR | [OSX] unknown: Encountered an unknown error (The `TestTool` pod failed to validate due to 2 errors:
- ERROR | license: Sample license type.
- WARN | homepage: The homepage has not been updated from default
- ERROR | source: The Git source still contains the example URL.
) during validation.
[!] TestTool did not pass validation, due to 3 errors and 2 warnings.
You can use the `--no-clean` option to inspect any issue.
***deMini:~ ***$
复制代码
可以看到有两个错误,三个警告信息,导致我们的验证没有通过,因为我们的文件里边有些配置需要根据我们的项目进行配置,相应修改项:
s.homepage = "https://coding.net/u/***/p/TestTool"
s.license = "MIT"
s.source = { :git => "https://git.coding.net/***/TestTool.git", :tag => "#{s.version}" }
复制代码
然后重新执行pod lib lint
命令,(重新执行之后,卡了我近半个小时也没反应),最后报错:
***deMini:~ ***$ pod lib lint
-> TestTool (0.0.1)
- ERROR | file patterns: The `source_files` pattern did not match any file.
- WARN | license: Unable to find a license file
[!] TestTool did not pass validation, due to 1 error and 1 warning.
You can use the `--no-clean` option to inspect any issue.
***deMini:~ ***$
复制代码
提示没有匹配到任何资源文件,没有协议文件,继续修改:
s.source_files = "TestTool/Tool", "TestTool/Tool/**/*.{h,m}"
复制代码
并从其他地方复制了一个license文件过来,运行之后依然报错:
-> TestTool (0.0.1)
- ERROR | file patterns: The `source_files` pattern did not match any file.
[!] TestTool did not pass validation, due to 1 error.
You can use the `--no-clean` option to inspect any issue.
复制代码
依然没有匹配到文件,这个时候,我意识到,我的路径出了问题了,此命令是已TestTool.podspec所在目录为基准的,然后我将TestTool.podspec与license两个文件全部移入TestTool文件夹中,目录结构如下:
然后重新执行命令pod lib lint
,结果如下:
-> TestTool (0.0.1)
TestTool passed validation.
复制代码
验证通过,不过这只说明了这个podspec文件是合格的,并不一定说明这个pod是可用的,我们需要在本地做进一步的验证。
4、本地测试podspec文件
所谓的本地测试其实很简单,就是我们创建一个新的项目testPod
,然后走一遍pod
流程,在Podfile
文件中指定刚才创建好的podspec
文件,看是否可用。因为是本地测试,此处Podfile
有两种写法:
- 第一种:指定路径
project 'testPod.xcodeproj'
platform :ios, '9.0'
target 'testPod' do
pod 'TestTool', :path => '/Users/wangbaoxiang/.cocoapods/repos/TestTool'
end
复制代码
这里注意:path路径不要写错,否则会报错无法找到目录下的podspec文件
Analyzing dependencies
Fetching podspec for `TestTool` from `/Users/wangbaoxiang/.cocoapods/repos/TestTool/TestTool`
[!] No podspec found for `TestTool` in `/Users/wangbaoxiang/.cocoapods/repos/TestTool/TestTool`
复制代码
- 第一种:指定
podspec
文件
project 'testPod.xcodeproj'
platform :ios, '9.0'
target 'testPod' do
pod 'TestTool', :podspec => '/Users/wangbaoxiang/.cocoapods/repos/TestTool/TestTool.podspec'
end
复制代码
但是执行pod install
命令安装依赖时报错:
Analyzing dependencies
Fetching podspec for `TestTool` from `/Users/wangbaoxiang/.cocoapods/repos/TestTool/TestTool.podspec`
Downloading dependencies
Installing TestTool (0.0.1)
[!] Error installing TestTool
[!] /Applications/CocoaPods.app/Contents/Resources/bundle/bin/git clone https://git.coding.net/zhongdaima/TestTool.git /var/folders/gt/l6g6khk5053fhhw0d5f7qjw80000gn/T/d20180521-1538-1t17nzn --template= --single-branch --depth 1 --branch 0.0.1
Cloning into '/var/folders/gt/l6g6khk5053fhhw0d5f7qjw80000gn/T/d20180521-1538-1t17nzn'...
fatal: could not read Username for 'https://git.coding.net': Device not configured
复制代码
不能读取https://git.coding.net此链接的用户名密码,这时候需要对podspec
中s.source做特殊处理,添加上用户名密码,这里不做讲解。
接第一种写法,然后我们执行pod install
命令安装依赖,之后我们打开项目,尝试使用TestTool
中的Person
类,效果如下:
运行成功,但是细心的话我们会发现红色框中的问题,TestTool
中的Person
文件并没有在Pods
目录下,而是存在于Development Pods
目录下的TestTool
中,这是因为我们是在本地测试,podspec
文件并没有被添加到Spec Repo
中的缘故。我们本地此时无误之后可以进行下一步,将podspec
提交到Spec Repo
中;
5、向Sepc Repo 提交podspec文件
向Spec Repo
提交podspec
需要:
podspec
必须通过验证无误- 删除无用的注释(非必须,规范还是删除的好) 将我们的私有
Spec Repo
提交podspec
只需要一个命令:
pod repo push TestTool TestTool.podspec
复制代码
执行之后报错:
Validating spec
-> TestTool (0.0.1)
- ERROR | [OSX] unknown: Encountered an unknown error ([!] /usr/bin/git clone https://git.coding.net/zhongdaima/TestTool.git /var/folders/gt/l6g6khk5053fhhw0d5f7qjw80000gn/T/d20180521-4470-1c18v0s --template= --single-branch --depth 1 --branch 0.0.1
Cloning into '/var/folders/gt/l6g6khk5053fhhw0d5f7qjw80000gn/T/d20180521-4470-1c18v0s'...
warning: Could not find remote branch 0.0.1 to clone.
fatal: Remote branch 0.0.1 not found in upstream origin
) during validation.
[!] The `TestTool.podspec` specification does not validate.
复制代码
很明显:我们所需要的0.0.1版本找不到,这个时候我们需要给git
上的代码打个标签
***deMini:TestTool ***$ git tag 0.0.1 #此处有说需要使用v0.0.1,我这里使用了v0.0.1不行
***deMini:TestTool ***$ git tag
0.0.1
***deMini:TestTool ***$ git push origin 0.0.1
复制代码
然后继续运行命令:
Validating spec
-> TestTool (0.0.1)
- WARN | license: Unable to find a license file
[!] The `TestTool.podspec` specification does not validate.
复制代码
在我们的0.0.1版本中缺少license
文件,我们向git代码目录中添加license
文件并重新打0.0.1的tag,然后继续运行命令:
Validating spec
-> TestTool (0.0.1)
[!] The repo `TestTool` at `.` is not clean
复制代码
这个时候我突然意识到这个0.0.1版本是git
上的版本,那么我这个命令其实应该是在从git
上checkout
下来的代码目录中执行的,于是我将TestTool.podspec
文件移到本地代码TestTool
目录中,然后重新执行命令:
Validating spec
-> TestTool (0.0.1)
Updating the `TestTool' repo
From https://git.coding.net/zhongdaima/TestTool
9d38110..ba86f03 master -> origin/master
* [new tag] 0.0.1 -> 0.0.1
Updating 9d38110..ba86f03
Fast-forward
.../UserInterfaceState.xcuserstate | Bin 19853 -> 20498 bytes
license | 21 +++++++++++++++++++++
2 files changed, 21 insertions(+)
create mode 100644 license
Adding the spec to the `TestTool' repo
- [Update] TestTool (0.0.1)
Pushing the `TestTool' repo
复制代码
成功。然后我们进入~/.cocoapods/repos/TestTool
目录下查看:
Coding服务器上也要一次提交:
至此,我们的组件库添加完成,使用pod search
命令查看:
这里我们添加到了私有的Repo,至于如何添加到Cocoapods官方库,可以查看官方文档
6、使用制作好的pod
完成以上步骤之后,我们就可以在自己的项目中使用这个私有的pod
了,
project 'testPod.xcodeproj'
source 'https://{username}:{password}@git.coding.net/{username}/TestTool.git'
source 'https://github.com/CocoaPods/Specs.git'
target 'testPod' do
pod 'TestTool_pod', '~> 0.0.1'
end
复制代码
注:因为我们的TestTool_pod是私有库,所以这里要指定私有库的地址(source 'https://{username}:{password}@git.coding.net/{username}/TestTool.git'
),否则会报错误
#Analyzing dependencies
[!] Unable to find a specification for `TestTool_pod (~> 0.0.1)`
复制代码
执行pod install
命令:
Analyzing dependencies
Downloading dependencies
Using TestTool_pod (0.0.1)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
复制代码
安装成功,然后运行测试:
可以看到红色框内已经显示正常pod
目录了。