从文档开始了解cocoapods之Podspec

概述

距离上一篇podfile介绍过去已经几个月了,很想抽时间将这个系列的文章抓紧补齐,但是时间一拖再拖,我也不想找什么理由。总结一下就是两个原因。

  • 1.最近工作比较忙(这其实是一个借口)
  • 2.确实是比较懒😆。

今天来把这个坑补一下。

这个系列的前两篇文章,其实都是在翻译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😆

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335