CocoaPods - 源码篇
来源:互联网 发布:淘宝怎么做好爆款 编辑:程序博客网 时间:2024/06/05 07:17
前言
由于项目里业务线很多,集成了很多第三方
pod
库 和 私有pod
库,整个pod
project
体积非常大。默认的Xcode 编译行为寻找依赖的project进行编译,并且是并行的。我们做了如下改动,加快主工程编译速度:
.去除了主工程对 Pods target的依赖编译
.取消上面两个勾选
.在 Manage Scheme 里勾选了Pods project,以便于可以手动选择 Pods project进行编译
如果对
Pods
库更改了,我们可以手动选择 Pods Scheme
进行编译,然后再编译主工程,这样避免Pods
不必要编译。问题
每次pod install
之后,pods scheme 自动消失了,我们找到 xcschememanagement.plist
文件
cd demo/Pods/Pods.xcodeproj/xcuserdata/Green.xcuserdatad/xcschemescat xcschememanagement.plist# 输出<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>SchemeUserState</key><dict> <key>Pods.xcscheme</key> <dict> <key>isShown</key> <false/> </dict>...
可以看到:Pods.xcscheme
isShown
是 false
,这样导致scheme
中没有Pods
。
Pod Install 剖析
我们来看看 CocoaPods
源码
cd /Library/Ruby/Gems/2.0.0/gems/#这里有很多版本,我们只看0.38.2
当我们执行 pod install
,其实调用到Installer
对象,
#文件位置:`cocoapods-0.38.2/lib/cocoapods/command/project.rb`#初始化 Installer 对象 def run_install_with_update(update) installer = Installer.new(config.sandbox, config.podfile, config.lockfile) installer.update = update #install 方法 installer.install! endend
install!
#文件位置:`cocoapods-0.38.2/lib/cocoapods/installer.rb`文件, #install 方法def install! prepare resolve_dependencies #下载依赖 download_dependencies determine_dependency_product_types verify_no_duplicate_framework_names verify_no_static_framework_transitive_dependencies verify_framework_usage #合成 pods project generate_pods_project integrate_user_project if config.integrate_targets? perform_post_install_actionsend
download_dependencies
#下载pods 资源def download_dependencies UI.section 'Downloading dependencies' do create_file_accessors install_pod_sources run_podfile_pre_install_hooks clean_pod_sources endend
generate_pods_project
#合成 pods projectdef generate_pods_project UI.section 'Generating Pods project' do prepare_pods_project install_file_references install_libraries set_target_dependencies #执行Podfile 的post_install 代码块 run_podfile_post_install_hooks #重新写入pod project,就是在这里修改了所有`pod.xcscheme` 的`isShown`为false write_pod_project share_development_pod_schemes write_lockfiles endend
run post_install
#执行Podfile 的post_install 代码块def run_podfile_post_install_hooks UI.message '- Running post install hooks' do executed = run_podfile_post_install_hook UI.message '- Podfile' if executed endenddef run_podfile_post_install_hook #执行 post_install,这个代码块(block)可以在Podfile里指定 podfile.post_install!(self)rescue => e raise Informative, 'An error occurred while processing the post-install ' \ 'hook of the Podfile.' \ "\n\n#{e.message}\n\n#{e.backtrace * "\n"}"end
post_install
我们经常在 Podfile
里设置 @post_install 代码块:
#文件位置:`cocoapods-core-0.38.2/lib/cocoapods-core/podfile/dsl.rb` 文件 def post_install(&block) @post_install_callback = block end
write_pod_project
# 重新写入pod project,就是在这里修改了所有`pod.xcscheme` 的`isShown`为falsedef write_pod_project UI.message "- Writing Xcode project file to #{UI.path sandbox.project_path}" do pods_project.pods.remove_from_project if pods_project.pods.empty? pods_project.development_pods.remove_from_project if pods_project.development_pods.empty? pods_project.sort(:groups_position => :below) ##重新创建schemes 文件,这里更改了isShown pods_project.recreate_user_schemes(false) pods_project.predictabilize_uuids if config.deterministic_uuids? pods_project.save endend
recreate_user_schemes
#重新创建schemes 文件def recreate_user_schemes(visible = true) schemes_dir = XCScheme.user_data_dir(path) FileUtils.rm_rf(schemes_dir) FileUtils.mkdir_p(schemes_dir) xcschememanagement = {} xcschememanagement['SchemeUserState'] = {} xcschememanagement['SuppressBuildableAutocreation'] = {} targets.each do |target| scheme = XCScheme.new scheme.add_build_target(target) scheme.save_as(path, target.name, false) xcschememanagement['SchemeUserState']["#{target.name}.xcscheme"] = {} #就是在这里修改的。 xcschememanagement['SchemeUserState']["#{target.name}.xcscheme"]['isShown'] = visible end xcschememanagement_path = schemes_dir + 'xcschememanagement.plist' Xcodeproj.write_plist(xcschememanagement, xcschememanagement_path)end
这样我们找到了根本问题,其实还是底层做了限制,每次 pod install 会重新生成 scheme 文件,并且每个 pod target 的 isShown 都是 false 。
Podfile 剖析
Podfile
其实是个 Ruby 类,对应 Cocoapods 的 Podfile class
,我们可以看看Podfile class
源码:
# 文件位置:/Library/Ruby/Gems/2.0.0/gems/cocoapods-core-0.38.2/lib/cocoapods-core/podfile/dsl.rbmodule Pod class Podfile module DSL ...
platform
指定 Pods target
的 platform
# @!group Target configuration# These settings are used to control the CocoaPods generated project.## This starts out simply with stating what `platform` you are working on. `xcodeproj` allows you to state specifically which project to link with.# Specifies the platform for which a static library should be built.## CocoaPods provides a default deployment target if one is not specified.# The current default values are `4.3` for iOS, `10.6` for OS X and `2.0` for watchOS.## If the deployment target requires it (iOS < `4.3`), `armv6` architecture will be added to `ARCHS`.## @param [Symbol] name# the name of platform, can be either `:osx` for OS X, `:ios`# for iOS or `:watchos` for watchOS.## @param [String, Version] target# The optional deployment. If not provided a default value# according to the platform name will be assigned.## @example Specifying the platform## platform :ios, "4.0"# platform :ios## @return [void]def platform(name, target = nil) # Support for deprecated options parameter target = target[:deployment_target] if target.is_a?(Hash) current_target_definition.set_platform(name, target)end
xcodeproj
指定 Pods libraries
可以被哪个 project
链接。
# @Specifies the Xcode project that contains the target that the Pods library should be linked with.# # @param [String] path# the path of the project to link with## @param [Hash{String => symbol}] build_configurations# a hash where the keys are the name of the build# configurations in your Xcode project and the values are# Symbols that specify if the configuration should be based on# the `:debug` or `:release` configuration. If no explicit# mapping is specified for a configuration in your project, it# will default to `:release`.## @example Specifying the user project## # Look for target to link with in an Xcode project called# # `MyProject.xcodeproj`.# xcodeproj 'MyProject'## target :test do# # This Pods library links with a target in another project.# xcodeproj 'TestProject'# end## @example Using custom build configurations## xcodeproj 'TestProject', 'Mac App Store' => :release, 'Test' => :debug### @return [void]def xcodeproj(path, build_configurations = {}) current_target_definition.user_project_path = path current_target_definition.build_configurations = build_configurationsend
inhibit_all_warnings
指定 是否需要忽略警告
# @Inhibits **all** the warnings from the CocoaPods libraries.### This attribute is inherited by child target definitions.## If you would like to inhibit warnings per Pod you can use the following syntax:## pod 'SSZipArchive', :inhibit_warnings => truedef inhibit_all_warnings! current_target_definition.inhibit_all_warnings = trueend
use_frameworks
指定是否使用 framework
# @Use frameworks instead of static libraries for Pods.## ------## This attribute is inherited by child target definitions.# def use_frameworks!(flag = true) current_target_definition.use_frameworks!(flag)end
workspace
指定 合成的 workspace
路径
# @!group Workspace## This group list the options to configure workspace and to set global settings.# Specifies the Xcode workspace that should contain all the projects.## -----## If no explicit Xcode workspace is specified and only **one** project# exists in the same directory as the Podfile, then the name of that project is used as the workspace’s name.## @param [String] path# path of the workspace.## @example Specifying a workspace## workspace 'MyWorkspace'## @return [void]def workspace(path) set_hash_value('workspace', path.to_s)end
source
指定 specs 仓库源
# @!group Sources## The Podfile retrieves specs from a given list of sources (repositories).## Sources are __global__ and they are not stored per target definition.# Specifies the location of specs## -----## Use this method to specify sources. The order of the sources is# relevant. CocoaPods will use the highest version of a Pod of the first# source which includes the Pod (regardless whether other sources have a# higher version).## @param [String] source# The URL of a specs repository.## @example Specifying to first use the Artsy repository and then the# CocoaPods Master Repository## source 'https://github.com/artsy/Specs.git'# source 'https://github.com/CocoaPods/Specs.git'## @return [void]def source(source) hash_sources = get_hash_value('sources') || [] hash_sources << source set_hash_value('sources', hash_sources.uniq)end
post_install
设置 installer 之后的执行的代码块
# This hook allows you to make any last changes to the generated Xcode# project before it is written to disk, or any other tasks you might want to perform.## It receives the [`Pod::Installer`](http://rubydoc.info/gems/cocoapods/Pod/Installer/) as its only argument.## @example Customising the build settings of all targets## post_install do |installer|# installer.pods_project.targets.each do |target|# target.build_configurations.each do |config|# config.build_settings['GCC_ENABLE_OBJC_GC'] = 'supported'# end# end# end## @return [void]#def post_install(&block) @post_install_callback = blockend
Podfile 自定义
我们在Podfile
中增加如下代码:
#设置 Podfile 对象 @post_install_callback 成员self.post_install do |installer|$KDPod_Projectbegin $KDPod_Project=installer.project rescue puts "installer.project is delete" $KDPod_Project=installer.pods_projectendinstaller.use_default_plugins = false$KDPod_Project.targets.each do |target| #设置ORGANIZATIONNAME 、 CLASSPREFIX #target.project.root_object.attributes['ORGANIZATIONNAME']='xxxxx.xxx' #target.project.root_object.attributes['CLASSPREFIX']='xxxx' target.build_configurations.each do |config| #设置target的编译后生成目录 config.build_settings['CONFIGURATION_TEMP_DIR'] = './build' config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO' endend# 延迟执行def kdperformSelector(time) before=Time.now fork do sleep(1) until Time.now-before >= time yield endend#延迟3秒 更改pods scheme visabledkdperformSelector(3){ ##update pod visabled $schemes_dir = Xcodeproj::XCScheme.user_data_dir($KDPod_Project.path) $xcschememanagement_path = $schemes_dir + 'xcschememanagement.plist' $xcschememanagement_content = Xcodeproj.read_plist($xcschememanagement_path) #设置 isShown 属性 $xcschememanagement_content['SchemeUserState']["Pods.xcscheme"]['isShown'] = true FileUtils.rm_rf($xcschememanagement_path) Xcodeproj.write_plist($xcschememanagement_content,$xcschememanagement_path) # puts $xcschememanagement_content # $KDPod_Project.recreate_user_schemes(true) $KDPod_Project.save puts "KDPod_Project.save"}end
我们新for一个进程,在 download_dependencies
之后 延迟了3秒执行更新 pods.xscheme
isShown
属性。
这样就可以显示Pods Scheme了。
这里只是做个例子,重要的是,了解了源码,我们就可以对project
进行其他配置。
0 0
- CocoaPods - 源码篇
- cocoapods安装前奏篇
- CocoaPods之----制作篇
- cocoaPods入门篇
- Cocoapods完整使用篇
- iOS工具篇--CocoaPods
- Cocoapods完整使用篇
- CocoaPods---制作篇(最新版)
- CocoaPods制作篇(2)
- CocoaPods制作篇(1)
- CocoaPods
- CocoaPods
- cocoapods
- CocoaPods
- CocoaPods
- CocoaPods
- cocoaPods
- CocoaPods
- 利用mysql 字符串函数 find_in_set()查询包含字符串
- 解决ios 开发百度地图设置中心点偏移无效的问题
- app接口概述
- 系统锁死
- Uva-11991 - Easy Problem from Rujia Liu?
- CocoaPods - 源码篇
- 我的窝子
- Throwable类
- android 关于软键盘的显示和隐藏监听,解决挡住Editview的问题
- C#多线程异步访问winform中控件
- 排序算法— 冒泡排序的三种实现
- compile 'com.github.userswlwork:pull-to-refresh:1.0.0'
- pg_dump 命令
- transform属性