project.pbxproj 文件被包含于 Xcode 工程文件 *.xcodeproj 之中,存储着 Xcode 工程的各项配置参数。它本质上是一种旧风格的 Property List 文件,历史可追溯到 NeXT 的 OpenStep。其可读性不如 xml 和 json,苹果却一直沿用至今,作为一家以创新闻名的公司可能这里剩下的就是情怀吧。
project.pbxproj 使用 UUID 作为交叉引用的索引,保证每个配置信息对象的唯一性。因为 UUID 根据机器硬件和时间戳生成,避免了多人在同一时间段操作修改工程文件带来的问题。也就是说工程中每项配置对象都有个唯一的 UUID,然后其他配置对象想引用某个配置对象直接使用它的 UUID 即可。这就跟我们编程时使用指针指向某个对象的地址一样,其他对象的属性想引用它,只需要给属性传个指针地址就行了。
可以把整个文件的内容想象成一个字典,字典中的 Key 按照字典序来排列。字典的第一层级总共有 5 个键值对,Key 分别为:archiveVersion
,classes
,objectVersion
,objects
和rootObject
。其中重要的 Key 是 objects
和 rootObject
。
所有的配置对象都放在 objects
对应的 Value 中,包括跟对象(rootObject
)。objects
对应的 Value 也是一个字典,Key 都为 UUID,Value 依然是个字典。可以将 rootObject
的值(是一个 UUID)作为 Key 在objects
对应的字典中找到根对象。这个根对象的 isa
属性为 PBXProject
(isa = PBXProject
)。读懂 project.pbxproj 的最好方式就是顺着rootObject
的各个属性对应的 UUID 在 objects
中找到对应的对象,然后一层层看下去。这样整个文件的配置信息存放方式就慢慢摸清了。
objects
中的键值对被分成了若干个 section,虽然 section 的顺序是 Xcode 私有 API 钦定的,但每个 section 内部的键值对会根据 Key 的字典序排列。
每个对象内部的属性(也是键值对)会把 isa
排在最前面,其余的按照字典序排列。
数组内部的顺序完全按照元素内容的字典序排列。
关于project.pbxproj文件的详细格式介绍: Xcode Project File Format
1. 直接使用MAC提供的property plist文件解析工具
plutil工具: plutil(1) Mac OS X Manual Page
plutil
工具提供了处理 Property list 文件的能力。 比如将 Property list 文件转成 XML 格式:
plutil -convert xml1 -s -r -o project.pbxproj.xml project.pbxproj
-convert
选项可以传入的参数有: xml1, binary1 和 json。
2. Swift语言解析
3. XUPorter开源库
Unity编译iOS工程的自动化配置(XUPorter) XUPorter里会去解析project.pbxproj文件,他是使用C#实现的。
4. 其他一些脚本语言实现的开源库
Xcodeproj CocoaPods 写的 Ruby 解析库,用于修改引入 CocoaPods 的工程文件并保存为 XML 格式。CocoaPods 本身是很强大的,还可以用来操作 Xcode workspaces (.xcworkspace), configuration files (.xcconfig) 和 Xcode Scheme files (.xcscheme).
mod-pbxproj 强大的 Python 解析库,支持一定的修改操作,可输出 OpenStep 格式,但是顺序和注释内容无法完美还原,有些鸡肋。目前没找到有效的Object-C实现的三方库,如果谁有找到的话,可以告知一下
聊聊 Xcode 项目文件中的 project.pbxproj
iOS 开发 xcode中的project.pbxproj--深入剖析