CocoaPods

96
朝洋
0.3 2017.05.18 14:57* 字数 5637

CocoaPods 是什么?

CocoaPods 是一个负责管理 iOS 项目中第三方开源库的工具。CocoaPods 的项目源码在 GitHub( https://github.com/CocoaPods )上管理。

开发 iOS 项目不可避免地要使用第三方开源库,在使用第三方库时,除了需要导入源码,集成这些依赖库还需要我们手动去配置,还有当这些第三方库发生了更新时,还需要手动去更新项目,这就显得非常麻烦。

而 CocoaPods 的出现使得我们可以节省设置和更新第三方开源库的时间,通过 CocoaPods,我们可以将第三方的依赖库统一管理起来,配置和更新只需要通过简单的几行命令即可完成。

为什么要使用 CocoaPods?

在使用 CocoaPods 之前,开发项目需要用到第三方开源库的时候,我们需要:

  1. 把开源库的源代码复制到项目中

  2. 添加一些依赖框架和动态库

  3. 设置 -Objc,-fno-objc-arc 等参数

  4. 管理它们的更新

在使用 CocoaPods 之后,我们只需要把用到的开源库放到一个名为 Podfile 的文件中,然后执行 pod update 就可以了,CocoaPods 就会自动将这些第三方开源库的源码下载下来,并且为我们的工程设置好相应的系统依赖和编译参数。

CocoaPods 的原理

CocoaPods 的原理是将所有的依赖库都放到另一个名为 Pods 的项目中,然后让主项目依赖 Pods 项目,这样就把源码管理工作从主项目移到了 Pods 项目中。

  1. 第三方库会被编译成 .a 静态库或者 .framwork 的动态链接库供我们真正的工程使用。

    CocoaPods 会将所有的第三方库以 target 的方式组成一个名为 Pods 的工程,该工程就放在刚才新生成的 Pods 目录下。整个第三方库工程会生成一个名称为 libPods.a 的静态库供我们的工程使用。

    对于资源文件,CocoaPods 提供了一个名为 Pods-resources.sh 的 bash 脚本,该脚本在项目每次编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中。

  2. 原来的工程设置已经被更改了,这时候我们直接打开原来的工程文件去编译就会报错。我们的工程和第三方库所在的 Pods 工程会被以一个新生成的 workspace 的形式组织和管理,方便我们直观的管理工程和第三方库。

  3. CocoaPods 通过一个名为 Pods.xcconfig 的文件来在编译时设置所有的依赖和参数。

CocoaPods 的核心组件

CocoaPods 是用 Ruby 写的,并划分成了若干个 Gem 包。

与 CocoaPods 相关的两个目录:

  1. ~/.CocoaPods/repos/:这个目录存储远端的 podspec 文件到本地。master 是所有第三方的 podspec 索引文件。其它的是我们自定义的 podspec 索引文件。

  2. ~/Library/Caches/CocoaPods/:这个目录就是缓存文件的存储目录。

CocoaPods 在解析执行过程中最重要的几个包的路径分别是:CocoaPods/CocoaPods、CocoaPods/Core 和 CocoaPods/Xcodeproj。

  1. CocoaPods/CocoaPods:这是面向用户的组件,每当执行一个 pod 命令时,这个组件将被激活。它包括了所有实用 CocoaPods 的功能,并且还能调用其它 Gem 包来执行任务。

  2. CocoaPods/Core:Core Gem 提供了与 CocoaPods 相关的文件(主要是 Podfile 和 Podspecs)的处理。

    1. Podfile:该文件用于配置项目所需要的第三方库,它可以被高度定制。

    2. Podspecs:该文件描述了一个库将怎样被添加进工程中。.podspec 文件可以标识该第三方库所需要的源码文件、依赖库、编译选项,以及其他第三方库需要的配置。

  3. CocoaPods/Xcodeproj:这个包负责处理工程文件,它能创建以及修改 .xcodeproj 文件和 .xcworkspace 文件。它也可以作为一个独立的包使用,当你要编写修改项目文件的脚本时,可以考虑使用 CocoaPods/Xcodeproj。

CocoaPods 的安装

替换源

CocoaPods 是基于 ruby ecosystem 的,需要 ruby 环境,使用 ruby 的 gem 命令。所以我们的系统要有 ruby 环境。而 Mac 系统默认会安装好 ruby 环境,可以在终端输入 $gem sources -l 命令查看系统 ruby 默认源为 https://rubygems.org/,但这个源在国内是访问不到的,所以需要更换 ruby 镜像。

我们可以使用淘宝的源 https://ruby.taobao.org/,但是淘宝的源已经不更新维护了,所以不建议使用淘宝的源,我们最好使用 ruby-china 的源 https://gems.ruby-china.org

  1. 移除系统 ruby 默认源

    $gem sources --remove https://rubygems.org/

  2. 使用新的源

    $gem sources -a https://ruby.taobao.org/(淘宝的源,不建议使用)

    $gem source -a https://gems.ruby-china.org(源已改变:$gem source -a https://gems.ruby-china.com

  3. 验证是否替换成功

    $gem sources -l

    如果结果如下图,表明替换成功。

安装 CocoaPods

  1. 选择版本

    安装最新版本

    $sudo gem install -n /usr/local/bin CocoaPods

    安装指定版本

    $sudo gem install -n /usr/local/bin CocoaPods -v 1.0.0

    安装最新的 release beta 版本

    $sudo gem install -n /usr/local/bin CocoaPods --pre

  2. 安装

    $pod setup

    pod setup 的作用:将所有第三方的 Podspec 索引文件更新到本地的 ~/.CocoaPods/repos 目录下。所有的第三方开源库的 Podspec 文件都托管在 https://github.com/CocoaPods/Specs 管理,我们需要把这个 Podspec 文件保存到本地,这样才能使用命令 pod search 来搜索一个开源库。

    1. 如果没有执行过 pod setup,用户根目录 ~ 下是找不到 .CocoaPods/repos 目录的,没有创建这个目录。

    2. 如果执行了 pod setup,但是命令没有执行成功,那么会创建 ~/.CocoaPods/repos 目录,只不过目录是空的。

    3. 如果执行了 pod setup,并且命令执行成功,说明把 GitHub 上的 Podsepc 文件更新到了本地,那么会创建 ~/.CocoaPods/repos 目录,并且 repos 目录里有一个 master 目录,这个 master 目录保存的就是 GitHub 上所有第三方开源库的 Podspec 索引文件。

第一次执行 pod setup 时,这个 GitHub 上的 Podspec 索引文件比较大,所以第一次更新时非常慢,要耐心等待,我们可以新建一个终端窗口,输入以下命令来查看下载文件的大小。

  1. 进入文件目录 ~/.CocoaPods

    $cd ~/.CocoaPods

  2. 查看文件大小

    $du -sh

  3. 验证是否安装成功以及是否是自己需要的版本

    $pod --version

安装过程常见错误

  1. Gem 版本过低

    Failed to send stats: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert handshake failure

    可以在终端输入以下命令:

    1. 查看 Gem 的版本号

      $gem -v 或者 $gem --version

    2. 升级 Gem

      $sudo gem update --system

      如果出现以下错误:

      ERROR: While executing gem ... (Errno::EPERM) Operation not permitted - /usr/bin/update_rubygems

      则输入以下命令来升级 Gem:

      $sudo gem update -n /usr/local/bin --system

    Gem 介绍:

    1. Gem 是一个管理 Ruby 库和程序的标准包,它通过 RubyGem(如 http://rubygems.org/ )源来查找、安装、升级和卸载软件包,非常的便捷。如果 Gem 的版本过低就会导致 CocoaPods 安装失败。

    2. 所有的 Gem 包会被安装到 /[Ruby root]/lib/ruby/gems/[ver]/ 目录下,其中包括了 cache、doc、gems、specifications 4 个目录,cache 下放置下载的原生 Gem 包,gems 下则放置解压过的 Gem 包。当安装过程中遇到问题时,可以进入这些目录,手动删除有问题的 Gem 包,然后重新安装。

    一些常用的 Gem 命令:

    查看 Gem 配置源:

    $gem sources -l

    Gem 添加配置源:

    $gem sources -a 源的url

    Gem 删除配置源:

    $gem sources -r 源的url

    更新所有 Gem 包:

    $gem update

    更新指定的 Gem 包:

    $gem update [gemname] (注意:此命令不会升级旧版本的包)

    更新 RubyGems 软件:

    $gem update --system

    清除所有 Gem 包旧版本,保留最新版本:

    $gem cleanup

    查看 Gem 环境:

    $gem environment

    从 Gem 源安装 Gem 包:

    $gem install [gemname]

    从本机安装 Gem 包:

    $gem install -l [gemname].gem

    安装指定版本的 Gem 包:

    $gem install [gemname] --version=[版本号]

    删除指定的 Gem 包:

    $gem uninstall [gemname] (注意:此命令将删除所有已安装的版本)

    删除某指定版本 Gem:

    $gem uninstall [gemname] --version=[版本号]

    查看本机已安装的所有 Gem 包:

    $gem list --local

  2. Ruby 版本过低

    ERROR: Error installing CocoaPods: activesupport requires Ruby version >= 2.2.2

    在终端输入以下命令查看当前 Ruby 版本:

    $ruby -v

    Ruby 是什么?

    Ruby 是一种简单快捷的面向对象脚本语言,主要用来实现一些自动化脚本。由于 iOS 系统上没有 Ruby 解释器,所以它通常是在 Mac 系统上使用,在编译前(绝非 app 运行时)进行一些自动化工作。CocoaPods 中的 podfile 其实就是一份 Ruby 代码。

    升级 Ruby

    1. 升级 Ruby 要首先安装 RVM

      RVM:Ruby Version Manager,Ruby 版本管理器,包括 Ruby 的版本管理和 Gem 库管理(gemset)。

      打开终端,执行以下命令:

      $curl -L get.rvm.io | bash -s stable

      期间需要输入管理员密码,然后会自动通过 Homebrew 安装依赖包,等待一段时间后就可以成功安装好 RVM。

      如果出现以下错误:

      Error running 'requirements_osx_port_libs_install curl-ca-bundle automake libtool libyaml libffi libksba', showing last 15 lines of /Users/acewill/.rvm/log/1468253599_ruby-2.3.0/ package_install_curl-ca-bundle_automake_libtool_libyaml_libffi_libksba.log https://github.com/Homebrew/homebrew/wiki/Common-Issues

      原因是 Mac 上未安装 Homebrew,需要先安装 Homebrew。

      Homebrew 是什么?

      Homebrew 是一个包管理器,用于在 Mac 上安装一些 OS X 上没有的 UNIX 工具。Homebrew 将这些工具统统安装到了 /usr/local/Cellar 目录中,并在 /usr/local/bin 中创建符号链接。

      安装 Homebrew

      Homebrew 官网:http://brew.sh

      从 Homebrew 官网获取安装命令在终端执行:

      $/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

      需要等待一段时间,Homebrew 安装成功之后,重新安装 RVM。

      Homebrew 常用命令

      1. 搜索软件:$brew search git

      2. 安装软件:$brew install git

      3. 查看软件信息:$brew info git

      4. 更新自己:$brew update

      5. 检查过时软件:$brew outdated

      6. 升级可以升级的软件:$brew upgrade

      7. 清理不需要的软件版本及其安装包缓存:$brew cleanup

      8. 列出已安装的软件:$brew list

      9. 卸载软件:$brew uninstall git

      RVM 安装成功之后执行以下命令,载入 RVM 环境:

      $source ~/.bashrc

      $source ~/.bash_profile

      $source ~/.profile

      最后,执行以下命令测试是否安装正常:

      $rvm -v

    2. 通过 RVM 升级 Ruby

      1. 列出已知的 Ruby 版本

        $rvm list known

      2. 安装指定的 Ruby 版本

        $rvm install 2.3.3

      3. 列出本地安装的所有 Ruby 版本

        $rvm list

      4. 指定系统默认的 Ruby 版本

        $rvm use 2.3.3 --default

      5. 删除指定的 Ruby 版本

        $rvm remove 2.0.0

      如果网速较慢的话,在执行 $rvm install 2.3.3 命令时,会花费很长的时间,而且很容易报时间超时的错误,解决办法就是多次重试,或者等网速好的时候安装。

      另一种解决办法就是通过 Homebrew 来升级 Ruby。

      打开终端,执行以下命令:

      $brew install ruby

      只需要等待很短的时间就可以升级 Ruby 成功。但通过这种方法升级 Ruby 之后,Gem 的版本可能不是最新的,我们只需要按照上文中提到的升级 Gem 的方法来升级 Gem 即可。但是会出现以下错误:

      ERROR: While executing gem ... (TypeError) no implicit conversion of nil into String

      解决办法:打开 Finder-->前往-->前往文件夹,输入路径 /usr/local/lib/ruby/2.3.0/rubygems/installer.rb,点击前往,找到 installer.rb 文件,打开该文件,找到文件中的以下代码段:

      if ruby_executable then
              question << existing
      

      然后用以下代码段替换找到的代码段:

      if ruby_executable then
            question << (existing || 'an unknown executable')
      

      替换之后,Gem 就可以升级了。

  3. GitHub 无法链接

    error: RPC failed; result=56, HTTP code = 200 fatal: The remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed

    解决办法:翻墙,然后重新安装。

  4. CocoaPods 的分支不支持当前最新的 Xcode 版本

    [!] An error occurred while performinggit pullon repomaster. [!] /usr/bin/git pull --ff-only

    解决办法:删除 master 分支,重新建立新的分支,然后重新设置仓库即可。在终端执行以下命令:

    $sudo rm -fr ~/.CocoaPods/repos/master

CocoaPods 的使用

常用 CocoaPods 命令:

  1. $pod setup

    将所有第三方的 Podspec 索引文件更新到本地的 ~/.CocoaPods/repos/ 目录下,更新本地仓库。

  2. $pod repo update

    执行 pod repo update 更新本地仓库,本地仓库完成后,即可搜索到指定的第三方库,作用类似 pod setup。不过这个命令经常不单独调用。比如执行 pod setuppod searchpod installpod update 会默认执行 pod repo update

  3. $pod search 开源库

    查找某一个开源库。

  4. $pod list

    列出所有可用的第三方库,现在已经 2.4W+ 了,还在不断地增长。

  5. $pod install

    根据 Podfile.lock 文件中列举的版本号来安装第三方框架,如果一开始 Podfile.lock 文件不存在,就会按照 Podfile 文件中列举的版本号来安装第三方框架。

    如果检查到当前三方库已经有的话,那就不会去下载了。

    $pod install –-no-repo-update

    安装开源库之前,不会执行 pod repo update 指令。

  6. $pod update

    将所有第三方框架更新到最新版本,并且创建一个新的 Podfile.lock 文件。

    无论当前三方库是否在项目中已经存在,都会重新下载更新。

    $pod update –-no-repo-update

    更新开源库之前,不会执行 pod repo update 指令。

以下以 AFNetworking 为例介绍 CocoaPods 的使用。

  1. 在终端搜索相应的开源类库

    $pod search AFNetworking

    如果 CocoaPods 支持,将会输出搜索到的所有类库版本和信息,以及在 Podfile 中配置的写法,例如:

    如果提示没有找到该开源库,但是我们这个第三方确实存在:

    1. 我们可以使用 pod setup 更新本地 podspec 索引文件,然后重新搜索。

    2. 如果按照 1 的方法还是搜索不到,那我们就把 ~/Library/Caches/CocoaPods/ 目录下的缓存文件删除。然后 pod setup,再重新搜索。

  2. 进入到我们的工程目录

    $cd 我们的工程路径

  3. 在我们的工程目录下创建 Podfile 文件

    1. 通过 Mac 默认文本编辑器编写

      $touch podfile 创建 Podfile 文件

      $open podfile 打开 Podfile 文件

    打开 Podfile 文件之后即可编写,编写完成之后关闭文本编辑器即可。

    1. 使用 VIM 编辑器编写

      $vim podfile 创建 Podfile 文件并使用 VIM 编写

    执行命令之后默认是编辑模式,用键盘输入 i,进入输入模式,输入 pod 信息,完成之后按 Esc 键,退出输入模式进入编辑模式,然后再输入 : 号,进入末行模式,在 : 号后边输入 wq 保存退出 Podfile 文件,回到终端,继续进行下一步。

    VIM 介绍

    VIM 是一个类似于 VI 的著名的功能强大、高度可定制的文本编辑器。

    VI:Visual Interface,可视化接口。

    VIM:VI iMproved,VI 增强版全屏编辑器,又叫模式化编辑器。

    VIM 有 3 种模式:

       1. 编辑模式(命令模式)(默认模式)
       2. 输入模式
       3. 末行模式
    

    VIM 3 种模式间的转换:

     1. 编辑 --> 输入:
     
         i:在当前光标所在字符的前面,转换为输入模式
         I:在当前光标所在行的行首,转换为输入模式
         a:在当前光标所在字符的后面,转换为输入模式
         A:在当前光标所在行的行尾,转换为输入模式
         o:在当前光标所在行的下方,新建一行,转换为输入模式
         O:在当前光标所在行的上方,新建一行,转换为输入模式  
     2. 输入 --> 编辑:
    
         Esc
         
     3. 编辑 --> 末行:
         
           :
    
     4. 末行 --> 编辑:
     
           Esc + ,或者按两次 Esc
     
     5. 输入模式和末行模式之间不能直接切换
    

    使用 VIM 打开文件:

     1. `$vim 文件名 +#` 打开文件,并定位于第 # 行
     
     2. `$vim 文件名 +:` 打开文件,并定位于最后一行
    

    使用 VIM 关闭文件:

     1. 末行模式下关闭文件
    
         :w  --> 保存
         :w! --> 强行保存
         :q  --> 退出
         :q! --> 不保存并退出
         :wq --> 保存并退出
         :x  --> 保存并退出
         
     2. 编辑模式下关闭文件
    
         ZZ --> 保存并退出
    

    Podfile 介绍

        source 'ssh://git@gitlab.9ijx.com:9830/iOS/Specs.git'
        source 'https://github.com/CocoaPods/Specs.git'
    
        platform :iOS, '8.0'
        
        use_frameworks!
        inhibit_all_warnings!
        workspace 'CocoaPodsTest'
        
        target 'CocoaPodsTest' do
        project 'CocoaPodsTest'
        
        pod 'AFNetworking'
        pod 'JYCarousel', '0.0.1'
        pod 'WCJCache', :git => "http://gitlab.9ijx.com/iOS/WCJCache.git"
        
        target :CocoaPodsTestUITests do
            inherit! :search_paths
            pod 'YYText'
        end
    
        end
    

    Podfile 语法解释:

     1. source
    
         * 指定 specs 的位置,自定义添加自己的 podspec。
         
         * 如果没有自定义添加 podspec,则可以不添加这一项,因为默认使用 CocoaPods 官方的 source。一旦指定了其它 source,那么就必须指定官方的 source,如上例所示。
    
     2. platform :iOS, '8.0'
    
         * 指定了开源库应该被编译在哪个平台以及平台的最低版本。
         
         * 如果不指定平台版本,官方文档里写明各平台默认值为 iOS:4.3,OS X:10.6,tvOS:9.0,watchOS:2.0。
    
     3. use_frameworks!
    
         使用 frameworks 动态库替换静态库链接
         
         * Swift 项目 CocoaPods 默认 use_frameworks!
    
         * OC 项目 CocoaPods 默认 #use_frameworks!
    
     4. inhibit_all_warnings!
    
         * 屏蔽 CocoaPods 库里面的所有警告
         
         * 这个特性也能在子 target 里面定义,如果你想单独屏蔽某 pod 里面的警告也是可以的,例如:
    
             `pod 'JYCarousel', :inhibit_warnings => true`
    
     5. workspace
    
         * 指定包含所有 projects 的 Xcode workspace
    
         * 如果没有指定 workspace,并且在 Podfile 所在目录下只有一个 project,那么 project 的名称会被用作 workspace 的名称
    
     6. target ‘xxxx’ do ... end
    
         * 指定特定 target 的依赖库
    
         * 可以嵌套子 target 的依赖库
     
     7. project
    
         * 默认情况下是没有指定的,当没有指定时,会使用 Podfile 目录下与 target 同名的工程
    
         * 如果指定了 project,如上例所示,则 CocoaPodsTest 这个 target 只有在 CocoaPodsTest 工程中才会链接
    
     8. inherit! :search_paths
    
         * 明确指定继承于父层的所有 pod,默认就是继承的
    
     9. 依赖库的基本写法
    
         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', '<= 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 的版本,写这个限制和什么都不写是一个效果,都表示使用最新版本
    

    关于 Podfile.lock:

     当执行 `pod install` 之后,CocoaPods 会生成一个名为 Podfile.lock 的文件。
     
     Podfile.lock 应该加入到版本控制里面,不应该把这个文件加入到 ignores 中。因为 Podfile.lock 会锁定当前各依赖库的版本,之后如果多次执行 `pod install` 不会更改版本,执行 `pod update` 时才会更改 Podfile.lock。
     
     这样在多人协作的时候,可以防止出现第三方库升级时造成大家各自的第三方库版本不一致。
    
  4. 在终端执行以下命令:

    $pod update –-no-repo-update

    成功之后打开工程,此时我们应该打开最新生成的 .xcworkspace 文件,即可使用该第三方库。

移除项目中已经配置的类库

  1. 打开终端,cd 到已经配置好 CocoaPods 的项目目录下

  2. 打开该目录下的 Podfile 文件

  3. 删除 Podfile 文件中要移除的第三方库

  4. 重新执行 $pod update –-no-repo-update 命令

完成以上步骤即可移除项目中已经配置的类库

移除项目中的 CocoaPods

  1. 删除工程文件夹下的 Podfile、Podfile.lock 和 Pods 文件夹

  2. 删除 .xcworkspace 文件

  3. 打开 xcodeproj 文件,删除项目中的 Pods 文件夹以及 Pods.xcconfig 引用和 libpods.a 静态库

  4. 打开 Build Phases 选项,删除 Check Pods Manifest.lockCopy Pods ResourcesEmbeded Pods Frameworks 选项

完成以上步骤即可移除项目中的 CocoaPods,项目即可编译运行。

CocoaPods 的卸载

在终端执行以下命令:

$sudo gem uninstall CocoaPods

需要输入密码,之后等待很短时间就会显示卸载成功。

卸载指定版本的 CocoaPods:

$sudo gem uninstall CocoaPods -v 0.39.0

iOS
Web note ad 1