Xcode 工程分析

Xcode 工程分析

1. 背景

Xcode作为日常开发iOS程序的IDE,支持C、C++、Objective-C、Swift、Ruby等语言进行编写。日常开发入口就是Xcode workspace或者Xcode project。

workspace是一个Xcode文档,它将项目和其他文件、project分组。一个workspace可以包含任意数量的Xcode project,以及资源文件(JSON、脚本、图片、视频等)。workspace除了组织每个project中的文件外,还提供了所包含项目及其目标之间的隐式和显式关系。

project就是一个 Xcode 工程,它是实际管理工程下 targets 、源码、资源文件、framework 等。project 只是一个容器,本身是无法被编译的,所以每个 project 至少应该有一个可编译的 target, target下需要包含可编译的源码。

在日常开发中难免会去在非Xcode的环境下去操作workspace或者project中的依赖关系,所以搞懂workspace、project、源码和资源文件之间的关系就显得特别重要,因为知道怎么来的才知道去如何做。

 

2. 了解workspace全貌

图片

由上图可以简单看出workspace和project的关系:

  • 一个workspace里可以包含多个project

  • 一个project里包含多个target

  • configuration 即Xcode中的Debug/Release 等工程配置

  • scheme 配置target编译参数

  • 每个target即每次编译生成对应产物:app或者framework

     

3. 探寻workspace

新创建一个空的workspace,直接看他的层级树:

图片

可以看到workspace主要包含三个层级:

  • xcworkspacedata,workspace的配置文件,实际上就是一个XML文件。

  • xcshareddata:可共享的配置,包含scheme、script等信息。

  • xcuserdata:当前用的配置,包含本地scheme、script、断点信息等。

 

以报价项目为例详细查看 contents.xcworkspacedata的内容:

图片

FileRef 顾名思义它是标记了每个文件在workspace中的路径关系,这个关系决定的在Xcode中的project的展示层级。

location的关键字包含如下:

  • self:当前文件夹下的同名project

  • group:指定目录下的xcodeproj文件

  • container:workspace当前目录下的不同名的xcodeproj文件

  • absolute:绝对路径下的文件

 

4. 探寻project

由对workspace的探寻我们可以看到,workspace确实只是把project等文件组织起来的一个工作空间,本身并不具备对源码、资源的编译、整合能力,进一步探寻到project文件,我们才能看到源码、资源文件等是怎么被整合起来的。

图片

由上图可看到,xcodeproj里包含了三个大的层级,xcuserdata里包含的常用的scheme和配置文件,还包含了一个xcodeworkspace,这是为了保证Xcode的兼容性,维持Xcode管理文件逻辑的统一。

xcodeproj中包含了开发中所需要的全部文件,管理了当前工程所有的源码、资源文件、配置文件等。重点是pbxproj文件,它与我们正常编译代码密切相关,管理target、文件之间的引用依赖关系、合并代码时候产生的文件冲突就在这里。

 

4.1

深入pbxproj

pbxproj全拼是Project Builder Xcode Project,它其实是我们熟悉的plist文件的一种,但是它不像我们常用的plist文件有着优越的可读性,由于历史原因它才被Xcode一直保存下来。

pbxproj中定义了target、script、文件、configuration等之间的引用关系,我们看到的Xcode项目布局实际上是可视化了pbxproj。

直接看看pbxproj的内部布局吧:

图片

可以看到,最外层包含了这些属性:

  • archiveVersion 当前文件版本

  • classes 占位符

  • objectVersion 当前文件需要的 Xcode最低版本

  • objects 以每个object的uuid为key的字典,存放了object属性

  • rootObject 当前文件的根object (isa = PBXProject)

 

objects里实际上存放的就是每个文件之间的依赖关系,我们称每个文件是一个Xcode object,这个Xcode object不仅仅可以是源码文件,也可以是group、framework、app、target、scheme等。

由上图的rootObject = D9658FA7290BA51D00A72187,我们简单看一下它作为Xcode object的内部结构:

图片

可以看到比较重要的信息是isa、mainGroup、configration、target,其他信息也都包含了Xcode中我们见到的、可以配置的全部信息。

这只是PBXProject中的信息,全部信息可在官网进行查询。下面列出了所有的类型配置:

  • PBXProject:Project 配置,编译工程所需信息

  • PBXNativeTarget:Target 的配置

  • PBXTargetDependency:Target 依赖关系配置

  • PBXContainerItemProxy:部署的元素

  • XCConfigurationList:Xcode中configuration配置

  • XCBuildConfiguration:Xcode 的 Build Settings 配置

  • PBXVariantGroup:storyboard 文件配置

  • PBXBuildFile:各类文件配置

  • PBXFileReference:各类文件引用配置

  • PBXGroup:Xcode中的group

  • PBXSourcesBuildPhase:需要编译的编译源文件

  • PBXFrameworksBuildPhase:需要编译的framework

  • PBXResourcesBuildPhase:除源码外的资源文件

 

他们之间的关系大致如下

图片

了解了各个文件之间的关系,可以为我们以后通过脚本去动态添加、删除、移动文件、修改build settings、scheme等操作打下基础。

 

5. 探寻scheme

scheme不是编译target的必要条件,没有scheme不影响Xcode的编译操作,但是,没有scheme我们就没办法在编译时传入参数条件,插入编译脚本,配置个性化编译配置,所以scheme是Xcode编译时的必须选项。

打开一个scheme源文件,我们可以看到如下布局:

图片

可以看到,最外层包含着build、test、launch、profile、analyze、archive。恰好对应了Xcode中的与之对应的命令,再次验证了Xcode就是pbxproj的可视化呈现。

进入BuildAction可以看到我们在Xcode中添加的预编译脚本和各种环境变量配置,这些配置有的是在编译过程中必不可少的参数,有的是方便我们管理编译产物的必须配置,灵活运用这些配置,可以让Xcode更好的为我们服务。

 

6. 探寻target

target用于指定要构建的产物,即framework或者app。target只包含了当前project中的部分指定的代码和资源文件,每一个target只能构建出一个特定的构建产物,为了丰富构建产物,一个project可以拥有多个target。

target使用Build Settings和Build Phases的形式来进行个性化配置,默认这些配置可以通过project继承,也可以通过手动或者配置文件的方式覆盖其他配置。

target之间可以互相依赖,如果是在同个workspace下,Xcode默认会触发隐式依赖,当然,如果用手动配置依赖关系,则会变为显式依赖。显式依赖的优先级高于隐式依赖。

 

7. 总结与展望

根据上面的介绍,大家一定对Xcode的工程配置有了一定的了解,在了解了这些之后,我们能做些什么呢?其实是有很多玩法的:

  • 根据不同的编译scheme编译指令,提取出编译产物,分发给不同的人员。

  • 根据target的不同,在不改变源码的前提下,每次编译设置不同的环境测试包。

  • 编译过程中检查出警告信息及时上报开发人员。

  • 编译时找出无效代码及文件。

  • 利用cocoapods的动态配置在安装的时候直接引入二进制组件以增加编译速度。

  • 输出指定framework的编译日志到文件方便对比查阅。

 

了解了这些基础配置,以后在项目的工程化方面才有更多手段解决重复度高或者棘手的问题,还有更多的新玩法可以在工作过程中发掘。

 

作者|王一飞

原文链接:https://www.cnblogs.com/88223100/p/Xcode-Engineering-Analysis.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Xcode 工程分析 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • iOS 组件化实施过程

    目录 一、组件化的优缺点 二、组件化的拆分 三、组件与组件之间如何进行通讯(路由) 四、从Cocopods拉取代码的过程 五、创建本地私有库 一、组件化的优缺点 二、组件化的拆分 三、组件与组件之间如何进行通讯(路由) 四、从Cocopods拉取代码的过程 远程索引库里很多的.spec文件,该文件记录了很多内容,如用户名,框架名称,描述,框架的地址 Podf…

    IOS 2023年4月18日
    00
  • graphhopper-ios 编译过程详解

    一、写在前面 GraphHopper 是一个快速且高效的路径规划引擎,它默认使用OpenStreetMap和GTFS数据, 也可以导入其他数据源。它可以用作java库或独立的web服务器,去计算两个或多个点之间的线路的距离,时间,转弯指令和许多道路属性。除了“A-to-B”的路径规划能力之外,它还支持“snap to road”、等时线计算、移动导航等。 g…

    IOS 2023年4月18日
    00
  • Swift CustomStringConvertible 协议的使用

    目录 一、前言 二、使用场景 1. 整型类型的枚举使用 2. Class类型的使用 一、前言 先看一下Swift标准库中对CustomStringConvertible协议的定义 public protocol CustomStringConvertible { /// A textual representation of this instance. /…

    IOS 2023年4月22日
    00
  • 2023年2月苹果最新屏蔽系统更新描述文件

    有相当一部分 iPhone 用户会拒绝iOS更新最新系统,不管是因为各种BUG还是因为其他优化方面的问题,他们都会选择一个自己觉得均衡的系统版本,安逸养老。 但是苹果 iOS 系统如果你不及时更新推送版本的话,就会在手机桌面「设置」上方出现角标数字红点,系统设置中也会出现红点提示。强迫症患者表示简直受不了,那么有没有什么办法能解决呢?   屏蔽系统更新 以前…

    IOS 2023年4月17日
    00
  • .NET Core部署到linux(CentOS)最全解决方案,入魔篇(使用Docker+Jenkins实现持续集成、自动化部署)

    通过前面三篇: .NET Core部署到linux(CentOS)最全解决方案,常规篇 .NET Core部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx) .NET Core部署到linux(CentOS)最全解决方案,高阶篇(Docker+Nginx 或 Jexus) 通过前面三篇文章的介绍,我们已经对.net co…

    C# 2023年5月7日
    00
  • iOS上架流程

    1 准备 2 申请App ID 2.1 打开[苹果开发者官网](https://developer.apple.com),点击Account登陆账号。 2.2 进入ID申请 3 创建证书请求文件(*.cerSigningRequest文件) 4 添加软件开发证书和分发证书 并下载(*.CER文件) 5 创建Profile配置文件 6 新建开发者应用 7 打包…

    IOS 2023年4月17日
    00
  • csm移动端h5用什么样的视觉方案?

    项目需要求在移动端H5需要展示一些数据统计的图表,虽然第一时间想到的是echarts,常用还有Highcharts,D3等,antv家族的图表UI好看一些,再加上F2是移动端可视化方案于是就选择F2,打开官网果然眼前一亮F2提供的正能满足需求,F2官网地址:https://antv.alipay.com/zh-cn/f2/3.x/demo/index.htm…

    IOS 2023年4月18日
    00
  • 使用SDLocalize高效完成iOS本地化国际化工作

    使用SDLocalize高效完成iOS本地化国际化工作 SDLocalize 该方案最大特点是对旧代码几乎没有较多修改就可以完成从单语言项目修改为多语言的项目。并支持XIB的控件本地化,无需创建不同语言版本的XIB文件。 SDLocalize的工作原理: 首先标记一组需要本地化的控件 然后在恰当时机(viewDidLoad),触发一组本地化任务(Then (…

    IOS 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部