Xcode 工程分析

yizhihongxing

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日

相关文章

  • 2023年2月苹果最新屏蔽系统更新描述文件

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

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

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

    Android 2023年5月9日
    00
  • .NET Core 环境变量详解

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

    C# 2023年4月22日
    00
  • Bat批处理命令实现一键安装mysql环境

    已测试可用的版本 MySQL 8.0; 环境: windows7/10MySQL 8.0.15免安装版 项目需求 需要实现一个自动化MySQL配置安装及初始化数据库(初始化包括:设置用户名和密码)。 批处理 用来对某对象进行批量的处理,即可通过批处理让相应的软件执行自动化操作。 MySQL免安装版使用步骤: 1.配置环境变量2.创建MySQL配置文件3.注册…

    MySQL 2023年4月18日
    00
  • 水平分库分表排雷帖

    一、背景 提起分库分表,对于大部分服务器开发来说,其实并不是一个新鲜的名词。随着业务的发展,我们表中的数据量会变的越来越大,字段也可能随着业务复杂度的升高而逐渐增多,我们为了解决单表的查询性能问题,一般会进行分表操作。 同时我们业务的用户活跃度也会越来越高,并发量级不断加大,那么可能会达到单个数据库的处理能力上限。此时我们为了解决数据库的处理性能瓶颈,一般会…

    MySQL 2023年5月6日
    00
  • iOS16新特性 | 灵动岛适配开发与到家业务场景结合的探索实践

    作者:京东零售 姜海 灵动岛是苹果在iPhone 14 Pro和iPhone 14 Pro Max上首次提出的全新UI交互形式,创新性的让虚拟软件和硬件的交互变得更为流畅。当有来电、短信等通知时,灵动岛会变化形态,以便让用户能够更直观地接收到这些信息。 而在用户使用一些应用App,比如音乐,并将其切换到后台时,灵动岛也能以另一种形态来显示这些软件,还可以通过…

    IOS 2023年4月17日
    00
  • ios animation 动画学习总结

    目录 一、前言 二、UIView Animation 2.1 简单动画 2.2 关键帧动画 2.3 View 的转换 三、CALayer Animation 一、前言 动画一直是 iOS 开发中很重要的一部分。设计良好,效果炫酷的动画往往能对用户体验的提升起到很大的作用,在这里将自己学习 iOS 动画的体会记录下来,希望能对别人有所帮助。 iOS 的动画框架…

    IOS 2023年4月18日
    00
  • iOS的Runtime知识点繁杂难啃,真的理解它的思想,你就豁然开朗了

    一、Runtime 1、概念: 概念:Runtime是Objective-c语言动态的核心,即运行时。在面向对象的基础上增加了动态运行,达到很多在编译时确定方法推迟到了运行时,从而达到动态修改、确定、交换。。。属性及方法 作用: 这给程序员写代码带来很大的灵活性,比如说你可以把消息转发给你想要的对象,或者随意交换一个方法的实现之类的!多态 kvo kvc 获…

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