IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

使用CocoaPods进行Xcode的项目依赖管理

装逼程序员 2015-01-04 23:37:16 累计浏览 2,030 次
本机暂存

什么是CocoaPods

   CocoaPods是Xcode上的一个依赖管理工具

   CocoaPods有点像Java领域的Maven.当然它并不是作为构建工具存在的,构建还是由Xcode来负责,CocoaPods主要负责了各个类库的依赖管理,而且强大的是它还有自己的资源库..而且对比Maven它的依赖管理更加灵活,可以直接依赖本地的库或者自定义依赖一个git上的库.这点和Gradle很像

安装CocoaPods

   安装CocoaPods需要有Ruby(Mac系统默认自带了1.8.7版本的Ruby已经够用了) 还需要安装Xcode的command line tools

   然后只需要执行sudo gem install cocoapods 就会给你安装了

   当cocoapods有版本更新时,在执行pods时就会有提醒,这个时候执行sudo gem update cocoapods就能更新CocoaPods了

   由于国内网速慢建议执行上面两台命令的时候加上--verbose参数,可以看到执行到哪一步了,不然基本就是黑屏等很久

使用CocoaPods

   刚装完CocoaPods,就先执行一下’pod setup’吧,它会去拉资源库上的podspec文件到你本地的库上(git库),默认在~/.cocoapods/master

   好了这个时候,你就可以编写Podfile了 Podfile就类似于Maven的pom.xml文件来描述依赖关系

   具体的怎么写可以参考 http://docs.cocoapods.org/podfile.html

   给个具体的样例

platform :ios, '5.0'
inhibit_all_warnings!

pod 'SDWebImage','~>3.2'
pod 'JASidePanels','~>1.3.1'
pod 'BlocksKit','~>1.8'
pod 'TTTAttributedLabel','~>1.7'
pod 'MBProgressHUD','~>0.6'
pod 'RTLabel','~>1.0'
pod 'KNSemiModalViewController','~>0.3'
pod 'SFHFKeychainUtils','~>0.0.1'
pod 'MBMvc',:git => 'git@github.com:alibaba/MBMvc.git'
pod 'RSA',:path => 'libs/Sources/RSA'

   可以看到依赖的库不单单可以依赖官方库,还可以直接依赖某个git上的库(git=>标示)或者本地的库(path=>标示) 不过自己依赖的库需要自己写podspec文件,这个下节会详述

   如上的Podfile有一个比较坑爹的事情就是 你这样写的话,只有对项目中的第一个target的起效,如果你的项目中有多个target的话怎么把依赖关系直接应用到每个target上,如下在

target :XXX_91 do
    pod 'Resources',:path => 'Resources'
end

target :XXX_Weiphone do
    pod 'Resources',:path => 'Resources'
end

target :XXX_Release do
    pod 'Resources',:path => 'Resources'
end

target :XXX_PreRelease do
    pod 'Resources',:path => 'Resources'
end

   为每个target都加上一个pod依赖,那么这个target会被Pod整体的加上依赖和配置,因为依赖是会被继承的,除非特别指定:exclusive => true

   详情见 http://docs.cocoapods.org/podfile.html#target

   当你写好了Podfile,就可以直接执行pod install,这个时候pod就是为您建立起一个Pods项目,并且简历好一个workspace来包含Pods项目和你自己的项目,并在你的项目中直接依赖Pods项目产出的lib包

   如果以后Podfile文件有变动的话,需要更新项目配置就不是执行pod install了 而是执行’pod update’,他会更新整个依赖和Pods项目..具体的依赖关系 可以直接cat Podfile.lock 来查看

怎么编写自己的PodSpec

   PodSpec是对一个Pod项目的描述,pod可以根据PodSpec文件来指导需要拉那些文件下来编译以及设置编译的参数

   详细的信息可以看http://docs.cocoapods.org/specification.html

Pod::Spec.new do |s|
  s.name         = "MBMvc"
  s.version      = "1.0.0"
  s.summary      = "MBMvc is a Message Based MVC framework."
  s.homepage     = "https://github.com/alibaba/MBMvc"

  s.license      = { :type => 'GPL2' , :text => <<-LICENSE
             (C) 2007-2013 Alibaba Group Holding Limited
             This program is free software; you can redistribute it and/or modify
             it under the terms of the GNU General Public License version 2 as
             published by the Free Software Foundation.
 LICENSE
                    }

  s.author       = { "文通" => "wentong@taobao.com" }
  s.source       = { :git => "https://github.com/alibaba/MBMvc.git", :tag => "1.0.0" }


  s.platform     = :ios, '6.1'

  s.ios.deployment_target = '4.3'

  s.source_files = 'MBMvc/**/*.{h,m}'

  s.public_header_files = 'MBMvc/**/*.h'

  s.requires_arc = true

  s.prefix_header_contents = <<-EOS

#ifdef DEBUG
#define TBMB_DEBUG
#endif

EOS

end

   如上可以看到一个很简单的描述文件..他执行了需要编译的源文件和头文件 以及是否支持ARC(这个很帅,不需要再自己去设置-fno-obj-arc了)..

   但是很多时候我们依赖的不是源码而是framework甚至带有Resource,这里给出一个支持直接依赖framework和Resource的例子:

Pod::Spec.new do |s|
  s.name         = "Huoyan"
  s.version      = "1.0.0"
  s.summary      = "Huoyan"

  s.source_files = '**/*.h'
  s.preserve_paths = 'huoyan.framework','TBScanLib.framework'
  s.requires_arc = true
  s.frameworks = 'huoyan','TBScanLib'
  s.resource = "huoyan.bundle"
  s.xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '"$(SRCROOT)/libs/Frameworks/Huoyan"' } 

end

   通过preserve_paths 留下framework文件,然后通过xcconfig来设置framework扫描路径来依赖framework

   而资源文件的拷贝直接用s.resource = "huoyan.bundle"的方式 依赖

模块化

   通过PodSpec的subspec 可以使一个项目能模块化输出功能 ,一个例子:

Pod::Spec.new do |s|
  s.name         = "iOS_Util"
  s.version      = "0.10.0"
  s.summary      = "Some iOS Util"

  s.license      = 'MIT'

  s.author       = { "文通" => "wentong@taobao.com" }


  s.platform     = :ios, '6.1'

  s.ios.deployment_target = '4.3'

  s.subspec 'Common' do |cos|
    cos.source_files = 'iOS_Util/Common/*.{h,m}'
    cos.public_header_files = 'iOS_Util/Common/*.h'
  end

  s.subspec 'Core' do |cs|
    cs.source_files = 'iOS_Util/Core/*.{h,m}'
    cs.public_header_files = 'iOS_Util/Core/*.h'
    cs.dependency 'libextobjc', '0.2.5'
  end

  s.subspec 'Json' do |js|
    js.source_files = 'iOS_Util/Json/*.{h,m}'
    js.public_header_files = 'iOS_Util/Json/*.h'
    js.dependency 'iOS_Util/Core'
  end

  s.subspec 'Bean' do |bs|
    bs.source_files = 'iOS_Util/Bean/*.{h,m}'
    bs.public_header_files = 'iOS_Util/Bean/*.h'
    bs.dependency 'iOS_Util/Core'
  end

  s.subspec 'DB' do |ds|
    ds.source_files = 'iOS_Util/DB/*.{h,m}'
    ds.public_header_files = 'iOS_Util/DB/*.h'
    ds.dependency 'FMDB/standard' ,'~> 2.1'
    ds.dependency 'iOS_Util/Common'
    ds.dependency 'iOS_Util/Core'
  end

  s.subspec 'WebP' do |ws|
    ws.source_files = 'iOS_Util/WebP/*.{h,m}'
    ws.public_header_files = 'iOS_Util/WebP/*.h'
    ws.dependency 'libwebp' ,'~> 0.3.0-rc7'
    ws.frameworks = 'CoreGraphics'
  end

  s.subspec 'Location' do |ls|
    ls.source_files = 'iOS_Util/Location/*.{h,m}'
    ls.public_header_files = 'iOS_Util/Location/*.h'
    ls.dependency 'iOS_Util/Common'
    ls.dependency 'iOS_Util/DB'
    ls.frameworks = 'CoreLocation' ,'MapKit'
    ls.resource = 'iOS_Util/Location/chinaDivision.sqlite'
  end

  s.subspec 'AMR' do |as|
    as.source_files = 'iOS_Util/AMR/**/*.{h,m,mm}'
    as.public_header_files = 'iOS_Util/AMR/**/*.h'
    as.preserve_paths = "iOS_Util/AMR/**"
    as.library   = 'opencore-amrnb','opencore-amrwb'
    as.xcconfig  = { 'LIBRARY_SEARCH_PATHS' => '"$(PODS_ROOT)/iOS_Util/iOS_Util/AMR/lib"' }
  end

  s.subspec 'Cache' do |cas|
    cas.source_files = 'iOS_Util/Cache/*.{h,m,mm}'
    cas.public_header_files = 'iOS_Util/Cache/*.h'
    cas.dependency 'iOS_Util/Common'
  end

  s.subspec 'Preference' do |ps|
    ps.source_files = 'iOS_Util/Preference/*.{h,m,mm}'
    ps.public_header_files = 'iOS_Util/Preference/*.h'
    ps.dependency 'iOS_Util/Json'
  end

  s.requires_arc = true



end

   可以看到通过subspec可以区分出不同的模块,而且模块间也能依赖

   而在其他项目要用到的时候在Podfile里面可以

pod 'iOS_Util/Json',:git => 'git@gitlab.alibaba-inc.com:tbw/ios_util.git'

   这样的方式来直接依赖其中一个模块的代码,而其他模块的代码不会被打包进来

同分类推荐文章

  1. 「置顶」我做了什么 (2026-05-05 12:13:28)
  2. 万字长文推演:手机不再从 App 开始,Agent OS 如何接管任务入口 (2026-04-28 14:57:22)
  3. Android Perfetto 系列 10 - Binder 调度与锁竞争 (2025-11-16 15:33:30)

查看更多 移动开发 文章 →

建议继续学习

  1. 10个必需的iOS开发工具和资源 (累计阅读 5,195)
  2. iOS 开发 UI 搭建心得(二)—— 善用 xib (累计阅读 3,512)
  3. iOS可视化编程 Tips 之“无需代码设置圆角” (累计阅读 3,519)
  4. iPhone中png图片格式处理 (累计阅读 3,481)
  5. 一张图帮你看懂 iPhone 的屏幕分辨率 (累计阅读 3,111)
  6. 如何做Xcode工程的工程化管理 (累计阅读 2,895)
  7. 如何将TTURLRequest和OAuthConsumer搭配使用 (累计阅读 2,737)
  8. Swift ABI 稳定对我们到底意味着什么 (累计阅读 2,245)
  9. 说说 XcodeGhost 这个事 (累计阅读 2,221)
  10. Objective-C Coding Style (累计阅读 2,114)