作为一个iOS开发者,在工作的每一天,我们都与 Xcode project打交道,如果使用Cocoapods管理第三方库,那还少不了xcworkspace,今天,我们从内容格式的角度来了解下这两个文件
pbxproj 和 xcworkspace
xcode project
在苹果的文档中是这样描述工程文件的:
Xcode project 里面包含了软件编译所需的所有文件,资源和一些编译设置信息,包括这些文件之前的依赖联系。
它包含一个或者多个targets,target用来描述如果去编译。工程文件定义了编译每一个target的编译方式。
在***.xcodeproj文件中,显示包内容,我们就可以找到project.pbxproj文件,打开文件
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
};
rootObject = AD5BA36126F07D6B00BBB9AF /* Project object */;
}
archiveVersion: 这个值一直为1,并且classes字段值一直为空。objectVersion: 这个代表了当前Xcode的版本。rootObject: 是最重要的一个key,pbxproj是一个树型结构,rootObject是其根节点,它的值是一个标识符,指向一个PXBProject对象,也就是我们常用的Xcode对象。
xcworkspace
workspace是一个Xcode文档,他对project和其他文档进行分组,以便可以一起处理。一个workspace包含一个或多个Xcode工程,以及想要包含处理的其他文件。
workspace的结构如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:HQPDemo.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
该workspce包含了两个xcodeproj对象,location存放的是文件的相对路径。
Xcode Objects
Xcode Object identifiers
所有的Objects都有一个唯一的标识符,例如rootObject = AD5BA36126F07D6B00BBB9AF,通过这个唯一的标识符在工程文件中,找到相对应的值。
在工程文件中,我们可以找到该对象:
AD5BA36126F07D6B00BBB9AF /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1250;
LastUpgradeCheck = 1250;
TargetAttributes = {
AD5BA36826F07D6B00BBB9AF = {
CreatedOnToolsVersion = 12.5.1;
};
AD5BA37E26F07D7000BBB9AF = {
CreatedOnToolsVersion = 12.5.1;
TestTargetID = AD5BA36826F07D6B00BBB9AF;
};
AD5BA38926F07D7000BBB9AF = {
CreatedOnToolsVersion = 12.5.1;
TestTargetID = AD5BA36826F07D6B00BBB9AF;
};
};
};
buildConfigurationList = AD5BA36426F07D6B00BBB9AF /* Build
configuration list for PBXProject "HQPDemo" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,Base
);
mainGroup = AD5BA36026F07D6B00BBB9AF;
productRefGroup = AD5BA36A26F07D6B00BBB9AF /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
AD5BA36826F07D6B00BBB9AF /* HQPDemo */,
AD5BA37E26F07D7000BBB9AF /* HQPDemoTests */,
AD5BA38926F07D7000BBB9AF /* HQPDemoUITests */,
);
};
PBXProject
rootObject指向一个PBXObject实例。
-
buildConfigurationList指向XCConfigurationList对象,通常一个工程都有Debug和Release这两个配置。 -
mainGroup指向PBXGroup对象,它是一个集合,它包含了工程编译的所有文件。
AD5BA36026F07D6B00BBB9AF = {
isa = PBXGroup;
children = (
AD5BA36B26F07D6B00BBB9AF /* HQPDemo */,
AD5BA38226F07D7000BBB9AF /* HQPDemoTests */,
AD5BA38D26F07D7000BBB9AF /* HQPDemoUITests */,
AD5BA36A26F07D6B00BBB9AF /* Products */,
BB80D1A639BC424ACD0B0514 /* Pods */,
66A61A52D7288E9C33A3B97A /* Frameworks */,
);
sourceTree = "<group>";
};
targets是该工程包含的所有target的合集。每一个taget为PBXNativeTarget对象,
PBXGroup
PBXGroup对象是一个或多个对象的集合。
PBXFileReference: 是一个包含文件引用的集合,可以是源文件、framework、二进制文件、或者其他工程文件。PBXReferenceProxy:一个包含工程外引用的集合,通常在需要引用一个依赖工程的时候用到。PBXGroup: 一个group可以包含其他group,在UI中展示的形式为一个子文件夹。
PBXFilereference
所有的实物都被定义为PBXFilereference对象。
2B64ADE26330B6773355D9FA /* Pods_HQPDemoTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HQPDemoTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3D84B89EBA3CA1C9B9C8C4B4 /* Pods-HQPDemo-HQPDemoUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HQPDemo-HQPDemoUITests.debug.xcconfig"; path = "Target Support Files/Pods-HQPDemo-HQPDemoUITests/Pods-HQPDemo-HQPDemoUITests.debug.xcconfig"; sourceTree = "<group>"; };
-
sourceTree是该实物对象的路径。<group>代表在PBXFilereference对象所属的group下。当是project自身时,sourceTree的值就是BUILT_PRODUCTS_DIR。 -
lastKnownFileType表示源码文件的类型,sourcecode.swift表示该文件为swift文件
xcconfig: text.xcconfig
swift : sourcecode.swift
xcassets: folder.assetcatalog
plist : text.plist.xml
explicitFileType表示要构建的对象,例如
AD5BA36926F07D6B00BBB9AF /* HQPDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HQPDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
在构建的时候需要将其构建为app文件。
PBXNativeTarget
PBXNativeTarget对象用来描述如何来构建target
AD5BA36826F07D6B00BBB9AF /* HQPDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = AD5BA39326F07D7000BBB9AF /* Build
configuration list for PBXNativeTarget "HQPDemo" */;
buildPhases = (
F854D8F9C862E74399020DEA /* [CP] Check Pods Manifest.lock */,
AD5BA36526F07D6B00BBB9AF /* Sources */,
AD5BA36626F07D6B00BBB9AF /* Frameworks */,
AD5BA36726F07D6B00BBB9AF /* Resources */,
AB27C9DC0F1571380994A639 /* [CP] Embed Pods Frameworks */,
);
buildRules = ();
dependencies = ();
name = HQPDemo;
productName = HQPDemo;
productReference = AD5BA36926F07D6B00BBB9AF /* HQPDemo.app */;
productType = "com.apple.product-type.application";
};
buildPhase在Xcode中的展现形式如下图所示,是和buildPhases的步骤一一对应的。
productReference的值为
AD5BA36926F07D6B00BBB9AF /* HQPDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HQPDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
说明其为一个可执行的二进制文件。
PBXNativeTarget对象有其自己的buildConfigurationList(环境变量设置)
PBXBuildPhase
PBXBuildPhase(构建步骤)有7个不同的类型:
PBXAppleScriptBuildPhase: 运行苹果脚本。PBXCopyFilesBuildPhase: 拷贝文件。PBXFrameworksBuildPhase: 链接framework文件。PBXHeadersBuildPhase: 编译的头文件。PBXResourcesBuildPhase: 资源文件。PBXShellScriptBuildPhase: 执行sh shell脚本。PBXSourcesBuildPhase: 编译的源文件。 对于我们来言,我们的注意点应该放在PBXSourcesBuildPhase对象上
PBXSourcesBuildPhase
AD5BA36526F07D6B00BBB9AF /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AD5BA37126F07D6B00BBB9AF /* ViewController.swift in Sources */,
AD5BA36D26F07D6B00BBB9AF /* AppDelegate.swift in Sources */,
AD5BA36F26F07D6B00BBB9AF /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
它是一个需要编译源文件(PBXBuildFile)集合的入口,在这里,所有编译3个源文件,在Xcode中的展现形式如下图所示。
PBXBuildFile
PBXBuildFile是xcode编译文件的核心。PBXBuildFile和PBXFileReference相关联。
AD5BA36F26F07D6B00BBB9AF /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD5BA36E26F07D6B00BBB9AF /* SceneDelegate.swift */; };
AD5BA36E26F07D6B00BBB9AF /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
lastKnownFileType来指明源文件的类型。文件类型我们在PBXFilereference中做了一次简单总结。
通过以上内容,我们对xcodeproj文件做了一个整体的介绍,希望通过这篇文章能够对xcode工程文件有进一步的认识。在Cocoapods中,通过xcodeprojGem 库来对工程文件进行修改的。通过了解工程结构,我们可以更好的做一些工程自动化的操作。
本文参考文章: