1.6 Xcode 界面及应用程序创建 - 少数派

点击查看原文

在软件准备的文章中,提到 Xcode 是一款功能齐备、需要在 iOS 开发的各个阶段使用的工具软件。本文中,我将从零开始,带你了解它的界面及应用程序运行方式。

本文是一篇实操教程,建议阅读本文时,打开 Xcode 跟着一起操作,这样有助于你熟悉界面和应用创建流程。Apple 所有软件及系统的最新版本都可以在 Apple News and Updates 网页中查看,若你发现以下教程中截图所展示的与你的软件界面不符,请确认是否使用软件版本是否于本教程一致。

创建应用程序的步骤

初次打开 Xcode,你会发现与其它即开即用的程序不同,Xcode 不会直接显示主界面,取而代之的是如下图所示的欢迎界面。这是因为 Xcode 是一款以项目为基础的软件,若没有项目它便不知道该显示什么,因此你需要明确告诉它打开或者创建一个应用程序项目。

在欢迎面板中,左侧提供了项目的来源的选项,右侧展示了最近使用过的项目以便快速打开。Xcode 项目的来源主要有三种,分别是:创建新应用项目 (Create a new Xcode project)、直接打开网络上他人创建的项目 (Clone an existing project)、打开之前创建的本地项目 (Open a project or file)。

第一步:选择欢迎面板中的「Create a new Xcode Project」来创建一个新项目。接下来会弹出如下图所示的 Xcode 模版选择界面。Apple 提供了一系列已经完成部分琐事后的成品模版以供使用,方便开发者快速进入创作状态。此处选择默认的「Multiplatform App」跨平台模版,并点击「Next」下一步。跨平台模版是开发 iOS、iPadOS、macOS 的跨平台应用的优秀起点,后续你也可以在项目中根据实际需求为其添加 watchOS 等其它平台的支持。

第二步:在选择模版后,接着弹出的便是当前项目设置。你既可以在这里提供项目的详细信息,也可以轻度定制你的模版。

上图中项目设置的界面中信息较多且比较重要,分解介绍如下:Product Name 是你的 Xcode 项目名称,此处你可以填写应用暂定的名称,范例中使用 LegolasDemo 为项目名;Team 处选择你的 Apple ID 账号;Organization Identifier 指的是创作者识别码,它有点像你的电子身份证,需要独一无二。开发者通常会在此填写个人网站地址的倒置,比如我的网址是 legolas.me,这里则填写 ​me.legolas​。若你没有个人网址,此处用邮箱名或其它可以唯一辨识你的信息也可以。

当你填写完项目名称、Apple ID 与创作者识别码后,会发现接下来的 Bundle Identifier 已经为你自动生成。Bundle Identifier 是创作者识别码与项目名称的组合,比如 ​me.legolas.LegolasDemo​,它的作用是在 Apple 各个平台中唯一识别你的应用。

「Use Core Data 和 Host in CloudKit」不勾选,用到时再讲。项目设置中的最后一个选项是「Include Tests」预置测试文件,请将其勾选。Tests 测试指的是代码的测试文件。在程序开发过程中,开发者时不时会写一些基于  XCTest 测试框架 的代码,来测试程序的 UI 及性能表现是否符合预期。勾选此选项之后,Xcode 会自动预留未来添加测试代码的文件。完成以上信息的填写后,点击「Next」下一步。

Product NameXcode 项目名称LegolasDemoTeam 创作团队Legolas Wang (Apple ID)Organization Identifier创作者识别码me.legolasBundle Identifier创作者识别码与项目名称的组合me.legolas.LegolasDemoInclude Tests预置测试文件勾选

第三步:接下来弹出的是项目存储地点和选择。因 Xcode 项目存储结构较为复杂,使用 iCloud 可能会造成项目文件同步不一致,不建议使用。我推荐将项目存在本机根目录中的开发者 Developer 文件夹中(如果没有自动创建,自己创建同名文件夹也可),如下图所示。

你可能会担心,将我的项目存在本地,如何保证数据不丢失?我每次做完更改后,万一遇到了问题,如何返回之前的版本?这两个问题我们会通过 Git 版本管理来解决,其详细用法会独立开篇讲解。现在,你只需要做好准备工作,勾选此弹窗下方的「Create Git repository on my Mac」来在项目文件中预置本地 Git 即可。接下来点击「Create」即可创建项目。

创建完成:创建完成后你便会看到如下图所示的 Xcode 主界面。点击左上角的三角形「运行」按钮,你的应用程序便会在弹窗出现的虚拟机中运行!

主界面

下面是 Xcode 中主要面板全部展开的情况,你也许会感觉它稍显复杂,下面我将依次为你分解介绍。为降低认知压力,我将它分割成五个区域,分别是上左中右下,其名称如下图所示。

若你的 Xcode 主界面和上图稍有不一致也不必担心,可能是因为部分面板被隐藏了。如下图所示,依次点击窗口顶端最左和最右侧的两个控制按钮即可显示左右面板。Xcode 主界面下方的调试面板则会在项目运行时自动显示。

上 - 运行面板

Xcode 上部的运行面板分为三行,其中第一行的左半部分负责运行及状态。若你观察下图,会发现整个左半部分重整语序后可以读成一个完整句子「在 iPhone 11 设备上运行 LegolasDemo (iOS) 这个目标,当前它的状态是项目已完成运行」。

第一行 - 运行及功能按钮:将第一行具体拆分来看,左侧是运行及停止按钮,中间部分允许你选择在什么设备上运行哪个目标程序。当前状态栏的部分会给出程序运行的结果,比如运行完成、因什么错误失败等。第一行右侧的两个按钮分别代表两个功能:便捷库和代码版本对比。便捷库类似于文具盒,它提供一系列预设和自定义功能,会在下文详细介绍。版本对比功能则与 Git 相关,会单独开篇讲解。

第二行 - 标签分页:第二行左侧类似于网页浏览器,允许你在不同分页中切换,最左侧提供类似网站的前进和返回按钮。这行右侧的两个按钮分别是「主编辑器设置」按钮及「新增编辑器」。主编辑器设置按钮中,包含开关 SwiftUI 的预览界面 Canvas、代码导航小地图 Minimap、显示不可见元素 Invisibles 等。若你对 Invisibles 不理解,可以阅读我的 Pages 教程 来学习不可见元素的语法,其原理相通。顾名思义,另外新增编译器的按钮,指的是在主编辑器区域新增一个编辑器,以便你同时查看或修改不同文件。

第三行 - 快速导航:这行有点类似文件夹管理中的文件路径,但功能更丰富些,你不但可以点击路径中的部分来实现快速跳转,还可以自定义代码中的不同提醒。具体用法会在下一篇文章的「常用功能 - 快速切换文件」中介绍。

左 - 导航器面板

Xcode 左侧导航器面板由可选择的不同小功能组成,包括下图中默认选择的「文件管理选项」。在文件管理选项下,左侧面板会显示项目中的组成文件,比如下图里的 LegolasDemo 根文件。

除文件管理外,导航器中还包含如下选项:版本管理的 Source Control、代码结构 Symbol、全局搜索 Search、管理代码问题的 Issue、显示测试的 Test、性能调试的 Debug、中断点切换的 Breakpoint、显示历史运行报告的 Report,共计 9 款不同功用的导航器。我们会在教程的不同阶段接触并讲解这些选项。

中 - 主编辑面板

主编辑器面板可以被视作一块随需求变动的显示区域,它显示的内容不固定,由左侧导航器面板中当前选择的文件决定。若你在导航器中选择 Assets,则主面板中会显示素材管理;导航器中选择 Swift 代码,则主面板中会提供代码编辑的功能,其它类别的文件也是如此。下图中展示了部分主编辑面板可能显示的内容。

右 - 监视器面板

与中部的主编辑面板类似,Xcode 右侧的监视器面板也是一个根据左侧导航器所选文件而变化的面板。但它的变动幅度没有导航器那么大。一般来说,Xcode 右侧的监视器面板具有下图中的四个常驻选项。第一个选项显示当前选中文件的重要信息、第二个时钟图标负责显示当前文件的版本控制提交记录、第三个问号显示与当前选择有关的开发者文档、第四个 Attributes 属性面板,会根据文件不同提供一些额外选项。

下 - 调试面板

Xcode 下方为调试面板,一般在项目运行时弹出。它包含上边一个功能条,与下边左右两部分视图。上边的功能条提供代码和正在运行程序的调试信息。以下图为例,功能条前六个按钮提供与中断点相关的功能,右侧的信息则告诉我们程序在哪个具体位置中断或运行完成。

功能条下方的视图,左边叫做变量视图 Variable View,这里会显示当前中断位置上下语境中所包含各种变量的详细信息。右侧视图叫做控制台 Console,你的 print 等信息会在这里显示,同时它还是个 LLVM 调试台,你也可以在此输入 LLVM 指令。此处部分内容超出本教程范围,若你感兴趣,可以通过其它 编译器课程 或文档学习。

上边功能栏中的中间四个功能分别负责:帮助检查 UI 界面中存在的问题、内存的异常使用情况、测试运行时程序的深色模式及字体设置开关、调整机器当前虚拟位置。你可以运行上一小节中创建的模版程序,运行后分别点击这四个按钮并观察 Xcode 行为,我们会在教程的不同阶段具体讲解并使用这其中部分功能。

程序运作的核心概念

在前两个小节中,我们使用模版创建了 Xcode 应用,并了解 Xcode 基本的界面元素。在本小节中,我将回到创建完成的应用中,来讨论与应用程序运作相关的几个概念。

项目中的文件类型

打开刚创建好的模版应用,你会发现其中包含不少预设好的文件,如下图所示。其中 Products 文件夹中包含编译好的应用、Tests 文件夹包含测试用的预留文件等,将会在以后使用时再讨论。模版预留文件中,文件名中的 Shared、 iOS、macOS 只用于区分该文件夹中文件是全平台适用还是仅与特定系统相关。

用 Finder 打开后的 Xcode 项目文件夹

在众多预设文件中,真正负责 iOS 应用运行的只有 4 个文件,分别是 LegolasDemoApp、ContentView、Assets 和 Info。而这四个文件又可以根据其尾缀进一步细分为三种类型,分别是 .swift、.xcassets、.plist。

Swift 作为编程语言,任何代码文件在 Xcode 中都以 .swift 类型为尾缀。当点击程序运行按钮时,Xcode 会自动读取所有 .swift 文件中的代码并编译,来实现程序功能。

Xcassets 文件指的是 Xcode Assets 素材文件类型,这是一类由 Xcode 管理的特殊文件,它包含程序运行的所有素材,如图标、图片、颜色等。

Plist 的全称是 Property List 属性列表类型文件,顾名思义,它所负责存储的是一些信息,并与目标设备沟通,比如当程序在 iPhone 运行时,.plist 文件负责告诉手机,程序的显示名是什么、是否支持横屏、为什么要申请使用相机等基础但不可或缺的信息。

预置文件用途:将刚才创建的模版应用中  4 个与 iOS 运行相关的文件依次排开,如上图所示。与刚刚对其文件类型的描述类似,也许你已经可以从上图的文件名中猜出其用途。具体来说,LegolasDemoApp.swift 文件是应用程序的入口,告知手机要显示 ContentView 文件中的 UI 界面;ContentView.swift 文件包含程序的 UI 信息,明确要显示什么内容,要怎么排版;Assets.xcassets 文件提供程序用到的图标等媒体素材;Info.plist 文件负责与目标设备沟通你应用程序的基本信息。

为程序添加更多功能:import 导入框架语法

上文介绍框架的概念时,提到过不同框架为程序提供不同预设功能,犹如开发者的百科全书。但市面上的框架非常多,除了 Apple 官方的,还有许多第三方开发者制作的框架,开发者必须优先根据应用目标做出筛选。而「import」导入语法可以让程序拥有更多可用功能,进而实现用户需求。

写一个程序好比写一篇文章,你会将待用的相关书籍从百科全书系列里找出来放在手边以做参考。当你从框架的百科全书中选择完你需要的之后,在 .swift 文件的开头使用「import X 」的语法,即导入 X 框架,来告诉 Xcode 你需要在当前文件中使用这本参考书。

LegolasAppDemo 文件的内容

在刚才创建的应用中,你会发现第一句便是 ​import SwiftUI​。正因为导入 SwiftUI,才可以使用 Swift 及 SwiftUI 的内容。如果你还记得上一篇文章中对 Swift 和 SwiftUI 的介绍,你也许会质疑以上代码的正确性:既然这两个框架不同,那为何不需要把 Swift 和 SwiftUI 都导入进来?以上代码确实是正确的,之所以可以运行是因为 Swift 语言实在太重要,以至于大部分 UI 框架在导入时默认也会自动导入 Swift 框架。虽然没有额外写明,但 import SwiftUI 的同时 Xcode 也准备好了 Swift。

应用程序的起点:@main

依旧是 LegolasDemoApp 文件中的内容,当点击运行按钮来运行应用后,Xcode 是如何知道在众多文件中从哪里开始呢?Xcode 会在所有 .swift 文件中寻找一个入口,当作应用程序起点,这个入口的路标在 Xcode 中便是​@main​语法。在下图的预置代码中,@main 已被 Xcode 放置在了导入框架后与代码开始之前。若你想深度了解 @main 的实现原理,可以查看 SE-0281 中的说明,本教程中只需要知道它的用途即可。

项目运行顺序:App > Scene > View

上文提到,创建 Xcode 项目时选择的 Multiplatform App 是一个跨平台模版,使用此模版创建的应用程序会自动包含运行在 iPhone、iPad 与 Mac 上的能力,并具有起始代码。

在这个模版中,真正负责执行命令并在虚拟机中显示文字的只有 LegolasDemoApp 和 ContentView 文件中的代码,如下图所示。若你也在跟着操作,可能会发现此图中我省略掉了 ContentView 中的后半部分代码,并将其前半部分代码与 LegolasDemoApp 中的代码拼合在一起,程序依旧可以顺利运行。

范例应用中 LegolasDemoApp 与 ContentView 两份文件拼接在一起

程序运行的完整流程如上图。Xcode 通过 @main 找到起点后,创建了 LegolasDemoApp 的应用 instance 实例来运行,此实例使用 WindowGroup Scene 来显示 ContentView 里的内容。应用运行时,显示的场景内容是 ContentView 的 instance 实例。依次而下,最终将 ContentView 里 body 的内容显示在屏幕上。若你目前对这个流程感到困惑也没关系,毕竟还没有学 Swift 编程语言,但你可以根据上面图片里的流程图大致感受一下应用程序的运作。

为什么将代码拼接在同一文件中也行呢?这是因为在同一个 Xcode 项目中,所有不同 .swift 文件中的代码都会被执行,因此开发者将代码放在不同文件、或是在同一文件中本质上没有区别。正因如此,可以将这两部分的代码拼合在一起。你操作时不需要这么拼接,但你需要理解代码放在不同文件中的缘由,更大程度上是为开发者的阅读及管理而已,并不一定需要分开。

项目与目标的关系:Project - Target

在创作应用程序时,我们时常需要考虑登陆不同平台,比如 iOS 和 macOS。如何根据不同平台的设备提供不同的功能,规划一套分类管理系统呢?Xcode 给出的这套分类系统便是 Project - Targets,即项目 - 目标,它允许开发者将不同需求的资源从主项目中划分给不同目标。针对一个项目 Project,如 LegolasDemo,可以设定多个不同目标 Target,如 iOS 和 macOS。

你可以将 LegolasDemo 这个根文件夹,看作是 LegolasDemo 应用所需要的全部代码、图片等内容的资源的集合。在理想情况下,我们也许希望应用在所有系统下使用完全一样的代码。实际情况却常告诉我们说这不现实,比如你有一套负责震动体验的代码,由于没有振动马达,这套代码放在 iPad 或 Mac 上则毫无价值。

Xcode 中从根目录中选择 LegolasDemo 文件后,主面板会显示上图选项

偏好设置

和其它软件类似,Xcode 也具备丰富的自定义设置。在本小节中,我将讲解设置界面中登录账号的设置,来为本章末 Git 版本管理的文章做准备,同时向你简单介绍 Xcode 强大且易用的行为系统,让 Xcode 更懂你的喜好。

依次点击「Xcode - Preference 」进入设置面板,这里面每个设置大致功能都比较明确,你可以点击每一项设置来了解这些选项。下文将着重讨论 Accounts 账户和 Behaviours 行为这两个选项卡。

帐号登录

在帐号登录选项卡中,我们首先需要登录 Apple ID 来向 Xcode 告知身份。这里你只需要登录你日常使用的 Apple ID 即可,无其它特殊设置。第二个需要登录的帐号是 Git 远程版本管理工具,本教程的选择是 GitHub。

点击「+」按钮添加帐号并选择 GitHub 之后,你会发现此处需要填写 Account 和 Token。其中 Account 是 GitHub 用户名,Token 则是一个特殊的许可,它允许 Xcode 使用你的 GitHub 帐号管理你的 Remote Repository 远程仓库。远程仓库的概念与 Git 有关,可以粗略理解为程序员的 iCloud 备份,会在 Git 文章中详细讲解。

点击 GitHub 设置页面 来登录你的 GitHub 帐号,如下图所示,点击右上角的「Generate new token」即可生成一串许可数字,将这串数字复制回到 Xcode 登录界面的 Token 文本框中,并点击「Sign In」登录即可完成 GitHub 帐号的设置。

不同阶段,不同响应方式:行为设置

Xcode 的不同面板设计非常灵活,你可以在 Behaviour 行为设置中,根据应用所处的不同状态,比如开始运行、暂停运行等状态来设置 Xcode 的反馈行为。下图中自定义行为面板的左侧代表事件发生的类型,右侧代表 Xcode 所作出的反馈。比如每次应用运行成功后在系统通知栏提醒,运行失败时在 Dock 中图标晃动提醒等,你可以根据个人喜好自由调整 Xcode。

总结

本文讨论了 Xcode 中应用的创建流程、界面要素以及程序运作中的重要概念。接下来的两篇文章中,我会以 Xcode 的基础知识为背景,带你了解一些围绕 Xcode 的常用工作流及提升效率的功能特性。