iOS开发—— CocoaPods
CocoaPods
什么是 CocoaPods
CocoaPods 是基于Ruby编写的一应用级别的依赖管理器,其中涵盖了4.5万个库
https://cocoapods.org/
CocoaPods 组成
-
CocoaPods/CocoaPod
这是是一个面向用户的组件,每当执行一个 pod 命令时,这个组件都将被激活。该组件包括了所有使用 CocoaPods 涉及到的功能,并且还能通过调用所有其它的 gems 来执行任务。 -
CocoaPods/Core
Core 组件提供支持与 CocoaPods 相关文件的处理,文件主要是 Podfile 和 podspecs。 -
Podfile
Podfile 是一个文件,用于定义项目所需要使用的第三方库。 -
Podspec
.podspec 也是一个文件,该文件描述了一个库是怎样被添加到工程中的。它支持的功能有:列出源文件、framework、编译选项和某个库所需要的依赖等。 -
CocoaPods/Xcodeproj
这个 gem 组件负责所有工程文件的整合。它能够对创建并修改 .xcodeproj 和 .xcworkspace 文件。它也可以作为单独的一个 gem 包使用。如果你想要写一个脚本来方便的修改工程文件,那么可以使用这个 gem。
什么是 Ruby
Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,OS X已自带Ruby
Podfile就是通过Ruby脚本解析的
安装 CocoaPods
sudo gem install cocoapods
Gem 是 Ruby 模块 (叫做 Gems) 的包管理器。其包含包信息,以及用于安装的文件。
安装问题
-
国内网络环境无法连接源
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError) Errno::ECONNRESET: Connection reset by peer - SSL_connect
解决方法:替换国内镜像源
gem sources --remove https://rubygems.org/ gem sources -a https://gems.ruby-china.com/
-
Ruby环境版本过低
Unable to resolve dependencies: cocoapods requires cocoapods-core (=0.35.0), claide (~> 0.7.0), xcodeproj (~> 0.20.2), cocoapods-downloader (~> 0.8.0)
解决方法:升级Ruby
sudo gem update --system
输入后出现
ERROR: While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the /usr/bin directory.
因缺少权限需要更换安装目录
sudo gem install cocoapods -n /usr/local/bin
使用 CocoaPods
pod常用命令
#从本地仓库记录搜索
pod search
#初始化、更新仓库信息
pod setup
#更新仓库信息
pod repo update
#为项目创建Podfile
pod init
#根据Podfile安装第三方库
pod install
#根据Podfile更新第三方库
pod update
#根据Podfile安装/更新第三方库,同时不更新仓库信息
pod install --verbose --no-repo-update
pod update --verbose --no-repo-update
查询Pod库也可直接从官网搜索
集成 CocoaPods
-
创建Podfile
终端进入工程目录输入
pod init
即可创建Podfile,若为Swift项目
# use_frameworks!
此句会自动取消注释,表明依赖的库编译生成.frameworkds,而不是.a
若项目中有多个Target则一个Podfile中会生成多段模板# Uncomment the next line to define a global platform for your project # platform :ios, '9.0' target 'TargetName' do # Uncomment the next line if you're using Swift or would like to use dynamic frameworks # use_frameworks! # Pods for TargetName end
消除第三方库警告
platform :ios, '9.0' # 隐藏所有警告 inhibit_all_warnings! target 'TargetName' do # 不要隐藏ReactiveObjC的警告,也可以用此方法只隐藏指定pod警告。 pod 'xxx', '~> 1.0.0', :inhibit_warnings => false end
-
编辑Podfile
pod 'xxx' : 使用仓库记录的最新版本。 pod 'xxx', '1.0' : 使用1.0版本。 pod 'xxx', '~>1.0': 则表示使用的版本范围是 1.0 <= 版本 < 2.0 若为是~>1.0.0, 那么则表示使用的版本范围是 1.0.0 <= 版本 < 1.1.0 pod 'xxx', '>1.0': 使用大于1.0的版本 pod 'xxx', '>=1.0': 使用1.0及以上的版本 pod 'xxx', '<1.0': 使用小于1.0的版本 pod 'xxx', '<=1.0': 使用小于等于1.0的版本 pod 'xxx', :path => '本地代码仓库的路径/xxx.podspec' #使用该方式可以指定本地存在的依赖路径(podspec文件稍后会结介绍到)。 pod 'xxx', :git => 'git仓库地址' #可以通过git仓库地址来加载相关依赖。 pod 'xxx', :git => '本地代码仓库的路径', :tag => '2.2.2' :#后方可以跟:tag参数来指定相关的tag号。当然后边还可以通过:branch => '分支号'来指定依赖于某个分支,通过:commit => 'commit号'来指定那个提交。
若使用多个私有库则可直接在Podfile开始添加source,但必须添加所有需要的source,否则无法找到目标库
CocoaPods 公共库索引地址source 'https://github.com/CocoaPods/Specs.git'
-
安装/更新第三方库
pod install pod update
安装完成后会创建 Pods目录、Podfile.lock文件、和.xcworkspace文件
以后项目都从.xcworkspace打开
Pods目录下下载了第三方库,此目录需要加入.gitignore文件中,避免随git提交/Pods
执行install命令时会检查Podfile.lock文件,若没有则会创建一个
Podfile.lock记录了创建时所安装的依赖库版本,当目录下有Podfile.lock文件时pod会依据Podfile.lock中记录的版本安装,否则就安装Podfile中指定版本或最新版本
update指令则会对未指定版本的库进行更新,并更新Podfile.lock
所以当协作开发时,每当一人更新了依赖库版本,也要提交Podfile.lock,其他人拉取后使用install指令而非update对Pod依赖库进行更新,方便统一版本
当发现无法更新到最新版本库时,执行pod setup
更新本地仓库索引
删除 CocoaPods
- Target->Build Phases,删除 [CP]Check Pods Manifest.lock 和 [CP]Copy Pods Resources
- 删除项目Pod相关引用
- 删除项目目录下Pod文件
制作 CocoaPods 仓库
-
创建框架工程并建立git仓库
-
编辑工程打tag
-
创建私有Repo git仓库
-
创建Pod配置文件
pod spec create XXX
生成.podspec文件,内容如下
name:框架名 version:当前版本,后续更新了新版本,需要修改此处,需要有对应git tag summary:简要描述,在pod search时会显示该信息。 description:详细描述 homepage:页面链接 license:开源协议 author:作者 source:源码git地址 platform:支持最低ios版本 source_files:源文件(可以包含.h和.m) public_header_files:头文件(.h文件) resources:资源文件(配置的文件都会被放到mainBundle中) resource_bundles:资源文件(配置的文件会放到你自己指定的bundle中) frameworks:依赖的系统框架 vendored_frameworks:依赖的非系统框架 libraries:依赖的系统库 vendored_libraries:依赖的非系统的静态库 dependency:依赖的三方库
官方示例
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 macOS.'
spec.source = { :git => 'https://github.com/tonymillion/Reachability.git', :tag => 'v3.1.0' }
spec.source_files = 'Reachability.h,m'
spec.framework = 'SystemConfiguration'
spec.requires_arc = true
end
-
校验配置文件
可用该指令进行本地校验合法性pod lib lint
更多详细配置方式可上官网
在push repo时会自动进行校验,但如果校验有warning或error则不能push,可添加--allow-warnings
忽略警告 -
添加/推送repo
pod repo add [repo名] [repo git地址] pod repo push [repo名] [podspec文件路径]
推送完成使用
pod spec lint
进行网络校验,校验source是否由指定tag
CocoaPod 工作原理
操作过程
- 分析依赖项
- 检查工程target
- 查找Podfile变化
- 解析Podfile
- 比较详情文件
- 下载依赖项
- 安装依赖项
- 创建Pod工程
- 创建工程
- 添加依赖源文件
- 添加framework
- 添加libraries
- 添加资源文件
- 链接头文件
- 安装依赖项target
- 写入pod工程文件
- 写lockfile
- 写manifest
- 整合工程
- 整合target
索引目录结构
~/.cocoapods/repos
.
├── Specs
└── [SPEC_NAME]
└── [VERSION]
└── [SPEC_NAME].podspec
工程结构
Demo
├── Demo
│ ├── Demo
│ ├── Demo.xcodeproj
│ ├── DemoTests
│ └── DemoUITests
├── Demo.xcworkspace
├── PodFile
├── Podfile.lock
└── Pods
├── AFNetworking
│ ├── Source Files
│ └── Support Files
│ ├── AFNetworking-dummy.m
│ ├── AFNetworking-prefix.pch
│ └── AFNetworking.xcconfig
├── Headers
├── Manifest.lock
├── Pods.xcodeproj
└── Target Support Files
├── Pods-Demo-acknowledgements.markdown
├── Pods-Demo-acknowledgements.plist
├── Pods-Demo-dummy.m
├── Pods-Demo-frameworks.sh
├── Pods-Demo-resources.sh
├── Pods-Demo.debug.xcconfig
└── Pods-Demo.release.xcconfig
-
target support files
- .xcconfig 配置环境变量
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SDWebImage" OTHER_LDFLAGS = -framework "ImageIO" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES
CONFIGURATION_BUILD_DIR : buid location GCC_PREPROCESSOR_DEFINITIONS : Clang preprocess OTHER_LDFLAGS : link binary with libraries PRODUCT_BUNDLE_IDENTIFIER : packaging SKIP_INSTALL
- -dummy.m
compile source
辅助纯分类库编译实现编译
- Pod target support files
- -acknowledgement声明文件
- -framewrok.sh 安装framework脚本
- -resource.sh 资源文件拷贝脚本
- check pods manifest.lock
运行时检查安装清单和下载清单是否一致 - copy pods resoources
执行resource拷贝