让自己的开源库支持CocoaPods

在iOS开发中,CocoaPods几乎成了使用第三方库的标配工具,因此我们也可以让自己的公共库也支持CocoaPods。


让自己的开源库支持CocoaPods

最近尝试整理这一年在项目中自己写的一些功能扩展和封装,突然想起来我还没有试过将自己的功能库上传CocoaPods,这样子就算换个项目,只需要Pod install,就能在下个项目中继续使用那些整理好的功能。

因为是第一次尝试,所以就先将一个非常小的原生弹框封装作为使用对象吧。

第一步

原本的项目文件结构:

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
//需要上传GitHub的文件
.
├── LICENSE // MIT license
├── MyUIDemo
│   ├── AppDelegate.h
│   ├── AppDelegate.m
│   ├── Assets.xcassets
│   │   ├── AppIcon.appiconset
│   │   │   └── Contents.json
│   │   └── Contents.json
│   ├── Base.lproj
│   │   ├── LaunchScreen.storyboard
│   │   └── Main.storyboard
│   ├── Info.plist
│   ├── SeaNativeHUD // 真正需要让CocoaPods知道的文件夹
│   │   ├── SeaNativeHUD.h
│   │   └── SeaNativeHUD.m
│   ├── ViewController.h
│   ├── ViewController.m
│   └── main.m
├── MyUIDemo.xcodeproj
│   ├── project.pbxproj
│   └── project.xcworkspace
│   ├── contents.xcworkspacedata
│   └── xcshareddata
│   └── IDEWorkspaceChecks.plist
├── README.md //开源库的说明文件
└── logo.png

CocoaPods强制要求所有的Pods依赖库都必须有license文件,否则验证不会通过。

然后 cd 到这个文件夹里面,使用:pod spec create 你的库名创建一个podspec文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

.
.
.

│   ├── SeaNativeHUD
│   │   ├── SeaNativeHUD.h
│   │   └── SeaNativeHUD.m
│   ├── ViewController.h
│   ├── ViewController.m
│   └── main.m
├── MyUIDemo.xcodeproj
│   ├── project.pbxproj
│   └── project.xcworkspace
│   ├── contents.xcworkspacedata
│   └── xcshareddata
│   └── IDEWorkspaceChecks.plist
├── README.md
├── SeaNativeHUD.podspec // 创建一个podspec文件
└── logo.png

然后打开这个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
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#
# Be sure to run `pod spec lint test.podspec' to ensure this is a
# valid spec and to remove all comments including this before submitting the spec.
#
# To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#

Pod::Spec.new do |s|

# ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# These will help people to find your library, and whilst it
# can feel like a chore to fill in it's definitely to your advantage. The
# summary should be tweet-length, and the description more in depth.
#

s.name = "test"
s.version = "0.0.1"
s.summary = "A short description of test."

# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC
DESC

s.homepage = "http://EXAMPLE/test"
# s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"


# ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# Licensing your code is important. See http://choosealicense.com for more info.
# CocoaPods will detect a license file if there is a named LICENSE*
# Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
#

s.license = "MIT (example)"
# s.license = { :type => "MIT", :file => "FILE_LICENSE" }


# ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# Specify the authors of the library, with email addresses. Email addresses
# of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
# accepts just a name if you'd rather not provide an email address.
#
# Specify a social_media_url where others can refer to, for example a twitter
# profile URL.
#

s.author = { "Bob" => "hgdigm@gmail.com" }
# Or just: s.author = "Bob"
# s.authors = { "Bob" => "hgdigm@gmail.com" }
# s.social_media_url = "http://twitter.com/Bob"

# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# If this Pod runs only on iOS or OS X, then specify the platform and
# the deployment target. You can optionally include the target after the platform.
#

# s.platform = :ios
# s.platform = :ios, "5.0"

# When using multiple platforms
# s.ios.deployment_target = "5.0"
# s.osx.deployment_target = "10.7"
# s.watchos.deployment_target = "2.0"
# s.tvos.deployment_target = "9.0"


# ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# Specify the location from where the source should be retrieved.
# Supports git, hg, bzr, svn and HTTP.
#

s.source = { :git => "http://EXAMPLE/test.git", :tag => "#{s.version}" }


# ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# CocoaPods is smart about how it includes source code. For source files
# giving a folder will include any swift, h, m, mm, c & cpp files.
# For header files it will include any header in the folder.
# Not including the public_header_files will make all headers public.
#

s.source_files = "Classes", "Classes/**/*.{h,m}"
s.exclude_files = "Classes/Exclude"

# s.public_header_files = "Classes/**/*.h"


# ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# A list of resources included with the Pod. These are copied into the
# target bundle with a build phase script. Anything else will be cleaned.
# You can preserve files from being cleaned, please don't preserve
# non-essential files like tests, examples and documentation.
#

# s.resource = "icon.png"
# s.resources = "Resources/*.png"

# s.preserve_paths = "FilesToSave", "MoreFilesToSave"


# ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# Link your library with frameworks, or libraries. Libraries do not include
# the lib prefix of their name.
#

# s.framework = "SomeFramework"
# s.frameworks = "SomeFramework", "AnotherFramework"

# s.library = "iconv"
# s.libraries = "iconv", "xml2"


# ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# If your library depends on compiler flags you can set them in the xcconfig hash
# where they will only apply to your library. If you depend on other Podspecs
# you can include multiple dependencies to ensure it works.

# s.requires_arc = true

# s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
# s.dependency "JSONKit", "~> 1.4"

end

我们可以发现有很多代码都是注释状态,这些都是先准备好的模板,我们选择我们需要的变量去赋值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Pod::Spec.new do |s|

s.name = "SeaNativeHUD"
s.version = "0.0.1"
s.summary = "A easy function for Native HUD."
s.description = "在iOS上面使用的原生风格弹框组件,对项目代码无侵入,使用简单."
s.homepage = "https://github.com/seabrea/SeaNativeHUD"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "seabrea" => "hgdigm@gmail.com" }
s.platform = :ios, "9.0"
s.ios.deployment_target = "9.0"
s.source = { :git => "https://github.com/seabrea/SeaNativeHUD.git", :tag => "#{s.version}" }
s.source_files = "MyUIDemo/SeaNativeHUD/**/*.{h,m}"
s.requires_arc = true

end

解释一下我所选择的属性:

  • s.name:库名
  • s.version:版本号
  • s.summary:简介
  • s.description:描述
  • s.homepage:首页
  • s.license:许可证
  • s.author:作者
  • s.platform:支持的平台及版本
  • s.ios.deployment_target:最低要求的系统版本
  • s.source:源文件的文字
  • s.source_files:选择所允许下载的文件(pod install时下载的文件)
  • s.requires_arc:支持ARC
  • s.dependency:依赖库

tag => “#{s.version}” 表示版本号和Tag号一致,这样就可以方便版本控制

s.source_files的常见写法:

1
2
3
4
>  - "Dic/*"              //“*” 表示匹配所有文件
> - "Dic1/Dic2/*.{h,m}" //“*.{h,m}” 表示匹配所有以.h和.m结尾的文件
> - "Dic/**/*.h" //“**” 表示匹配所有子目录
>

此时,第一步就完成了。

第二步

接下来,我们需要在GitHub上面创建一个仓库,并把这个项目上传至GitHub上面你准备好的仓库中。

并将为你准备好的这个版本打上Tag

1
2
git tag "0.0.1"
git push --tags

也可以使用SourceTree完成上面所有Git相关的操作,原理都是一样的。
另外如果你写了(tag => "#{s.version}"),那tag号和s.version要保持一致。

做完以后我们需要验证验证一下,在有你的podspec文件的目录下输入:pod spec lint 你的库名.podspec --verbose

如果你的那些步骤啊之类的处理错了,此时会报错,大部分错误只需要copy+搜索就能解决。

而你的描述过短之类的问题,则会报警告,但是警告并不影响验证,有时候你可以选择pod lib lint --allow-warnings来忽略警告⚠️。

当最后出现XXXX passed validation时则表示验证通过了。

第三步

万事俱备只欠东风。
接下来就是发布这个库的时候了。

首先你需要检查下你有没有上传的资格,只有注册后的用户才能上传。

输入pod trunk me来检查一下。如果不能查看到用户信息,则表示你不是用户。

创建用户:pod trunk register 邮箱 "用户名",创建完成后,进入你填写的邮箱,会收到一个验证链接,点击链接完成验证。

最后一步:
pod trunk push 你的库名.podspec

稍微等一下后,如果出错,会有错误提示; 如果成功了,会有恭喜成功的提示。

然后更新一下你的本地CocoaPod Spec库,然后pod search 你的库名,就可以看到你的库了。

总结

事实上,将自己的库上传CocoaPods并不麻烦,做好每个步骤可以避免大部分的问题。

最后附上这个库的地址:https://github.com/seabrea/SeaNativeHUD

数据结构(Data Structure) MarkDown整理

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×