从文档开始了解cocoapods之Podspec
概述
距离上一篇podfile介绍过去已经几个月了,很想抽时间将这个系列的文章抓紧补齐,但是时间一拖再拖,我也不想找什么理由。总结一下就是两个原因。
- 1.最近工作比较忙(这其实是一个借口)
- 2.确实是比较懒😆。
今天来把这个坑补一下。
这个系列的前两篇文章,其实都是在翻译cocoapods官方文档,也加入了一些自己的理解,并且对文档说明不清的地方做了补充,若有翻译不清楚的地方或者理解不清的地方,大家直接在评论里提出来即可。我看到了就会修改的。
该系列文章链接
- 1.podfile相关内容
- 2.podspec相关内容
- 3.搭建私有cocoapods库
那么接下来,我们进入正题,开始Podspec相关内容的探讨。
一:Podspec文件介绍
podsepc文件的全称我们可以叫做 pod specification,specification是规格说明书的意思,所以顾名思义,podspec就是pod 库的规格说明书(配置文件),这个说明书描述了pod库的版本,包括了源文件的需要的地址,用什么样的文件,需要什么样的构建配置,还有许多普通的元数据像是库的名称,版本号以及描述。
podspec可以通过以下创建
pod spec create "库名"
spec的DSL(特定领域的计算机语言)提供了非常好的扩展性和动态性。另外,DSL还采用了convention over configuration(简而言之就是给定一些默认值从而减少程序员对于某些问题的决策数量)因此可以非常简单,如下。
Pod::Spec.new do |spec|
spec.name = 'Reachability'
spec.version = '3.1.0'
spec.license = { :type => 'BSD' }
spec.homepage = 'https://github.com/tonymillion/Reachability'
spec.authors = { 'Tony Million' => 'tonymillion@gmail.com' }
spec.summary = 'ARC and GCD Compatible Reachability Class for iOS and OS X.'
spec.source = { :git => 'https://github.com/tonymillion/Reachability.git', :tag => 'v3.1.0' }
spec.source_files = 'Reachability.{h,m}'
spec.framework = 'SystemConfiguration'
end
或者可以更加复杂
Pod::Spec.new do |spec|
spec.name = 'Reachability'
spec.version = '3.1.0'
spec.license = { :type => 'BSD' }
spec.homepage = 'https://github.com/tonymillion/Reachability'
spec.authors = { 'Tony Million' => 'tonymillion@gmail.com' }
spec.summary = 'ARC and GCD Compatible Reachability Class for iOS and OS X.'
spec.source = { :git => 'https://github.com/tonymillion/Reachability.git', :tag => 'v3.1.0' }
spec.module_name = 'Rich'
spec.swift_version = '4.0'
spec.ios.deployment_target = '9.0'
spec.osx.deployment_target = '10.10'
spec.source_files = 'Reachability/common/*.swift'
spec.ios.source_files = 'Reachability/ios/*.swift', 'Reachability/extensions/*.swift'
spec.osx.source_files = 'Reachability/osx/*.swift'
spec.framework = 'SystemConfiguration'
spec.ios.framework = 'UIKit'
spec.osx.framework = 'AppKit'
spec.dependency 'SomeOtherPod'
end
二 : 根配置
根配置存储了特定版本库的详细配置信息。这一节李的属性只可以被写在根配置中,不可以写在子配置中。
note:以下的顺序做了一下调整,与官网不同。我将必须配置的选项提到前面,方便查阅。
2.1 name (必须配置)
这个代表了pod库的名称。
spec.name = 'AFNetworking'
2.2 version (必须配置)
这个代表了pod库的版本。cocoapods遵循semantic versioning(一个版本号管理标准)
spec.version = '0.0.1'
2.3 authors (必须配置)
库的作者和邮件地址。
spec.name = 'ErMao'
spec.name = 'ErMao','YiPing'
spec.name = {'ErMao' => '123@qq.com','YiPing' => '321@qq.com'}
2.4 license (必须配置)
库的开源协议。
除非源文件中包含文件名为LICENSE.*或者LICENCE.*的文件,必须要指定协议的完整路径。一旦指定了协议文件,要么是个没有扩展名的文件,要么是txt、md、markdown的其中之一。
spec.license = 'MIT'
spec.license = { :type => 'MIT', :file => 'MIT-LICENSE.txt' }
spec.license = { :type => 'MIT', :text => <<-LICENSE
Copyright 2012
Permission is granted to...
LICENSE
}
2.5 homepage (必须配置)
库的主页。
spec.homepage = 'http://www.ermao.com'
2.6 source (必须配置)
库存放的地址。
指定一个带有tag的git源。tag就是对commit打的标签,通过这个可以区分版本。
{ :git => 'https://github.com/AFNetworking/AFNetworking.git',:tag => spec.version.to_s }
在tag前面加v前缀和子模块
spec.source = { :git => 'https://github.com/typhoon-framework/Typhoon.git',
:tag => "v#{spec.version}", :submodules => true }
使用svn管理源文件
spec.source = { :svn => 'http://svn.code.sf.net/p/polyclipping/code', :tag => '4.8.8' }
使用http下载打包好源文件的包。支持zip、tgz、bz2、txz、tar
spec.source = { :http => 'http://dev.wechatapp.com/download/sdk/WeChat_SDK_iOS_en.zip' }
使用http下载打包好源文件的包。可以使用一个hash值来校验下载文件是否有错误。支持sha1、sha256
spec.source = { :http => 'http://dev.wechatapp.com/download/sdk/WeChat_SDK_iOS_en.zip',
:sha1 => '7e21857fe11a511f472cfd7cfa2d979bd7ab7d96' }
支持的关键字
:git => :tag, :branch, :commit, :submodules
:svn => :folder, :tag, :revision
:hg => :revision
:http => :flatten, :type, :sha256, :sha1
2.7 summary (必须配置)
一个pod库的140之内的小简介。summary需要注意大写和正确的标点符号。
spec.summary = 'Some lalalal.'
2.8 swift_versions
指定swift的版本号。版本号'4'会被cocoapods处理成'4.0',而不是'4.1'或者'4.2'。
note:Swfit编译器主要接受大版本,有时候也会接受小版本。虽然cocoapods接受指定一个小版本或者次要的版本,但是swift不一定会完全支持。
spec.swift_versions = ['3.0','4.0','4.2']
2.9 cocoapods_version
cocoapods的版本号。
spec.cocoapods_version = '>= 1.5.0'
2.10 description
比上面的那个summary更详细的说明。
spec.description = <<-DESC
Computes the meaning of life.
Features:
1. Is self aware
...
42. Likes candies.
DESC
2.11 screenshots
用来展示pod库的一组图片,cocoapods更建议使用gif格式的。
spec.screenshots = [ 'http://dl.dropbox.com/u/378729/MBProgressHUD/1.png',
'http://dl.dropbox.com/u/378729/MBProgressHUD/2.png' ]
2.12 documentation_url
一个存放说明文档的地址。
spec.documentation_url = 'http://www.example.com/docs.html'
2.13 prepare_command
一个pod被下载完成后将要被执行的脚本。这个命令可以被用来创建,删除修改任何下载的文件,并且在配置文件的其他属性被收集之前运行。
这个在pod 被清除和pod被创建之前运行。运行的路径是根路径。
如何pod通过:path选项安装,那么command将不会执行。
spec.prepare_command = 'ruby build_files.rb'
spec.prepare_command = <<-CMD
sed -i 's/MyNameSpacedHeader/Header/g' ./**/*.h
sed -i 's/MyNameOtherSpacedHeader/OtherHeader/g' ./**/*.h
CMD
2.14 static_framework
如果使用了 use_frameworks!(在podfile中标记),pod将要包含一个静态库。
2.15 deprecated
标记着库被弃用了。
spec.deprecated = true
三 : Platform
一个配置文件应该标明对应的平台和对应的部署tagets。如果没有在subspec中标明,那就继承父亲的值。
3.1 platform
标明支持的平台,如果为空,一位置所有的平台都可以支持。如果支持多平台,就使用下方的deployment_target。
spec.platform = :osx, '10.8'
spec.platform = :ios
spec.platform = :osx
3.2 deployment_target
支持平台的最小编译版本。
与platform不同的是,这个属性允许指定多个平台。
spec.ios.deployment_target = '6.0'
spec.osx.deployment_target = '10.8'
四:build settings(构建配置)
这一组主要是列举了创建库所需要的构建配置,如果subspec(子配置)中没有定义,那么将主动继承父亲的值。这里的值都是可以从子类配置的。与(二)中的区别开。
note:在翻译过程中发现很多是官方不建议使用的属性,这里直接屏蔽,也没必要看。
4.1 dependency
添加依赖。
依赖可以指定版本需求,表达式 是 ~> ,比如 ~> 1.0.1 意思就是 >= 1.0.1并且 < 1.1 。类似的 ~> 1.0 会匹配到1.0,1.0.1等,不会升级到2.0.
sepc.dependency 'AFNetworking', '~> 1.0'
4.2 requires_arc
这个属性允许指出哪一个source_file使用arc。可以指定某个文件使用arc,也可以设置 true or false 来指定整个源文件。
不使用ARC的文件,需要有-fno-objc-arc编译器标识。
默认值是true
spec.requires_arc = true
spec.requires_arc = false
spec.requires_arc = 'Classes/Arc'
spec.requires_arc = ['Classes/*ARC.m', 'Classes/ARC.mm']
4.3 frameworks
需要链接的framework列表。
spec.ios.framework = 'CFNetwork'
spec.frameworks = 'QuartzCore', 'CoreData'
4.4 weak_frameworks
需要弱链接的库列表。
spec.weak_framework = 'Twitter'
spec.weak_frameworks = 'Twitter', 'SafariServices'
4.5 libraries
需要链接的系统库列表。
spec.ios.library = 'xml2'
spec.libraries = 'xml2', 'z'
4.6 compiler_flags
编译器标识,可以将值传递给编译器。
spec.compiler_flags = '-DOS_OBJECT_USE_OBJC=0', '-Wno-format'
4.7 module_name
这个名字用于框架或者clang模块的名称,该模块会根据spec生成,而不使用默认名称。
spec.module_name = 'Three20'
4.8 header_dir
整体的头文件。包含了其他用得到的头文件,避免分开导入
spec.header_dir = 'Three20Core'
4.9 header_mappings_dir
保存头文件夹的目录。
spec.header_mappings_dir = 'src/include'
4.10 script_phases
这个脚本是作为pod的编译的一部分,但是与prepare command不同,script是作为xcodebuild的一部分执行的,脚本可以利用编译器的一切环境变量。脚本的执行顺序是按照声明顺序执行的。
note:为了提供透明性,如果库里包含脚本,那么将会对用户有一个提醒。
spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"' }
spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"',
:input_file_lists => ['/path/to/input_files.xcfilelist'], :output_file_lists => ['/path/to/output_files.xcfilelist']
}
spec.script_phases = [
{ :name => 'Hello World', :script => 'echo "Hello World"' },
{ :name => 'Hello Ruby World', :script => 'puts "Hello World"', :shell_path => '/usr/bin/ruby' },
]
五 : File patterns(文件模式、类型)
这里主要了解一下cocoapods文件的通配符。因为 podspec文件是放到根目录的,所以是不支持 '..' 的。
*:一般意义上的通配符,意思就是全匹配。c*就是c开头的,*c就是c结尾的。与正则 /.*/x一样
**:递归文件夹
?:匹配任何字符
[set]:匹配数组里面的任意字符
{p,q}:匹配p或者匹配q
\:转义
"JSONKit.?" #=> ["JSONKit.h", "JSONKit.m"]
"*.[a-z][a-z]" #=> ["CHANGELOG.md", "README.md"]
"*.[^m]*" #=> ["JSONKit.h"]
"*.{h,m}" #=> ["JSONKit.h", "JSONKit.m"]
"*" #=> ["CHANGELOG.md", "JSONKit.h", "JSONKit.m", "README.md"]
5.1 source_file
源文件。
spec.source_files = 'Classes/**/*.{h,m}', 'More_Classes/**/*.{h,m}'
5.2 public_header_files
用来做公共头文件的文件列表。这些头文件是要给用户看的,并且可以根据这些生成对应的文档,当库被构建的时候,这些头文件将要在构建的文件夹中出现。如果没有指定公共头文件,那么source_file里的头文件都会被视为公开的。
spec.public_header_files = 'Headers/Public/*.h'
5.3 exclude_files
从文件列表中剔除的文件
spec.ios.exclude_files = 'Classes/osx'
spec.exclude_files = 'Classes/**/unused.{h,m}'
六 : Subspecs
子说明。
6.1 subspec
代表了一个库的其中一个模块的说明。
一方面,一个说明书将会自动的作为children的子说明书(除非一个默认的子说明书被指定)。另一方面,一个子说明从父说明继承属性的值,所以公共属性的值可以在父说明中被指定。
比如说ShareKit/Evernote, ShareKit/Facebook。
pod 'ShareKit/Twitter', '2.0'
pod 'ShareKit/Pinboard', '2.0'
只是添加shareKit的其中的两个部分,注意:在这种情况下,子说明将要编译需要的源文件,依赖以及其他通过根说明定义的属性。cocoapods非常智能,可以来处理任何来自属性的冲突。
有着不同源文件的子说明
subspec 'Twitter' do |sp|
sp.source_files = 'Classes/Twitter'
end
subspec 'Pinboard' do |sp|
sp.source_files = 'Classes/Pinboard'
end
引用对其他子说明依赖关系的子说明。
Pod::Spec.new do |s|
s.name = 'RestKit'
s.subspec 'Core' do |cs|
cs.dependency 'RestKit/ObjectMapping'
cs.dependency 'RestKit/Network'
cs.dependency 'RestKit/CoreData'
end
s.subspec 'ObjectMapping' do |os|
end
end
嵌套的子说明
Pod::Spec.new do |s|
s.name = 'Root'
s.subspec 'Level_1' do |sp|
sp.subspec 'Level_2' do |ssp|
end
end
end
6.2 requires_app_host
这个属性标明,测试是否需要在app的主机进行测试。这个属性只是在测试说明中有用。
test_spec.requires_app_host = true
6.3 test_spec
测试说明。在这里可以放置针对于podspec的所有测试。
Pod::Spec.new do |spec|
spec.name = 'NSAttributedString+CCLFormat'
spec.test_spec do |test_spec|
test_spec.source_files = 'NSAttributedString+CCLFormatTests.m'
test_spec.dependency 'Expecta'
end
end
6.4 app_spec
表示库的应用程序说明。在这里,可以为podspec放置所有应用程序源文件以及应用程序依赖项。
Pod::Spec.new do |spec|
spec.name = 'NSAttributedString+CCLFormat'
spec.app_spec do |app_spec|
app_spec.source_files = 'NSAttributedString+CCLFormat.m'
app_spec.dependency 'AFNetworking'
end
end
七 : Multi-Platform support(多平台支持)
说明书可以存储指定平台的相关值。
spec.resources = 'Resources/**/*.png'
spec.ios.resources = 'Resources_ios/**/*.png'
spec.osx.source_files = 'Classes/osx/**/*.{h,m}'
spec.tvos.source_files = 'Classes/tvos/**/*.{h,m}'
spec.watchos.source_files = 'Classes/watchos/**/*.{h,m}'
八 : 结束语
以上就是podspec的相关文档的翻译,这里我删减了一些不常用的,官方不推荐的使用的属性。这个可以作为一个podspec的开发手册。如果有什么问题,大家可以在留言板直接留言。我会及时跟大家讨论并更正问题。
如果您觉得对您有用,不妨点个赞呗,转载请注明
我是二毛,一个集智慧和逗比于一身的iOSer😆