使用xcodeproj 动态插入第三方代码
# 为什么这么做?
现在有这么一个使用场景,基线能生成项目A,项目B,项目C...如果只有项目A中使用SDK_A,其他项目都不使用,这时候就需要对基线进行差分,只有当我切换到项目A时,才插入SDK_A。
不同于cocoapods的库管理方式,xcodeproj是通过脚本在编译前向项目中插入指定代码文件。
# Xcode中的项目结构
项目中都会有个主target作为根节点,底下有很多group节点,这些group节点管理者三类文件
1. 常规的 .h/.m 文件
2. 资源文件
3. 库文件,分为静态库.a文件、动态库.framework文件、阉割版的动态库embed franework文件
## 如何引入
这里涉及到xcodeproj的具体使用,贴一下官方文档:
#获取项目
$project = Xcodeproj::Project.open($project_path); #获取target,通常取第一个为项目的主target
$target = $project.targets.first # 获取插件目录的group,如果不存在则创建
$group_One = $project[$plugin_folder] || $project.main_group.find_subpath(File.join($plugin_folder), true); # 在目标目录新建group目录
$group = $group_One.find_subpath($folderName, true)
$SDK_PATH = $group_One.real_path.to_s + "/" + $plugin_folder + "/" + $folderName # 判断SDK_PATH目录下是否存在第三方代码,不存在则退出
if !FileTest::exists?($SDK_PATH)
puts "SDK file not found in #{$SDK_PATH}"
exit 1
end
* project_path 是项目的路径
* plugin_folder 是插入的目录名称,它是创建在项目目录底下的
* folder_name 是插入的第三方库的文件夹的名称,它是创建在plugin_folder目录底下的
注意,这里的第三库的代码文件其实和项目的代码是放在一块的,我们要做的只是将它和项目关联起来,也就是在XXX.xcodeproj文件中添加其引用。具体的关联就是建立target底下的group组后 添加上述3类文件的引用。
1. .h/.m 文件添加引用
if filePath.to_s.end_with?(".h") then
fileReference = aGroup.new_reference(filePath);
# aTarget.source_build_phase.add_file_reference(fileReference, true)
elsif filePath.to_s.end_with?(".m", ".mm", ".cpp") then
fileReference = aGroup.new_reference(filePath);
aTarget.source_build_phase.add_file_reference(fileReference, true)
需要注意的是.h文件只需要 在group底下new一个reference,.m文件需要将group底下的reference添加进source_build_phase
2. 资源文件添加引用
if filePath.to_s.end_with?(".bundle",".plist" ,".xml",".png",".xib",".js",".html",".css",".strings")
fileReference = aGroup.new_reference(filePath);
aTarget.resources_build_phase.add_file_reference(fileReference, true)
根据资源文件创建其group的reference后,需要将其添加进resources_build_phase
3. 库文件的引用
if filePath.to_s.end_with?(".framework" ,".a")
fileReference = aGroup.new_reference(filePath);
build_phase = aTarget.frameworks_build_phase;
build_phase.add_file_reference(fileReference);
if $isEmbed == true
#添加动态库
$embed_framework.add_file_reference(fileReference)
#勾上code sign on copy选项(默认是没勾上的)
$embed_framework.files.each do |file|
# puts "entry filePath : #{filePath} fileRef path : #{file.file_ref.path}"
if filePath.end_with?(file.file_ref.path) then
if file.settings.nil? then
# puts "setting is nil"
file.settings = Hash.new
end
file.settings["ATTRIBUTES"] = ["CodeSignOnCopy", "RemoveHeadersOnCopy"]
end
end
end
库文件需将 reference 添加进frameworks_build_phase,如果是embed framework还需将其添加进embed_frameworks_build_phase,其在xcodeproj中的具体类型是PBXCopyFilesBuildPhase
## 如何清除
因为SDK_A仅仅是项目A使用,如果从项目A切换到项目B,此时就得从XXX.xcodeproj文件中清除关于SDK_A的所有引用,其实是添加引用的一个逆向工程。
上文中我们说到 将SDK_A插入{$PROJECT_PATH}/plugin_folder,所以只需遍历这个group,清除其中所有的reference即可。
def removeBuildPhaseFilesRecursively(aTarget, aGroup)
aGroup.files.each do |file|
if file.real_path.to_s.end_with?(".m", ".mm", ".cpp") then
aTarget.source_build_phase.remove_file_reference(file)
elsif file.real_path.to_s.end_with?(".bundle",".plist" ,".xml",".png",".xib",".js",".html",".css",".strings") then
aTarget.resources_build_phase.remove_file_reference(file)
elsif file.real_path.to_s.end_with?(".framework" ,".a")
aTarget.frameworks_build_phase.remove_file_reference(file)
# remove embed ref
if $isEmbed && !$embed_framework.nil?
$embed_framework.remove_file_reference(file)
end
end # extra r+emove file ref
file.remove_from_project
end aGroup.groups.each do |group|
# puts "group path : #{group.path}"
if group.path == "embed"
$isEmbed = true
end
removeBuildPhaseFilesRecursively(aTarget, group)
$isEmbed = false
end
end
* .m 文件的引用由source_build_phase移除
* 资源文件的引用由resources_build_phase移除
* 库文件的引用由frameworks_build_phase移除,其中embed的framework还需由embed_framework_build_phase额外移除一下
# 后记
xcodeproj 其实不光只是添加引用,xcode中的build_settings的所有选项几乎都可以通过xcodeproj的脚本控制,这里先按下不表。
最后附一下 github的传送门地址:https://github.com/xuanyuelin/ManuallyInsertCodes
使用xcodeproj 动态插入第三方代码的更多相关文章
- js动态插入标签代码(insertAdjacentHTML)
做网页时通过ajax请求获取到数据后,有的需要把数据拼接到带有各种标签的字符串中,拼接完字符串就需要把字符串动态添加到网页上的某个位置,举个
- 动态插入的html代码,点击节点无效以及获取节点下标的方法
动态插入的html,需要使用delegate或者on事件来监听,方式如下. 如果需要获取节点对应的下标,$(this).index()是无法获取的,需要以$(selectot).index(this) ...
- (转载)JAVA动态编译--字节代码的操纵
在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...
- XML 动态 插入 父类标示 子类标示
由于第一次写博客,写的不好的地方,还请各位大神多多指点, 讲解一下:xml动态插入数据并保存,写这个时候费了我不少劲,最后终于皇天不负有心人让我搞出来了,特意分享给大家,写的不完美的地方还请大家多多指 ...
- JavaScript 动态插入 CSS
写组件时有时想把一些组件特性相关的 CSS 样式封装在 JS 里,这样更内聚,改起来方便.JS 动态插入 CSS 两个步骤就可以 创建一个 style 对象 使用 stylesheet 的 inser ...
- FMDB处理动态插入语句
昨天做一个需求,参数的数量不确定,所以无法使用这个API: - (BOOL)executeUpdate:(NSString*)sql, ... 但是用 - (BOOL)executeUpdate:(N ...
- jquery动态插入行
这是一个利用jquery动态插入输入内容的代码. html代码: <div title="分表2" class="ui-edit" style=" ...
- jquery动态插入行,不用拼写html,简洁版
这个一个利用jquery实现动态插入输入行效果小功能,不用在javascript里拼写html字符串,更简洁.高效. html代码: <div class="fitem"&g ...
- iOS_动态插入或删除行
终于效果图: 分MVC三层设计;自己定义的Cell有两种;一种是MainCell,由ModelArr提供数据源;还有一种是插入的cell,由代码创建,而且由另外一个数组供状态数据 数据源部分: wat ...
随机推荐
- [论文阅读笔记] Community aware random walk for network embedding
[论文阅读笔记] Community aware random walk for network embedding 本文结构 解决问题 主要贡献 算法原理 参考文献 (1) 解决问题 先前许多算法都 ...
- Scrum Master 生存指南
近年来,出现了一批新兴且广受关注的岗位,以 Scrum Master 为典型代表.2018年,Scrum Master 的平均工资为98239美元.领英更是将其列为2019年最有前途的工作之一.但对于 ...
- Step By Step(Lua数据持久化)
Step By Step(Lua数据持久化) 1. 数据文件: 我们可以利用Lua中table的构造式来定义一种文件格式,即文件中的数据是table构造并初始化的代码,这种方式对于Lua程序而言 ...
- Docker学习(12) Dockerfile构建过程
Dockerfile的构建过程 以上为构建缓存
- Manjaro Linux安装singularity-container
技术背景 容器化技术在各种生产领域已经得到了广泛的应用,这得益于容器的轻量化(相比于虚拟机而言),安全性(隔离弱于虚拟机,但是权限控制得当的情况下也可以认为是安全隔离的)以及系统级虚拟化带来的高可用性 ...
- CMOS图像传感器理解
CMOS图像传感器理解 水流方向从左边流向右边,上面有一个开关,拧下去的时候水流停止,拧上去的时候水流打开.左边是水流的源头我们给它起个名字,叫做源端(就是源头的意思嘛),右边是水流出去的地方,也就是 ...
- Paddle概述
Paddle概述 本文结合深度学习理论与实践,使用百度飞桨平台实现自然语言处理.计算机视觉及个性化推荐等领域的经典应用. 实践部分使用飞桨深度学习开源框架,适配最新的2.0版本,默认使用动态图编程范式 ...
- PyTorch 数据并行处理
PyTorch 数据并行处理 可选择:数据并行处理(文末有完整代码下载) 本文将学习如何用 DataParallel 来使用多 GPU. 通过 PyTorch 使用多个 GPU 非常简单.可以将模型放 ...
- NVIDIA TensorRT:可编程推理加速器
NVIDIA TensorRT:可编程推理加速器 一.概述 NVIDIA TensorRT是一个用于高性能深度学习推理的SDK.它包括一个深度学习推理优化器和运行时间,为深度学习推理应用程序提供低延迟 ...
- 图分析Rapids cuGraph
图分析Rapids cuGraph 英伟达(Nvidia)建立的新的开源库可能是推进分析和使图形数据库更快的秘密要素. 在Nvidia GPU上进行并行处理. Nvidia很久以前就不再只是" ...