CocoaPods【基础篇】

2,549 阅读6分钟

Podfile是一个用来描述项目中Target的依赖的文件

  • 一个简单的Podfile文件
target 'MyApp' do
  use_frameworks!
  pod 'Alamofire', '~> 3.0'
end

1、 use_frameworks!: 在Podfile里使用use_frameworks的话,是通过frameworks的方式来管理pod代码,不配置的话,使用Static Libraries的方式来管理 2、 在pod中导入Swift框架到Swift或者OC项目,都需要使用use_frameworks!,因为Swift不支持静态库 3、 使用Dynamic frameworks,必须要在Podfile文件中添加use_frameworks! 4、 在Podfile文件中,不使用use_frameworks!是,则会生成响应的.a文件(静态链接库),通过静态库的方式管理Pod代码 5、 使用use_frameworks!时,则会生成.framework文件(动态链接库:Header+动态链接库+资源文件),使用Dynamic Frameworks来取代Static Libraries

在Xcode 9,CocoaPods1.5.0之后,Swift支持静态库,最主要的优势加快启动时间

  • 一个复杂的Podfile文件
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/Artsy/Specs.git'

platform :ios, '9.0'
inhibit_all_warnings!

target 'MyApp' do
  pod 'GoogleAnalytics', '~> 3.1'

  # Has its own copy of OCMock
  # and has access to GoogleAnalytics via the app
  # that hosts the test target

  target 'MyAppTests' do
    inherit! :search_paths
    pod 'OCMock', '~> 2.0.1'
  end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    puts target.name
  end
end

inhibit_all_warnings!: 可以直接屏蔽所有第三方pod的警告,同时也提供了单独屏蔽某一个pod的配置项

pod 'ReactiveCocoa', '~> 2.1', :inhibit_warnings => true

有时候想在pod install / pod update的时候做一些除了安装第三方意外的事情,比如关闭所有target的Bitcode功能,就可以使用hooks

有兴趣的可以了解下:CocoaPods Hooks

  • 多个Target共用Pods,使用abstract_target
# There are no targets called "Shows" in any Xcode projects
abstract_target 'Shows' do
  pod 'ShowsKit'
  pod 'Fabric'

  # Has its own copy of ShowsKit + ShowWebAuth
  target 'ShowsiOS' do
    pod 'ShowWebAuth'
  end

  # Has its own copy of ShowsKit + ShowTVAuth
  target 'ShowsTV' do
    pod 'ShowTVAuth'
  end
end

在Podfile根目录中含有隐式abstract_target,因此可以将上述改写为:

pod 'ShowsKit'
pod 'Fabric'

# Has its own copy of ShowsKit + ShowWebAuth
target 'ShowsiOS' do
  pod 'ShowWebAuth'
end

# Has its own copy of ShowsKit + ShowTVAuth
target 'ShowsTV' do
  pod 'ShowTVAuth'
end

指定Pod版本

Pod 'AFNetworking'  // 不显示指定依赖库版本,表示每次都获取最新版本
Pod 'AFNetworking', '2.0'   // 只是用2.0版本
Pod 'AFNetworking', '> 2.0'   //  使用高于2.0的版本
Pod 'AFNetworking', '>= 2.0'    // 使用高于等于2.0的版本
Pod 'AFNetworking', '<= 2.0'    // 使用低于2.0的版本
Pod 'AFNetworking', '~> 0.1.2'  // 使用高于等于0.1.2但低于0.2的版本
Pod 'AFNetworking', '~> 0.1'    // 使用高于等于0.1但低于1.0的版本
Pod 'AFNetworking', '~> 0'      // 高于0的版本,等于没写

使用本地文件

pod 'Alamofire', :path => '~/Documents/Alamofire'

使用自定义的fork

有时候需要对库进行自定义修改,这时候就需要具体说明Pod的描述

  • 使用master分支
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git'
  • 使用非master分支下的repo
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'dev'
  • 使用指定tag
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :tag => '3.1.1'
  • 使用指定commit
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :commit => '0f506b1c45'

值得注意的是,这意味着改版本必须满足Pod对于其他Pod的依赖关系。

Podfile.lock

当你执行pod install之后,除了Podfile之外,CocoaPods还会生成一个名为Podfile.lock的文件,Podfile.lock应该加入到版本控制里面,不应该把这个文件加入到.gitignore中。因为Podfile.lock会锁定当前个依赖库的版本,之后如果多次执行pod install不会更改版本,要pod update才会改Podfile.lock。这样多人协作的时候,可以防止第三方库升级时造成大家各自的第三方库版本不一致。

This file should always be kept under version control.

PODS:
  - AFNetworking (3.0.0):
    - AFNetworking/NSURLSession (= 3.0.0)
    - AFNetworking/Reachability (= 3.0.0)
    - AFNetworking/Security (= 3.0.0)
    - AFNetworking/Serialization (= 3.0.0)
    - AFNetworking/UIKit (= 3.0.0)
  - AFNetworking/NSURLSession (3.0.0):
    - AFNetworking/Reachability
    - AFNetworking/Security
    - AFNetworking/Serialization
  - AFNetworking/Reachability (3.0.0)
  - AFNetworking/Security (3.0.0)
  - AFNetworking/Serialization (3.0.0)
  - AFNetworking/UIKit (3.0.0):
    - AFNetworking/NSURLSession
  - Masonry (0.6.4)

DEPENDENCIES:
  - AFNetworking (= 3.0)
  - Masonry

SPEC REPOS:
  https://github.com/cocoapods/specs.git:
    - AFNetworking
    - Masonry

SPEC CHECKSUMS:
  AFNetworking: 932ff751f9d6fb1dad0b3af58b7e3ffba0a4e7fd
  Masonry: 281802d04d787ea2973179ee8bcb50500579ede2

PODFILE CHECKSUM: ff4af33a0a494eec1db11ee6081aa90709e7a11d

COCOAPODS: 1.6.0

CocoaPods常用命令

pod install和 update 使用时机

## pod install vs pod update

* pod install:添加和删除pods的时候
* pod update:更新pods到新版本
场景举例
  • stage1:User1 创建一个项目,并且加入Pods A, B, C,并且制定版本都为v1.0.0。并且创建Podfile,执行pod install,此时Podfile.lock将会监听并且标记A,B,C的版本为v1.0.0

当执行pod install时,如果.xcodeproj不存在,改命令将会创建.xocdeproj.xcworkspace,但这不是主要的。

  • stage2:User1添加一个Pod D,并且此时Pod B发布了一个新版本v1.1.0,此时要执行pod install用来添加Pod D,这样将不会影响到Pod B

这个情况下有很多人用pod update,他们认为我想要去更新一个新的pods

  • stage3:User2首次加入项目,首先clone了仓库,并且执行了pod install,此时的Podfile.lock将会保证User2拉取到的Pods就是User1使用的版本,即使Pod C更新到v1.2.0,User2此时也只会拉取到v1.0.0,因为在Podfile.lock中已经注册指定,Pod C 已经被Podfile.lock锁定了

  • stage4:User1想要更新已经发布新版本的Pods,此时执行pod outdated列举出Pod B发布了新版本v1.1.0, Pod C发布了新版本v1.2.0。User1决定更新Pod B,但是不更新Pod C,此时执行pod update B,将Pod B从v1.0.0更新到v1.1.0(此时Podfile.lock也相应的更新),但是Pod C并不会改变。

有时候在在没有将Podfile.lock加入版本控制的时候, 仅仅只在Podfile中指定版本号是远远不够的 ,举例如下:

  • User1在Podfile中指定了pod 'A', '1.0.0',pod A有一个依赖库pod A2(A.podpsec中指定 dependency 'A2', '~> 3.0'),在这个例子中,使用pod 'A', '1.0.0',可以确保User1和User2同时都会使用到Pod A v1.0.0,但是,User1在使用的时候A2的最新版本为v3.4,所以在'pod install'时,A2的版本为v3.4,但是在User2的时候,A2的最新版本升到了v3.5,此时User2'pod install',A2将会安装最新版v3.5,和User1的冲突。

1. pod install

根据Podfile文件指定的内容,安装依赖库,如果有Podfile.lock文件而且对应的Podfile文件未被修改,则会根据Podfile.lock文件指定的版本安装。每次更新Podfile文件时,都需要重新执行该命令,以便重新安装Pods依赖库。

2. pod update

如果Podfile中指定的依赖库版本不是写死的,当对应的依赖库有了更新,无论有没有Podfile.lock文件都会去Podfile文件描述的允许获取到最新依赖库版本。

3. pod search

命令格式:

$ pod search Masonry

结果如下:

-> Masonry (1.1.0)
   Harness the power of Auto Layout NSLayoutConstraints with a simplified, chainable and expressive syntax.
   pod 'Masonry', '~> 1.1.0'
   - Homepage: https://github.com/cloudkite/Masonry
   - Source:   https://github.com/cloudkite/Masonry.git
   - Versions: 1.1.0, 1.0.2, 1.0.1, 1.0.0, 0.6.4, 0.6.3, 0.6.2, 0.6.1, 0.6.0, 0.5.3, 0.5.2, 0.5.1, 0.5.0, 0.4.0, 0.3.2, 0.3.1, 0.3.0, 0.2.4, 0.2.3, 0.2.2, 0.2.1, 0.2.0, 0.1.6, 0.1.5, 0.1.0, 0.0.3, 0.0.2 [master repo]

-> Masonry-FlattenLayout (0.1.0)
   More ergonomic thinkable and readable code with the new methods: .gap() .equalTill() .greaterOrEqualTill()
   pod 'Masonry-FlattenLayout', '~> 0.1.0'
   - Homepage: https://github.com/doggy/Masonry-FlattenLayout
   - Source:   https://github.com/doggy/Masonry-FlattenLayout.git
   - Versions: 0.1.0 [master repo]

-> Masonry_HQCategory (0.0.5)
   Masonry_HQCategory
   pod 'Masonry_HQCategory', '~> 0.0.5'
   - Homepage: https://github.com/LiuHuanQing/Masonry_HQCategory
   - Source:   https://github.com/LiuHuanQing/Masonry_HQCategory.git
   - Versions: 0.0.5, 0.0.4, 0.0.3, 0.0.2, 0.0.1 [master repo]

-> MasonryHidden (0.5.0)
   MasonryHidden.
   pod 'MasonryHidden', '~> 0.5.0'
   - Homepage: https://github.com/SunnySunning/MasonryHidden.git
:

4. pod setup

这条命令用于更新本地电脑上的保存的Pods依赖库tree。由于每天有很多人会创建或者更新Pods依赖库,这条命令执行会非常慢。我们需要经常执行这条命令,否则有新的Pods依赖库的时候执行pod search命令是搜不出来的。

输出如下:

$ pod setup
Setting up CocoaPods master repo
  $ /usr/bin/git -C /Users/meitu/.cocoapods/repos/master fetch origin --progress
  remote: Enumerating objects: 15381, done.
  remote: Counting objects: 100% (15381/15381), done.
  remote: Compressing objects: 100% (173/173), done.
  remote: Total 43946 (delta 15241), reused 15270 (delta 15197), pack-reused 28565
  Receiving objects: 100% (43946/43946), 4.85 MiB | 654.00 KiB/s, done.
  Resolving deltas: 100% (30103/30103), completed with 3842 local objects.
  From https://github.com/CocoaPods/Specs
     aaf88082ef6..edceb6eba08  master     -> origin/master
  $ /usr/bin/git -C /Users/meitu/.cocoapods/repos/master rev-parse --abbrev-ref HEAD
  master
  $ /usr/bin/git -C /Users/meitu/.cocoapods/repos/master reset --hard origin/master
  Checking out files: 100% (4609/4609), done.
  HEAD is now at edceb6eba08 [Add] CucumberSwift 2.1.33
warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your diff.renameLimit variable to at least 4318 and retry the command.

CocoaPods 1.7.0.beta.2 is available.
To update use: `sudo gem install cocoapods --pre`
[!] This is a test version we'd love you to try.

For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.7.0.beta.2

Setup completed

5. pod outdated

列出所有在Podfile.lock中,拥有新版本的pods

参考

CocoaPods详解之进阶篇 玩转CocoaPods 用CocoaPods做iOS程序的依赖管理 CocoaPods官网