CocoaPods介绍

CocoaPods 是开发 OS X 和 iOS 应用程序的一个第三方库的依赖管理工具。利用 CocoaPods,可以定义自己的依赖关系 (称作 pods),并且随着时间的变化,以及在整个开发环境中对第三方库的版本管理非常方便。

CocoaPods 背后的理念主要体现在两个方面。首先,在工程中引入第三方代码会涉及到许多内容。针对 Objective-C 初级开发者来说,工程文件的配置会让人很沮丧。在配置 build phases 和 linker flags 过程中,会引起许多人为因素的错误。CocoaPods 简化了这一切,它能够自动配置编译选项。

其次,通过 CocoaPods,可以很方便的查找到新的第三方库。当然,这并不是说你可以简单的将别人提供的库拿来拼凑成一个应用程序。它的真正作用是让你能够找到真正好用的库,以此来缩短我们的开发周期和提升软件的质量。

核心组件

CocoaPods是用 Ruby 写的,并由若干个 Ruby 包 (gems) 构成的。在解析整合过程中,最重要的几个 gems 分别是:CocoaPods/CocoaPods, CocoaPods/Core, 和 CocoaPods/Xcodeproj (是的,CocoaPods 是一个依赖管理工具 -- 利用依赖管理进行构建的!)。

CocoaPods 是一个 objc 的依赖管理工具,而其本身是利用 ruby 的依赖管理 gem 进行构建的。

CocoaPods/CocoaPod 这是是一个面向用户的组件,每当执行一个 pod 命令时,这个组件都将被激活。该组件包括了所有使用 CocoaPods 涉及到的功能,并且还能通过调用所有其它的 gems 来执行任务。

CocoaPods/Core Core 组件提供支持与 CocoaPods 相关文件的处理,文件主要是 Podfile 和 podspecs。

CocoaPods/Xcodeproj 这个 gem 组件负责所有工程文件的整合。它能够对创建并修改 .xcodeproj 和 .xcworkspace 文件。它也可以作为单独的一个 gem 包使用。如果你想要写一个脚本来方便的修改工程文件,那么可以使用这个 gem。

Ruby 概述

Ruby 的语法具有强大的表现力,并且其使用非常灵活,能快速实现我们的需求,这里简单介绍一下 Ruby 中跟CocoaPods有关的特性。

方法

简单的方法

def method_name (var1=value1, var2=value2)expr..
end
复制代码

ruby中的方法以'def'开头,以'end'作为结尾,我们可以为参数设置默认值,如果方法调用时未传递必需的参数则使用默认值,上例中的value1value2就是默认值。

Ruby 代码在调用方法时可以省略括号。

可变数量的参数

def sample (*test)puts "参数个数为 #{test.length}"for i in 0...test.lengthputs "参数值为 #{test[i]}"end
end
sample "Zara", "6", "F"
复制代码

以上实例的输出结果为:

参数个数为 3
参数值为 Zara
参数值为 6
参数值为 F
复制代码

数据类型--Hash

哈希(Hash)是类似 "key" => "value" 这样的键值对集合。哈希类似于一个数组,只不过它的索引(或者叫"键")不局限于使用数字,Hash 的索引几乎可以是任何对象。

Hash 虽然和数组类似,但却有一个很重要的区别:Hash 的元素没有特定的顺序。 如果顺序很重要的话就要使用数组了。

pod 'SwViewCapture', :git=>'git@github.com:startry/SwViewCapture.git', :branch=>'master'
复制代码
def pod(name = nil, *requirements)unless nameraise StandardError, 'A dependency requires a name.'endcurrent_target_definition.store_pod(name, *requirements)
end
复制代码

pod方法后面跟着的参数就是一个Hash的对象,写成key-value的形式就是

{":git": "git@github.com:startry/SwViewCapture.git",":branch": "'master'"
}
复制代码

block

Ruby 对函数式编程范式的支持是通过 block,Ruby 中的 block 也是一种对象,所有的 Block 都是 Proc 类的实例,也就是所有的 block 可以作为参数传递,返回。

这边构造一个block传参的方法

def target(name, &proc)definition = TargetDefinition.new(name, parent)proc.call() if proc
end
复制代码

除了声明block参数作为参数传入,还可以使用关键字yield在ruby中表示调用块。

yield 主要用于隐式 block 回调,ruby 方法默认可以不声明 block,在其内部可通过 yield 回调。yield 会调用外部传入的 block,block_given? 用于判断当前方法是否传入了 block。

def target(name)definition = TargetDefinition.new(name, parent)yield if block_given?
end
复制代码

Ruby中do ~end之间的部分称为块,也可以写为{..}

所以这个target方法可以以这种形式调用:

target('PodSample') {pod('SDWebImage', '~> 4.4.2')
}
复制代码

也可以使用我们常见的形式调用:

target('PodSample') dopod('SDWebImage', '~> 4.4.2')
end
复制代码

eval

最后一个需要介绍的特性就是 eval 了,早在几十年前的 Lisp 语言就有了 eval 这个方法,这个方法会将字符串当做代码来执行,也就是说 eval 模糊了代码与数据之间的边界,iOS开发过程中也会使用eval执行js代码。

 eval "1 + 2 * 3" => 7
复制代码

我们在执行Podfile文件的相关操作时,比如常用的installupdate,都会用eval在上下文中执行Podfile文件中的“代码”。

Podfile&Podfile.lock的解析

Podfile

在介绍完ruby的语言特性之后,大家对于理解Podfile文件应该没有什么问题了。

CocoaPods内部定义了一些配置方法,把方法参数转化为内部Hash变量的属性。

def source(url)$hash_value['source'] = url
enddef target(target)$hash_value['target'] = target
enddef pod(pod)pods = $hash_value['pods']pods = [] if pods == nilpods << pod$hash_value['pods'] = pods
end
复制代码

下面说一下CocoaPods在解析完Podfile的结果是怎么样的。

执行eval(Podfile.content)的同时会生成一个Podfile类的对象,这个类有重要的两个属性:

  1. 一个是Hash类型的internal_Hash,保存全局的一些配置,比如sourceworkspace
  2. 另一个是TargetDefinition类的root_target_definitions对象,TargetDefinition类之间有parent和children之间的联系,通过root_target_definitions对象可以遍历到Podfile文件所有声明的target对象,target对象会保存传入该target方法中block的所有参数。

Podfile.lock

Podfile.lock文件是用数据描述语言YAML编写的,YAML(YAML Ain’t Markup)是一种简洁的非标记语言,以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读,其可以与json互转,CocoaPods内部是把Podfile.lock文件解析成Hash类型,从而进行参数数据查询和与Podfile文件中的参数进行对比。

看源码发现Cocoapods不仅支持ruby形式的podfile文件,也支持YAML形式的podfile文件配置方式。

PODS:
  - AFNetworking (3.1.0):
    - AFNetworking/NSURLSession (= 3.1.0)
    - AFNetworking/Reachability (= 3.1.0)DEPENDENCIES:
  - AFNetworking (= 3.1.0)SPEC REPOS:
  https://github.com/cocoapods/specs.git:
    - AFNetworkingSPEC CHECKSUMS:
  AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67PODFILE CHECKSUM: a06ca71d7960a7bf4f294d3ad147e0e67528a467COCOAPODS: 1.5.3
复制代码
{"PODS":[{"AFNetworking (3.1.0)":["AFNetworking/NSURLSession (= 3.1.0)","AFNetworking/Reachability (= 3.1.0)"]}],"DEPENDENCIES":["AFNetworking (= 3.1.0)"],"SPEC REPOS":{"https://github.com/cocoapods/specs.git":["AFNetworking"]},"SPEC CHECKSUMS":{"AFNetworking":"5e0e199f73d8626b11e79750991f5d173d1f8b67"},"PODFILE CHECKSUM":"a06ca71d7960a7bf4f294d3ad147e0e67528a467","COCOAPODS":"1.5.3"
}
复制代码

总的来说ruby形式podfile的解析就是调用方法,把各类参数配置转化为Hash数据,如果是YAML形式的数据转化就更便捷了,本身就是key-value形式的数据。

参考链接:
CocoaPods 都做了什么?
pod install和pod update背后那点事

CocoaPods原理(一)相关推荐

  1. CocoaPods 原理分享及遇到的问题改进

    cocoapods 原理分享及问题阐述 cocoapods 管理私有工程,需要两个git 仓库, repo 仓库,保存podspec 文件,告诉我们项目从哪来, 项目 仓库,保存工程文件,告诉我们引用 ...

  2. iOS SDK开发系列一之Cocoapods原理,Xcode的配置,动态库和静态库介绍

    前言 三个月没写东西了,是时候总结点东西了.SDK这个东西开发其实和项目开发类似,但是项目中你不需要关注一些配置和打包的参数,或者你压根不需要关注Framework和.a到底是怎么链接配置的,因为Co ...

  3. CocoaPods原理

    CocoaPods是IOS项目上负责管理依赖的工具,即对第三方库的依赖. CocoaPods 的原理是将所有的依赖库都放到另一个名为Pods的项目中, 然而让主项目依赖Pods项目, 这样,源码管理工 ...

  4. CocoaPods的使用和安装

    更新时间:2020.6.28 安装方式有两种,第一种使用普通的终端命令行去安装,第二种使用工具Homebrew去安装,homebrew是一个安装包工具,可以安装node.git.Cocoapods等工 ...

  5. iOS CocoaPods 详解

    每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm.随着 iOS 开发者的增多,业界也出现了为 iOS 程序提供依赖管理的工具,它的名字叫 ...

  6. iOS-Xcode7安装CocoaPods

    一.CocoaPods介绍以及好处 CocoaPods 是开发 OS X 和 iOS 应用程序的一个第三方库的依赖管理工具,该项目源码在Github上管理.通过 CocoaPods,可以很方便的查找到 ...

  7. iOS App 的编译过程

    在 iOS 开发的过程中,Xcode 为我们提供了非常完善的编译能力,正常情况下,我们只需要 Command + R 就可以将应用运行到设备上,即使打包也是一个相对愉快的过程. 但正如我们写代码无法避 ...

  8. iOS之深入解析Cocoapods的工作原理与源码分析

    一.Cocoapods 简介 ① Cocoapods 是什么? Cocoapods 是一个运行在 Ruby 环境下,负责管理 iOS 项目中第三方开源库的工具,它可以解决库与库之间的依赖关系,同时通过 ...

  9. automake生成静态库文件_基于CocoaPods的组件化原理及私有库实践

    轮子为什么会存在 智人能在残酷的进化大战中存活下来,原因之一就是智人懂得将知识沉淀成外物,辅助彼此之间的合作,从而使得整个群体产生了规模效应,即1+1>2的效果. 从一个角度上说,石器时代是基于 ...

最新文章

  1. 引人遐想,用 Python 获取你想要的 “某个人” 摄像头照片
  2. Ueditor的两种定制方式
  3. 天上掉馅饼,我被砸中了!
  4. C语言再学习 -- 声明与定义
  5. 第四范式完成C+轮融资,估值约20亿美元
  6. 从源代码的角度分析--在BaseAdapter调用notifyDataSetChanged()之后发生了什么
  7. 右键删除选中的行总提示rowIndex
  8. JDBC 创建连接对象的三种方式 、 properties文件的建立、编辑和信息获取
  9. 用循环求出1-100之间的偶数和
  10. Ubuntu18.04.3虚拟机安装步骤图文教程
  11. 最详细的git( Github和Gitee )入门使用(上传与克隆)
  12. 致敬创新者 | 看中国小企业掌握哪些核心技术?
  13. hdu2046-饭卡
  14. VBA调用sqlserver带参数的存储过程
  15. qt 合并单元格 tablewidget 合并单元格
  16. 在韩国5G商用神话中,我们不能学到什么?
  17. python ffmpeg mp3文件转为wav文件
  18. 【资讯】时间的朋友2017跨年演讲全回顾
  19. Java定义获取所有偶数元素集合的方法
  20. 使用三丰云服务器建立moon节点搭建zerotier

热门文章

  1. Android提示框与通知的使用
  2. 【C++】algorithm具体操作记录
  3. spl_autoload_register与autoload区别
  4. 明白了这十个故事,你也就参悟了人生
  5. 浅析.Net下的AppDomain编程
  6. C++中插件使用举例
  7. 图像相似度计算之直方图方法OpenCV实现
  8. 【OpenCV】cv::VideoCapture 多线程测试
  9. 电子合同的履行_什么是电子合同履行?怎么履行电子合同?
  10. java 操作mysql数据库得到错误码_[数据库/Java]数据库开发过程中产生的MySQL错误代码及其解决方案...