背景

随着业务的扩展,私有CocoaPod库和第三方CocoaPod库越来越多,项目中的文件也越来越多。每次pod install/update的时候,重新编译的过程需要等待很长时间,这就间接地向我们提出了加快编译速度的需求。
二进制化指的是通过编译把模块的源码转换成静态库或动态库,以提高该组件在项目中的编译速度。

具体实现

  • 创建一个Xcode项目,选择Framework或者Static Library模版
  • 添加Cocoapods支持,用于调试的时候源码切换
  • 添加Carthage支持,用于二进制化
  • 添加Podspec,用于管理相关的二进制库

Cocoapods

我们通过Cocoapods把每一个组件都拆成独立的pod库。

创建组件项目



pod lib create MyLib



编辑podspec file



Pod::Spec.new do |s|
  s.name             = 'MyLib'
  s.version          = '0.1.0'
  s.summary          = 'A short description of MyLib.'
  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC
  s.homepage         = 'https://github.com/wkcdeie/MyLib'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'wkcdeie' => 'wkcdeie@gmail.com' }
  s.source           = { :git => 'https://github.com/wkcdeie/MyLib.git', :tag => s.version.to_s }
  s.ios.deployment_target = '8.0'
  s.source_files = 'MyLib/Classes/**/*'
end



验证



pod lib lint MyLib.podspec



推送代码到远程仓库



git tag '0.0.1'
git push --tags



Carthage

Carthage是一个简单的,去集中化的依赖管理工具。

安装



brew install carthage



使用



mkdir my-vendors
cd ~/my-vendors
touch Cartfile



编辑Cartfile



# git "https://github.com/SVProgressHUD/SVProgressHUD.git" ~> 1.0
# 或者
github "SVProgressHUD/SVProgressHUD" ~> 1.0



依赖源

  • github:告诉Carthage去Github下载文件,格式为Username/ProjectName。
  • git:资料库的地址,可以是远程的URL地址。使用git://, http://, ssh://或者是本地资料库地址。

版本号

  • == 1.0表示使用1.0版本
  • >= 1.0表示使用1.0版本或更高的版本
  • ~> 1.0表示使用1.0版本以上但低于2.0版本
  • branchtagcommit表示使用特定的分支、标签、提交信息
    运行
    1
  • --platform iOS表示只构建iOS平台
  • --no-use-binaries表示不要使用网上已经构建好的库,直接从本地源码重新构建

当执行完上面这个命令后,会在当前目录下生成Carthage/CheckoutsCarthage/Build。其中Checkouts存放下载的源码,Build存放构建过的二进制文件。如图:




iOS模块动态上下架 ios动态化实现方案_iOS模块动态上下架


使用注意

由于目前Swift还没有Module Stability,最好是不要把Carthage/Build添加到代码库中。当每次拉取依赖后,使用当前电脑的Swift环境重新执行一次carthage build操作。

创建二进制库Pod项目


carthage update --platform iOS --no-use-binaries


编辑podspec file


Pod::Spec.new do |s|
  s.name             = 'MyVendors'
  s.version          = '0.1.0'
  s.summary          = 'A short description of MyVendors.'
  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC
  s.homepage         = 'https://github.com/wkcdeie/MyVendors'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'wkcdeie' => 'wkcdeie@gmail.com' }
  s.source           = { :git => 'https://github.com/wkcdeie/MyVendors.git', :tag => s.version.to_s }
  s.ios.deployment_target = '8.0'

  s.subspec "SVProgressHUD" do |sp|
    sp.framework = 'QuartzCore'
    if ENV['IS_SOURCE']
      puts 'Notice: SVProgressHUD is source now'
      sp.dependency 'SVProgressHUD', '~> 2.2.5'
    else
      puts 'Notice: SVProgressHUD is binary now'
      sp.vendored_frameworks = 'Carthage/Build/iOS/SVProgressHUD.framework'
    end
  end
end


然在你的主工程Podfile中加入:


pod 'MyVendors', :subspecs => ['SVProgressHUD'], :path => '../my-vendors'


执行pod install,至此整个操作就已经完成了。如果需要源码调试,使用IS_SOURCE=1 pod install

后记

  • 如果项目使用的是Swift且Xcode创建的是Framework工程,那么你的主项目的Podfile里面需要加上use_frameworks标记。
  • 如果项目中动态库的数量很多,这会影响项目启动时间。根据Apple的推荐,项目中不应该超过6个动态库,系统库除外。解决这个问题的方案是使用静态库。