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日

相关文章

  • [Android开发学iOS系列] Auto Layout

    [Android开发学iOS系列] Auto Layout 内容: 介绍什么是Auto Layout. 基本使用方法 在代码中写约束的方法 Auto Layout的原理 尺寸和优先级 Auto Layout的使用细则 重要的属性 StackView Layout Guide Performance Debugging What is Auto Layout …

    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
  • iOS 悬浮球效果实现,悬浮按钮,拖拽,贴边,隐藏,显示,旋转屏幕适配

    1.悬浮球与设备刘海的安全距离无论是横屏还是竖屏,悬浮球距离有刘海的一边会留出安全距离设备方向的上下两边,也有安全距离 2.贴边吸附方向和距离悬浮球只能贴设备方向的左右两边,需要贴上下两边自行调整距离边缘的数值自行调整 3.切换横竖屏,悬浮球自适应悬浮球位置切换横竖屏后,等比例转换的。 4.隐藏和显示拖到屏幕中间ImageView范围内可以隐藏悬浮窗,在范围…

    IOS 2023年4月18日
    00
  • 教会你使用AI绘画利器Stable Diffusion

    随着 stable-diffusion 的开源,让更多人有机会直接参与到 AI 绘画的创作中,相关的教程也如雨后春笋般的出现。可是目前我看到的教程同质性较高,通常只能称作为”使用流程讲解”,但是通常没有对其原理和逻辑进行深入说明。 所以本文的目的,是用尽可能少的废话,给大家补充一些重要的相关知识。对于”怎么用”这类的问题,通常有别人已经讲解过,我就不会过多赘…

    人工智能概论 2023年5月11日
    00
  • .NET Core 环境变量详解

    一、概述 软件从开发到正式上线,在这个过程中我们会分为多个阶段,通常会有开发、测试、以及上线等。每个阶段对应的环境参数配置我们会使用不同的参数。比如数据库的连接字符串,开发环境一般我们都是连接的测试库。以前这种情况通常是 COPY 两个同名的配置文件来进行处理,然后在本地就使用本地的配置,生产环境就使用生产环境的配置文件,十分麻烦。而 ASP .NET CO…

    C# 2023年4月25日
    00
  • Apple Xcode 14 (14A309) 正式版发布 (含下载)

    Command Line Tools for Xcode 14tvOS 16 Simulator RuntimewatchOS 9 Simulator Runtime 请访问原文链接:https://sysin.org/blog/apple-xcode-14/,查看最新版。原创作品,转载请保留出处。 作者主页:www.sysin.org Xcode 14 包…

    IOS 2023年4月18日
    00
  • 内存管理(二)之别小看了Tagged-Pointer关键时刻起到大作用

    本文主要研究Tagged Pointer技术,针对该技术需要解决的问题、以及在实际应用中的价值做一些简单的探讨。 如果你想要更进一步,去挖掘Tagged Pointer是如何实现的,可以参考Friday Q&A 2012-07-27: Let’s Build Tagged Pointers和objc源码。 另外,本文中涉及到的示例代码,请在真机iOS…

    IOS 2023年4月18日
    00
  • 汽车之家Unity前端通用架构升级实践

    背景介绍 随着之家3D虚拟化需求的增加,各产品线使用Unity引擎的项目也越来越多,新老项目共存,代码维护成本也随之增加。代码质量参差加之代码规范仍没有完全统一产生高昂学习成本进一步加重了项目维护负担。 为应对这些问题,我们决定借助主机厂数科产品线销冠神器VR版本大升级为契机,开发一套移动端通用Unity代码框架,旨在统一Unity项目开发流程和规范,使不同…

    Android 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部