前言
每种语言发展到一个阶段,就会出现相应的依赖管理工具, 或者是中央代码仓库。比如
- Java: maven,Ivy
- Ruby: gems
- Python: pip, easy_install
- Nodejs: npm
随着iOS开发者的增多,业界也出现了为iOS程序提供依赖管理的工具,这个工具叫:CocoaPods。
CocoaPods简介
CocoaPods是一个负责管理iOS项目中第三方开源代码的工具。CocoaPods项目的源码在Github上管理。该项目开始于2011年8月12日,经过一年多的发展,现在已经超过1000次提交,并且持续保持活跃更新。开发iOS项目不可避免地要使用第三方开源库,CocoaPods的出现使得我们可以节省设置和更新第三方开源库的时间。
拿我之前开发的粉笔网iPhone客户端为例,其使用了14个第三方开源库。在没有使用CocoaPods以前,我需要:
- 把这些第三方开源库的相关文件复制到项目中,或者设置成git的submodule,然后这些开源库通常需要依赖系统的一些framework,我需要手工地将这些framework一一增加到项目依赖中,比如ASI网络库就需要增加以下framework: CFNetwork, SystemConfiguration, MobileCoreServices, CoreGraphics and zlib。
- 对于RegexKitLite这个正则表达式库,我还需要设置-licucore的编译参数
- 手工管理这些依赖包的更新。
这些体力活虽然简单,但毫无技术含量并且浪费时间。在使用CocoaPods之后,我只需要将用到的第三方开源库放到一个名为Podfile的文件中,然后执行pod install。CocoaPods就会自动将这些第三方开源库的源码下载下来,并且为我的工程设置好相应的系统依赖和编译参数。
CocoaPods的安装和使用介绍
安装
安装方式异常简单, Mac下都自带ruby
1、以防本机的Ruby环境不够新,可能要更新一下sudo gem update --system
2、更新完Ruby之后安装cocoapods
<1、sudo gem install cocoapods
如果该操作报错:
Building native extensions. This could take a while...
ERROR: Error installing cocoapods:
ERROR: Failed to build gem native extension.
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb
mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/ruby.h
这是因为本机上还未安装command line tools ,对于Mac OS X 10.9 Mavericks系统,已经将command line tools的安装从必须安装xcode改为可选安装xcode,所以对于10.9以下的系统,既可以用打开XCode,Preferences -> Downloads -> Components方式下载 Command Line Tools,也可以在终端执行
sudo xcode-select --install
进行下载安装;10.9的系统,在xode里已经没有了安装command line tools的选项,只能使用命令安装方式。待command line tools下载完成之后再次执行
sudo gem install cocoapods
等待一阵子,安装成功
<2、执行
pod setup
等待一会,执行完毕,至此cocoapods安装完成。
现在pod安装好了,怎么使用呢?
搜索
先试试搜索功能,你需要什么库,可以用pod来搜索,比如要用JSONKit这个库:
pod search是搜索命名,后面写上库名称就行了。
pod search RegexKitLite
搜索出来:
-> RegexKitLite (4.0)
Lightweight Objective-C Regular Expressions using the ICU Library.
pod 'RegexKitLite', '~> 4.0'
- Homepage: http://regexkit.sourceforge.net/RegexKitLite/
- Source: http://svn.code.sf.net/p/regexkit/code/RegexKitLite
- Versions: 4.0 [master repo]
使用
打开终端,然后cd到你的项目文件夹根目录。首先新建一个文本文件Podfile:
touch Podfile
打开Podfile:
open Podfile
编辑Podfile文件,如果需要添加RegexKitLite,编辑Podfile如下:
platform :ios
pod 'RegexKitLite', '~> 4.0'
保存,后续还可以继续给该文件添加第三方依赖库。运行:
pod install
如果运行失败提示
[!] Pod::Executable pull
error: cannot open .git/FETCH_HEAD: Permission denied
这应该是cache的原因,运行:
sudo chown -R username ~/Library/Caches/CocoaPods
sudo chown -R username ~/.cocoapods
执行完之后再重新执行pod install
运行成功之后,会发现目录结构如下:
原来的工程根目录只有Untitled文件夹和Untitled.xcodeproj,后来多出来了Podfile、Podfile.lock、Pods和Untitled.xcworkspace。Untitled.xcworkspace是pod生成的项目管理文件,打开LibDemo.xcworkspace 项目文件,在Xcode里看到是这样的目录结构:
现在,你的所有第三方库(目前只有RegexKitLite)都已经下载完成并且设置好了编译参数和依赖,你只需要记住如下2点即可:
- 使用CocoaPods生成的 .xcworkspace 文件来打开工程,而不是以前的 .xcodeproj 文件。
- 每次更改了Podfile文件,你需要重新执行一次pod update命令。
头文件引用问题
试试看使用JONSKit.h,在AppDelegate.h里引用下。找不到头文件(当你输入#import "JSONKit.h"的时候没有自动完成JSONKit.h),怎么办?还没设置头文件的目录,在项目的Target的里设置一下:
如下图所示,输入${SRCROOT} 后面选上recursive
现在,当重新输入#import "JS"将会看到自动完成#import "JSONKit.h"了。
原理
大概研究了一下CocoaPods的原理,它是将所有的依赖库都放到另一个名为Pods项目中,然后让主项目依赖Pods项目,这样,源码管理工作都从主项目移到了Pods项目中。发现的一些技术细节有:
- Pods项目最终会编译成一个名为libPods.a的文件,主项目只需要依赖这个.a文件即可。
- 对于资源文件,CocoaPods提供了一个名为Pods-resources.sh的bash脚本,该脚本在每次项目编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中。
- CocoaPods通过一个名为Pods.xcconfig的文件来在编译时设置所有的依赖和参数。
删除已经配置的类库或者移除cocoapods
如果发现某个类库不适用,甚至是整个CocoaPods我们都不想再在项目中持有,那么我们要怎么把这些东西从项目中清理出去呢?以下介绍的就是如何删除一个或若干个已经在项目中配置好的第三方类库,以及如何将整个CocoaPods从项目中移除(不是在终端中卸载)
1、删除项目中已经配置的类库
在podfile文件中,删除对不需要的第三库的引用,然后重新执行pod install命令即可。2、在项目中移除CocoaPods
如果你觉得CocoaPods让你的项目出现了问题,不好用甚至是恶心,想将其从项目中彻底移除,方法:
1.删除工程文件夹下的Podfile、Podfile.lock和Pods文件夹。
2.删除xcworkspace文件。
3.打开xcodeproj文件,删除项目中的libpods.a和Pods.xcconfig引用。
4.打开Build Phases选项,删除Check Pods Manifest.lock和Copy Pods Resources:
完成,编译运行,无错通过。
个人感觉,从项目中移除某个类库还算是可以的,但是移除整个CocoaPods就有点麻烦了(也可能是我没有找对方法),希望CocoaPods能作出改进。
另外,如果在编辑工程时不小心删除了某个文件,如Podfile.lock,那么我们就要用上面的方法先移除整个CocoaPods,然后重新建立Podfile和使用pod install命令重装CocoaPods