iOS组件化(三)-podspec使用详解

本文为博主原创文章,未经博主允许不得转载
上一次,我们尝试建立了自己的私有pod库,但是例子相对简单,这次我们详细的解析一下podspec的使用。

一、官方文档地址:

首先,官方文档最为官方:
https://guides.cocoapods.org/syntax/podspec.html

二、spec是什么

spec描述了一个pod库的版本。它包括有关应从何处获取源、使用什么文件、要应用的构建设置以及其他一般元数据(如其名称、版本和描述)的详细信息。
可以通过pod spec create命令创建。
可以简单到:

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

三、Root specification

root spec存储关于库的特定版本的信息,一些属性只能写在root上,而一些细节规范则可以只写在sub spec上面,用于约束细节。
如下为root spec才可以使用的字段(required为必须存在的字段):

  • name(required)
  • version(required)
    pod的版本信息,遵循 semantic versioning.规则,具体规则可参考https://semver.org
  • swift_version
  • authors(required)
  • social_media_url
    社交联系url
  • license(required)
  • homepage(required)
  • source(required)
  • summary(required)
  • description
  • screenshots
  • documentation_url
  • prepare_command
    在pod被清理之前和pod项目被创建之前执行的命令。从pod的根目录作为相对路径
  • static_framework
    如果用了use_frameworks!,则应该声明为true
  • deprecated
    是否library被弃用
  • deprecated_in_favor_of
    被弃用库的名字

四、Platform

  • platform
    指定支持的平台和版本,不写则默认支持所有的平台,如果支持多个平台,则使用下面的deployment_target定义,example:
spec.platform = :osx, '10.8'
spec.platform = :ios
spec.platform = :osx
  • deployment_target
    支持的平台的最小目标,和platform字段相反,他分别指定了不同平台的支持版本
spec.ios.deployment_target = '6.0'
spec.osx.deployment_target = '10.8'

五、Build settings

在这个组中列出了与构建库的配置相关的属性,这些构建环境应该用于构建库。
如果未在子规范中定义,则该组的属性继承父值。

  • dependency
    可以依赖其他的pod库,或者一个subspec,可以是自己建立的subspec
spec.dependency 'AFNetworking', '~> 1.0'
spec.dependency 'RestKit/CoreData', '~> 0.20.0'
spec.ios.dependency 'MBProgressHUD', '~> 0.5'
spec.dependency '自己的主spec/subspec'
  • requires_arc
    设置是否使用ARC,哪些文件使用ARC,默认是true
spec.requires_arc = false
spec.requires_arc = 'Classes/Arc'
spec.requires_arc = ['Classes/*ARC.m', 'Classes/ARC.mm']

如果我们想指定某些文件不使用ARC,我们可以将这些文件放在一个spec.requires_arc = false的subspec里面:

non_arc_files = 'xxx/xxx.{h,m}'
s.subspec 'no-arc' do |mrc|
    mrc.source_files = non_arc_files
    mrc.requires_arc = false
end
  • frameworks
    用户的target需要用到的framework
spec.ios.framework = 'CFNetwork'
spec.frameworks = 'QuartzCore', 'CoreData'
  • weak_frameworks
    弱连接的framework
spec.weak_framework = 'Twitter'
spec.weak_frameworks = 'Twitter', 'SafariServices'
  • libraries
    应用或者target需要使用的library,注意名字为去掉前面lib和后面的类型字段剩下的部分:
spec.ios.library = 'xml2'
spec.libraries = 'xml2', 'z'
  • compiler_flags
    编译器的flags
spec.compiler_flags = '-DOS_OBJECT_USE_OBJC=0', '-Wno-format'
  • pod_target_xcconfig
    添加到最终私有pod目标xcconfig文件的flag
spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' }
  • user_target_xcconfig
    用户的target设置,不建议使用,因为pod的设置不应该污染用户的设置,这可能会导致设置冲突,并且影响其他的pod设置
spec.user_target_xcconfig = { 'MY_SUBSPEC' => 'YES' }
  • prefix_header_contents
    在pod项目的头文件中注入的任何内容。
    不推荐使用此属性,因为pod不应该污染其他库或用户项目的头文件。
spec.prefix_header_contents = '#import <UIKit/UIKit.h>'
spec.prefix_header_contents = '#import <UIKit/UIKit.h>', '#import <Foundation/Foundation.h>'
  • prefix_header_file
    在pod项目的头文件中注入头文件的路径。false指示不应生成默认的CocoaPods头文件。默认为true,并指示应该生成默认的CocoaPods头文件。
    不推荐文件路径选项,因为POD不应该污染其他库或用户项目的前缀标头。
spec.prefix_header_file = 'iphone/include/prefix.pch'
spec.prefix_header_file = false
  • module_name 没用过,直接给官方解释
    The name to use for the framework / clang module which will be generated for this specification instead of the default (header_dir if set, otherwise the specification name).
spec.module_name = 'Three20'
  • header_dir 没用过,直接给官方解释
    The directory where to store the headers files so they don’t break includes.
spec.header_dir = 'Three20Core'
  • header_mappings_dir 没用过,直接给官方解释
    A directory from where to preserve the folder structure for the headers files. If not provided the headers files are flattened.
spec.header_mappings_dir = 'src/include'

六、文件模式

podspec应位于存储库的根目录中,并且应针对存储库的根指定文件路径。文件模式不支持遍历父目录(…)文件模式可以包含以下通配符模式:

  • 符号:*
    • *匹配所有文件
    • c* 匹配所有c开头的文件
    • *c 匹配所有c结尾的文件
    • *c* 匹配所有包含c的文件
  • 符号:**
    递归路径
  • 符号:?
    匹配任意一个字符
  • 符号:[set]
    匹配任意set中的一个字符,和正则规则类似,例如否集[^a-z]
  • 符号:{p,q}
    包含p和q的集合
  • 符号:\
    跳出下一个元字符。

例如在https://github.com/johnezang/JSONKit的文件路径下:

"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"]
(1)source_files

pod的源文件:

spec.source_files = 'Classes/**/*.{h,m}'
spec.source_files = 'Classes/**/*.{h,m}', 'More_Classes/**/*.{h,m}'
(2)public_header_files

应用作公共头文件的的文件模式列表。
这些头文件将暴露给用户的工程,当这个库被建立的时候,这些文件也将出现在build目录下,如果没有设定头文件,那么所有source的头文件都将被暴露。

spec.public_header_files = 'Headers/Public/*.h'
(3)private_header_files

私有的头文件。
如果没有设定公有头文件,所有文件被暴露的情况下,设定私有头文件,则这部分文件将不会暴露出来。
没有被私有和公有头文件设定的文件,将被视作私有的。

spec.private_header_files = 'Headers/Private/*.h'
(4)vendored_frameworks

路径下的framework将与pod一同使用

spec.ios.vendored_frameworks = 'Frameworks/MyFramework.framework'
spec.vendored_frameworks = 'MyFramework.framework', 'TheirFramework.framework'
(5)vendored_libraries

路径下的Library将与pod一同使用

spec.ios.vendored_library = 'Libraries/libProj4.a'
spec.vendored_libraries = 'libProj4.a', 'libJavaScriptCore.a'
(6)resource_bundles

该方式会建立name和file对应的bundle文件
强烈建议使用该方式,将所需的资源打成bundle,这样可以避免文件名的冲突,在命名的时候建议加上pod库的相关名称以避免bundle名字的冲突。

spec.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' }
spec.resource_bundles = {
    'MapBox' => ['MapView/Map/Resources/*.png'],
    'OtherResources' => ['MapView/Map/OtherResources/*.png']
  }
(7)resources

copy至target的资源列表。
强烈建议使用上述的resource_bundles方式,来避免命名冲突,并且该方式是直接拷贝到客户端,没有xcode对相关资源的优化措施。

spec.resource = 'Resources/HockeySDK.bundle'
spec.resources = ['Images/*.png', 'Sounds/*']
(8)exclude_files

应该从其他文件模式中排除的文件模式列表。

spec.ios.exclude_files = 'Classes/osx'
spec.exclude_files = 'Classes/**/unused.{h,m}'
(9)preserve_paths

下载后不应删除的文件。
默认情况下,CocoaPods将移除所有其他文件模式不匹配的文件。

spec.preserve_path = 'IMPORTANT.txt'
spec.preserve_paths = 'Frameworks/*.framework'
(10)module_map

当这个pod集成为framework时所需要使用的模块映射文件。

默认情况下,CocoaPods根据spec中的公共头文件创建模块映射文件。

spec.module_map = 'source/module.modulemap'
(11)script_phases

这个属性允许定义一个脚本,作为编译pod的一部分来执行。与prepare command不同,脚本阶段作为xcodebuild的一部分执行,它们还可以利用编译期间设置的所有环境变量。

一个pod可以提供多个脚本来执行,它们将按照声明的顺序来执行

注意,为了提供可见性和意识到执行内容的情况,如果用户安装了你的pod,如果包含任何脚本,将向用户发出警告。

spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"' }
spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"', :execution_position => :before_compile }
spec.script_phase = { :name => 'Hello World', :script => 'puts "Hello World"', :shell_path => '/usr/bin/ruby' } }
spec.script_phases = [
    { :name => 'Hello World', :script => 'echo "Hello World"' },
    { :name => 'Hello Ruby World', :script => 'puts "Hello World"', :shell_path => '/usr/bin/ruby' } },
  ]

七、Subspecs

一个library可以指定对另一个library的依赖性,另一个library的subspec或自身的subspec。

  • subspec
    表明库的一个子模块的spec
    一般来说,subspec集成父类的值,并且有自己的设定,比如我们在使用如下库时,当我们庄ShareKit,会将她所有的subspec都安装上,有些我们并不需要
pod 'ShareKit', '2.0'

而我们可以指定安装的subspec来安装我们想要的库

pod 'ShareKit/Twitter',  '2.0'
pod 'ShareKit/Pinboard', '2.0'

而这样做的前提是我们设定了ShareKit的诸多subspec。
例如:

  • subspec含有不同的source文件
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
  • 嵌套subspec
Pod::Spec.new do |s|
  s.name = 'Root'

  s.subspec 'Level_1' do |sp|
    sp.subspec 'Level_2' do |ssp|
    end
  end
end
  • requires_app_host
    测试spec是否要求应用程序主机运行测试。这仅适用于测试spec。
test_spec.requires_app_host = true
  • test_spec
    表示库的测试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
  • default_subspecs
    一个subspec的数组,该数组将作为优先依赖的subspec进行提供,如果没有指定,则spec要求全部subspec为依赖项。
    默认情况下,pod应该可以提供完整的库。当用户的要求是已知的,用户可以微调他们的依赖关系,并排除不需要的subspec。因此,很少需要这种属性。它是用来选择默认subspec的,例如有subspec提供替代一些subspec不兼容的实现,或很少需要的模块(特别是如果它们依赖于其他库)
spec.default_subspec = 'Core'
spec.default_subspecs = 'Core', 'UI'

八、多平台支持

为不同的平台不同的代码,例如:

spec.resources = 'Resources/**/*.png'
spec.ios.resources = 'Resources_ios/**/*.png'

不同的平台将拥有不同的资源。

  • ios
spec.ios.source_files = 'Classes/ios/**/*.{h,m}'
  • osx
spec.osx.source_files = 'Classes/osx/**/*.{h,m}'
  • macos
spec.osx.source_files = 'Classes/osx/**/*.{h,m}'
  • tvos
spec.tvos.source_files = 'Classes/tvos/**/*.{h,m}'
  • watchos
spec.watchos.source_files = 'Classes/watchos/**/*.{h,m}'
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值