大多数浏览器和
Developer App 均支持流媒体播放。
-
Xcode 入门
Xcode 是用于为各个 Apple 平台打造出色 app 的开发环境。了解如何利用 Xcode 功能来完成从新建项目到 App Store 分发的整个过程。您将通过开发一个正常工作的 SwiftUI app,学习如何浏览 Xcode 用户界面,如何利用源代码编辑器和实时用户界面预览,如何将社区开发的 Swift 软件包整合到您的 app 中,以及如何重构和测试您的代码。
资源
- Learn more about App Store Connect
- Swift API Guidelines
- The Swift Programming Language
- Xcode Help
- 演示幻灯片 (PDF)
相关视频
WWDC19
WWDC18
-
下载
(Xcode入门)
欢迎参加Xcode入门演讲 我是Prachi 是Xcode工程师 我将和同事Holly、Honza 一起演讲 我要讲的是如何用Xcode 创建简单的iOS app Xcode是一个集成的开发环境 用于Swift、 Objective-C 和其它语言的软件开发
在本场演讲中 我们会讲如何用 Xcode创建新项目 在Xcode的源编辑器中如何编写 并导航源代码
运行和调试可能存在于代码基中的 任何问题
使用程序包和框架扩展app的功能 最后讲如何测试并把app 发布到App Store
(创建新项目) 让我们先讲… 在Xcode中创建新项目
在你面前的是Xcode窗口 我要分成四个不同的区块讲
中间的区块是源编辑器 你可以浏览并编辑所有文件 特别是当源编辑器打开时 你可以用它导航并编辑所有源代码 还有其它编辑器可用 如项目编辑器 在这里 你可以在需要的时候 自定义项目设置
在项目编辑器内 你可以找到app的目标 目标包含创建产品的说明 这些产品比如包含库、框架、 测试包和app自己
Xcode最左边的窗口是导航器 你可以快速、轻松地浏览 项目内的所有内容 你可以使用导航器选择条 来选择一个导航器 你有许多可用的工具
因为我们已经选择好了项目导航器 你可以用它来添加、删除群组 或管理存在于项目中的所有文件
在最右边的区块是检查器 它提供关于编辑器的内容的情境数据 因为我们已经打开了源编辑器 你可以浏览所显示的文件的信息 比如文件名称和文件路径
顶部区块是一个工具栏 你可以在这里找到运行按钮 它会创建并运行产品
停止按钮会终止 当前正在进行中的行动
接下来的两个下拉菜单是 方案和运行目的地 方案是一个可共享的文件 包含创建、运行和测试app的规则 运行目的地是在哪里运行app 你可以选择在某设备的模拟器上 运行app 如iPhone XR 我们用的是 iPhone XR模拟器 你可以在Mac上运行它 或在已连接的设备上运行它 比如iPhone或iPad
最后三个按钮 是显示和隐藏菜单 它们会显示并隐藏Xcode窗口的 不同区块 这些菜单用起来非常便利 比如 如果你正在开发代码 并且你需要在编辑器中有更多空间 你可以右击鼠标关闭检查器 并在编辑器中获得额外的空间
现在我想让你们注意一下 Xcode帮助按钮 在这里你可以访问资源 比如 开发者文档、 版本注释和Xcode帮助
Xcode帮助对于了解Xcode 来说是一个非常棒的资源 我们强烈推荐你们自己浏览 其中的内容
(演示) 现在我们讲了Xcode窗口的布局 让我们继续并从零开始 创建一个实际的项目
在你们面前的是 欢迎进入Xcode窗口 在左边 你可以选择创建一个新项目 它会保存app的所有文件和资源 你还可以克隆一个现有项目 那可能会托管在源代码控制账户上 比如GitHub 最后你还可以选择打开 Xcode Playground 它允许你体验你的Swift代码 然后实时查看代码所产生的结果
在右侧是我们最近正在修改的 所有项目 我们可以快速、轻松的看到它们 我要继续并在Xcode中 创建一个新项目
这将打开模板选择器 模板是app的起点 Xcode中有各种不同的可用模板
为了选择合适的模板 我们需要先确认我们要开发的平台 我知道我要写一个iOS app 所以我继续并点击iOS标签 在这个标签内 你会注意到有两大类模板 即app模板 以及框架和库模板
为了达到这场演讲的目的 我要继续并选择app模板 我要选择最简单的一个模板 即单一视图app 我要点击下一步 我和我同事决定创建一个冥想app 我们决定把它命名为Mind 对于项目名称 我要输入Mind
对于组织名称 一般来说 我会填写我的组织的名称 但为了本场演讲的目的 我要把我们的组织叫做 Example Team
然后组织标识符是 组织名称的反向DNS 在这个例子中 是com.exampleteam
最后捆绑标识符是自动填写的 它是你的app 在Apple生态系统内的唯一ID 它是产品名称 和组织标识符的组合 对于语言 我要继续并保留Swift 因为我要用Swift写我的app
我要确保我包含了UI测试 从而它会为UI测试创建一个目标 因为作为开发人员 我们想形成 时常测试代码的习惯 我们稍后会演示如何添加单元测试
在你点击完成后 它将打开保存表单 在这里我可以决定 我想把app保存到哪儿 它默认保存到桌面 我觉得没问题 所以我没做出什么修改 但我想确认一件事 即在项目的最开始源代码就可用 从而我可以管理、追踪和备份
我在开发过程中所做出的任何修改 因此我要继续并检查 Mac复选框中的 创建一个Git仓库 我要点击创建
现在我们已经设置好模板了 我们可以向app中添加app图标 app图标是无论何时 当用户想启动我们的app时 所要选择的图片 app图标是资产 资产比如包括图片和颜色
资产目录管理和组织资产 我们可以通过导航器 点击资产目录进行访问 因为我们想要app图标的目录 让我们继续并点击 app图标和编辑器
从目录中你会注意到你的资产有 通知、设置、聚焦以及app自己 我桌面上有app图标了 它已经可以使用了 我有一台设备使用2X分辨率 因此app图标—— 资产有1X、2X和3X分辨率可用 取决于你所使用的设备 我要继续并把这个app图标 拖入到针对iPhone app的 2X目录框中
现在我想测试我的app图标 以确保它确实可以使用 为此 我想在iPhone XR 的模拟器中运行它 因此我要把运行目的地修改为 iPhone XR
然后点击运行按钮
这将会启动模拟器
你将注意到模拟器 立即启动我的app 我知道这是因为它显示的是 Hello World 这是我的模板的设置 所以我需要进入硬件菜单 在主页屏幕上查看我的app图标 我要进入硬件菜单…
点击主页
这将把我带到主屏幕上 我可以看到那儿有我的图标 如果我点击app图标 我的app会返回到前台中 很棒 我知道我的app图标能用了 我可以终止模拟器的执行
现在我们的起点很好 我们可以提交并保存我们的修改 从而同事Holly和Honza 可以继续开发这个app… 继续开发这个项目 为此 我们首先需要添加一个 GitHub账户
我们可以通过Xcode首选项实现 你可以打开Xcode菜单 然后进入首选项菜单
Xcode首选项可让你按需 自定义Xcode 要添加一个账户 我们要继续并继续账户首选项面板 并点击加号按钮 你可以看到 有许多可用的账户 因为我们只对 GitHub账户感兴趣 我们要点击GitHub并点击继续
现在它要求我填写账户认证信息 我要继续并输入我的账户名称和密码
它登录了我的账户 很棒 我要继续并关闭Xcode首选项
现在我需要进行提交 为此 我要进入源代码控制菜单 并点击提交
这将打开提交表单 在这里你可以核实你所做的全部修改 并且你可以添加一条提交信息 从而告诉你的同事你做了哪些修改 对于提交信息 我要写此次提交 将添加一个app图标
然后我点击提交 那将关闭提交表单
现在我们的情况是这样的… 在我们的开发中 我们先是用Xcode 创建了一个项目
然后选择了一个 适合我们的平台的模板
我们给我们的资产目录中 添加了一个app图标 然后我们使用了 Xcode源代码控制功能 提交了我们的修改 从而我们的同事可以继续开发 我们的项目
要了解更多关于源代码控制的信息 我们推荐你们参看 2018年的Xcode中的 源代码控制流程演讲
现在我们可以开始 向我们的app中 添加实际的冥想功能了 为此 我要邀请同事Holly上台 谢谢
谢谢Prachi
我叫Holly 是Xcode 源代码编辑器团队的软件工程师
欢迎使用源代码编辑器 你可以在这里编写app的所有代码
在源代码左侧有行编号 代码右侧是迷你地图 显示编辑器中的文件的视图缩影 用于导航
在源代码上方是跳转栏
跳转栏还会帮助你在编辑器中 导航文件 通过弹出功能实现
跳转栏可以让你自定义 编辑器的布局 通过使用编辑器选项 和编辑器拆分菜单实现
我们已经在创建我们的冥想app上 取得了很大的进展 让我们看一下我们的目标
我们要创建一个冥想app 可以让用户选择一个持续时间 并在那段时间内进行冥想 当冥想结束后 app将把用户进行冥想的分钟数 写到他们的健康数据中
我们需要添加大量Swift代码 才能让我们的app发挥作用 但我们不尝试读取我所写的代码 我希望你注意一下 Xcode所提供的工具 用以辅助编辑过程
如果你不熟悉Swift 那么欢迎你使用Swift 要了解Swift 我推荐你浏览Swift指南 它在线可用 或你可以查看 Xcode Playground 从而可以在你看Swift指南时 体验Swift代码
你可以在docs.swift.org上 找到指南
接下来让我们继续讲Xcode
我向Prachi刚展示给我们的 项目模板中添加了一些代码 用于实施冥想的时间选择 并为app绘制一个平静的背景 我们仍需要实施一个UI 用于选择一个冥想持续时间 从而开始冥想
我们还需要实施一个 与HealthKit相交互的类 为了让我们的app 非常快速地启动并运行 我实施了一个虚假HealthStore 它不会与HealthKit进行交互 我们稍后再实施 真正的HealthStore
那么在这里 我们正在从项目模板中 查看ContentView.swift 并且我添加了一个标题和背景
在创建app的UI时 Xcode可以在 交互式的Canvas上 给你展示UI的预览 要显示Canvas 我们要选择编辑器菜单 并点击编辑器和Canvas
Canvas将在你编辑时 创建并运行你的代码 因此它可以实时显示代码的运行结果 现在在预览中 我们可以看到欢迎标题和平静的背景 接下来我想添加一个冥想视图 因此我要创建一个新文件
我要使用 SwiftUI视图文件模板
我要把它命名为 MeditationView
现在预览给我显示了一个 完整的设备列表 但我正在创建的视图 只占据屏幕的一小部分 我可以修改预览提供器 把在Canvas上显示哪个视图 修改为只显示我正在使用 previewLayout修改器创建的视图
当我开始在修改器中输入时 Xcode会打开代码完成窗口 这会根据我所键入的文本 以及代码周边的情境 给我显示一个推荐列表
我想要的修改器就是 完成列表中的第一项 我可以按回车以接受推荐
现在Xcode在编辑器中插入了 所推荐的修改器的标志 以及占位符 从而填写余下的代码 我现在要填写 sizeThatFits
接下来我知道 MeditationView 需要与MeditationController 进行交互 因此我要添加一个属性包装器 包装 MeditationController
然后我就重新预览
如果你不确定源代码编辑器中 某个API有什么作用 你可以浏览那个API的文档 按住“选项”并点击 你要查看文档的API的标志即可
这会打开快速帮助弹出框 显示该标志的声明 及其文档
在我们继续之前 我需要提供一个 MeditationController 通过使用environmentObject 修改器实现
现在让我们开始创建这个视图 目前我们有 Hello World文本 我想把它修改为 显示冥想的剩余时间 我可以从MeditationController中 获取剩余时间
当我在编辑器中更新代码时 预览也更新了 用以反映所做的修改 现在文本看起来有点小 我可以用检查器把它变大点 我要从Xcode工具栏中的按钮 打开检查器 我要点击属性图标 然后点击我想检查的视图 在这里我可以看到 这个视图上所应用的 所有修改器的值 目前字体是继承的 我可以通过点击菜单并选择大标题 修改它
当我这样做时 预览会进行更新 并且源代码编辑器会自动添加 做出这个修改所需要的代码
在文本上方 我想显示一个按钮 可以让用户暂停并恢复冥想 你可以使用库把现成的资源 添加到你正在处理的文件中 你可以通过点击工具栏中的加号按钮 访问它
库有许多类不同的对象 包括视图、修改器和代码片段 让我们看一下代码片段类
Xcode有内置代码片段 你可以也可以添加自己的代码片段 添加你经常写的代码碎片 在这里你可以看到我所添加的 全部片段 可以让我们在这个演示中 非常快速地添加代码 但现在我要切换到视图类中 我可以键入我正在查找的视图
我可以把这个按钮 拖入源代码编辑器中 或直接拖到预览上 现在Canvas告诉我这个按钮 以及现有文本 将被添加到一个新的垂直堆栈上 当我释放按钮时 源代码编辑器将添加必要的代码 从而把按钮 和文本嵌入一个垂直堆栈中 通过添加一个VStack实现 现在我可以填写占位符 当我们轻触按钮时 我们希望切换冥想 我不想显示文本…
而是显示一个图标 显示播放或暂停
最后 我只想显示剩余时间 如果用户正在活跃地冥想的话 否则我就显示一个选择器 有预设的冥想持续时间
Xcode非常了解 我在编辑器中所写的代码的结构 并且它可以使用结构化编辑 帮助我转换和重构我的代码 如果我按住Command 并点击一个代码结构 比如文本 Xcode将给我显示行动按钮 它有许多我可以实施的不同的行动 用于转换这种代码结构 在菜单中还有跳转到目的地选项 可以浏览文本标志的快速帮助
因为我只想在特定条件下显示文本 我要点击条件式
现在我可以再次填写占位符 条件是如果冥想是活跃的 现在文件下面还有另一个占位符 我可以跳转到它 使用控制-向前/键绑定 它会帮助我非常迅速地填写缺失代码 甚至不需要触摸鼠标
这就是我想要的那个冥想视图 因此我切换到ContentView 并把它添加到ContentView中
我想把MeditationView 添加到这个VStack的底部 与另一个占位器一起
现在预览已经进行了更新 以显示我的欢迎标题 我的播放按钮 和用于选择冥想持续时间的选择器 现在我已经完成了UI 我要关闭Canvas 我要隐藏检查器 从而在编辑器中获得更多空间
在我们尝试运行app之前 我想要修改 MeditationController 使调试变得稍微简单点 在这里 我要使用迷你地图 导航到冥想计时器状态的代码段
迷你地图给我显示这个文件中 所有标记的文本标签 我可以通过点击迷你地图中的标签 导航到某一个标记
标记是一个Xcode 使用的特殊注释 用于在任意编辑器中显示代码段 在跳转栏中或迷你地图中 现在在这段代码中 我有一些计算的属性 用于表明状态 为了方便地检查状态 我要添加一个已存储的属性 叫做状态 它有其中一个可能的值 已停止、已暂停或正在运行 并且我把它默认为已停止
现在当我们更新 MeditationTimer时 我们想使用开关语句 查看计时器状态并更新控制器状态
计时器可能的值是无、已暂停 或正在运行 在Swift中 开关语句必须要面面俱到 如果不面面俱到 我会得到一个编译程序报错 要求我添加缺失的情况 请注意我已经在编辑器中得到了一个 编译程序报错 甚至没有生成我的代码 这些叫做实时问题 在你输入时发生
那么如果我点击实时问题 我得到一个修复它 问我是否想添加缺失的情况 我想 因此我要继续并点击它
现在当计时器为无时 我希望状态是已停止
现在我不想对可以被包装起来的 所有可能的值 都使用同一个设置 我想明确每一个值的情况 因此我要把这个下划线改为第一个值 即正在运行 现在我已经完成了 这个开关语句已经不再面面俱到了 因此我得到了另一个实时问题 有另一个修复它 用于添加最后剩余的情况
我不需要… 这个关联值 因此我要继续并移除它
你可能已经注意到这两个名称 正在运行和已暂停 与这个状态枚举的剩余的情况相同 我可以使用多光标编辑 来迅速地填写代码占位符 目前我有一个插入点 我可以添加另一个插入点 按住Control和Shift 并点击我要放置下一个插入点的位置
现在我有多个插入点 我可以实施任意命令 该命令将对每个插入点起作用 要了解所有可用的命令 你可以进入Xcode首选项 选择按键绑定标签 在这里你可以看到所有命令 及其按键绑定 你甚至可以把按键绑定修改为 任意你想要的组合
我现在可以给你展示其中一些 我可以选择词比如返回、 复制、跳转到下一个占位符、 键入和粘贴
现在我们已经完成了
这是要实施我们的app的基本功能 所需要的全部代码 在我们运行和调试之前 让我们回顾一下 我们在源代码编辑器中学到了什么 (演示) (总结)
我们了解了Xcode的 交互式Canvas如何 帮助我们预览app的UI 以及如何帮助我们编辑视图的外观
我们了解了代码完成 如何极大地加速了开发过程
然后我们了解了 Xcode如何从行动菜单中 帮助我们自动转换代码结构 并给代码结构添加功能
最后我们了解了实时问题和修复它 如何帮助我们修复编译程序报错 甚至在创建我们的项目之前
要获取更多关于 Swift语言的新功能 或SwiftUI框架的信息… SwiftUI框架 用于创建我们的视图 请参看Swift的新功能 以及SwiftUI入门演讲视频 现在我们已经准备运行app了 我要把舞台交给Honza 她会带我们运行并调试app (运行和调试)
谢谢Holly 大家好 我是Honza 我是Xcode的一名软件工程师
现在Prachi创建了项目 Holly添加了一些代码 接下来我们要讲 如何在模拟器和实际设备上 创建、运行和调试app 然后我们要添加一个 Swift程序包依赖关系 那可以让我们向app中添加新功能 让我们开始吧
Prachi已经讲了如何创建 并使用工具栏中的 运行按钮运行app 但我们还可以从产品菜单中实现 我们可以选择运行、测试、存档、 创建等等 那么目前我要在模拟器中运行app
这个app的创建、安装和启动 是在iPhone模拟器上 并且模拟器app会自动进入前台
这就是我们的app现在的样子
因为我们进展太快了 让我们用我们的新app 做一个快速冥想 我所要做的就是点击播放按钮 并开始一个新的三分钟冥想
那么冥想开始了 没有任何问题 但播放图标却没有发生改变 我觉得这不对 就像在音乐app中一样 我们希望当冥想暂停时显示播放图标 当冥想正在运行时显示暂停图标 因此我们要在Xcode中使用 调试器整合 帮助我们发现并修复这个错误
要运行附加有调试器的app 我不需要做任何特别的操作 因为当我刚运行app时 Xcode自动附加了调试器
因此我要让app 在模拟器中继续运行 并返回到Xcode中 我们要开始查看 MeditationView 我们通过使用跳转栏进入 MeditationView
MeditationView 用于显示 播放图标和剩余的时间标签 在这里看起来我们得到了 来自 MeditationController的 displayedIcon 属性的图片 因此要进入 MeditationController 我要命令点击 displayedIcon 并选择跳转到目的地
在这里我们在 MeditationController中 我要向displayedIcon getter属性的第二行 添加一个断点 通过点击行编号实现
因为app仍在模拟器中运行 并且计时器仍在计时 立即就击中了断点 并以绿色突显那行代码
断点通常会当击中某行特定的代码时 暂停app的执行
因此现在在Xcode窗口底部 让我把它变大点 我们有调试区 调试区顶部是调试栏 调试栏中有按钮可以控制调试器 并激活功能 比如浏览调试器 内存图形调试器等等
在它下边 左侧是变量视图 右侧是控制台
最后在Xcode窗口的左侧 我们有调试导航器 其中包含有关我们正在运行的 app的相关信息 比如它做了多少工作 它使用了多少内存 在它下边 我们有调用栈 调用栈是关于 如何调用这段代码的记录
当我在调用栈中 选择一个不同的框架时 Xcode将在这里 切换源代码编辑器、 调试器甚至是变量
我要切换回原始框架 我们要返回去尝试修复 当我们开始冥想之后 图标没有发生变更的错误
让我们看一下现在要使用哪个图标
我可以通过选择变量 并点击底部的快速查看按钮实现 在这里我们得到了一个预览
因为我们所预览的变量是个图片 我们实际上得到了一个渲染版 但在Xcode中损坏了
快速查看预览支持图片、颜色、视图 以及实施了调试快速查看对象方法的 任意自定义对象
因此在预览中我们可以看到 我们仍显示播放图标 即使冥想已经正在运行中了
因此我想是否因为 MeditationController 处于错误的状态 为了找到答案 我要扩展引用MeditationController的 self变量 我们在这里进行调试并显示属性 其中一个是状态属性 它告诉我们 MeditationController 是正在运行状态
这正是我所期待的 那意味着所显示的图标 getter属性 在选择要显示的图标时 并没有考虑到 MeditationController的状态 因此为了修复这个问题 我要检查MeditationController 是否正在运行 如果是 我们将显示… 我们将显示暂停图标
否则我们就显示播放图标 现在因为我不再需要断点了 我要移除它 我把它拖拽出来并释放它 因为我们刚刚修改了代码 我要停止app并在此点击运行按钮 这会重新编译项目 在模拟器中 重新安装并重新启动app 这一次 当我开始新的冥想时 我们可以看到图标从播放改成了暂停 错误已经修复了 太棒了
我们要暂时停止app
并隐藏调试区
我们已经在模拟器中运行了app 这是一种快速迭代 我们的代码的好方法 但我还想在真实设备上 安装我的app 这样我就可以随时随地开始冥想了
首先 要运行… 要在已连接的设备上 安装并运行app 我们需要用Apple ID 登录到Xcode中
我们首先要进入Xcode首选项
选择一个账户 然后添加新账户
我们选择Apple ID
输入用户名和密码
然后我们就用Apple ID 登录了Xcode 接下来关闭窗口 进入项目导航器并选择项目
在这里我们要选择app目标 并进入签名&权限标签
在这里我们可以管理代码签名和权限 权限可以让我们声明我们的app 所需要的权限 在我们的例子中 我们要访问HealthKit数据 从而能写入用户在我们的app中 所实施的冥想 但同时也读取用户在其它app上 所实施的冥想 从而我们可以给他们显示 他们所有冥想行为的统计信息
因此我们要添加一个新权限
搜索健康 并选择HealthKit权限
接下来我把这个iPhone 连接到我的Mac
我要把iPhone作为运行目的地
我要点击运行 现在已经针对该设备进行了 app的创建 并在该设备上进行了安装和启动 从而你可以看到屏幕上正在进行什么 我们要用QuickTime播放器 它可以让我把iPhone屏幕 传回Mac
我们现在正在真正的iPhone上 运行Mind 我可以拔下这台手机 随时随地都可以开始冥想 现在… 让我停止app…
把目的地切换回模拟器
当你想查找关于设备的更多信息时 你可以进入窗口、设备、模拟器 我们可以在模拟器中看到名称、 类型以及设备的OS版本 并且我们还可以看到已安装的app 但同时我们其实可以配置设备 通过Wi-Fi连接Mac 那样我就不需要用USB线 把手机插到Mac上了 但我仍然可以在手机上创建、 运行并调试app
现在我们已经成功地在模拟器上 和设备上运行了我们的app 并且我们甚至还使用调试器 修复了一个错误 让我们讲一下如何向app中 添加更多功能
我希望我们的app可以显示 关于用户的冥想的统计信息 比如他们进行了多少次冥想、 平均持续时间是多少等等 但计算统计信息 并不只是我们的冥想app的一个 特定问题 我们创建了一个Swift程序包 叫做QuickStats 它可以帮助我们解决那个问题
从根本上说 Swift程序包是一个文件夹 其中包含你可以用于创建产品的 清单文件和源文件 比如我们的QuickStats库
要把项目添加到我们的程序包中 我要进入项目编辑器 并选择顶部的Swift程序包 在这里我要向我们的项目中 添加一个新的程序包 因为Prachi用我们的账户 登录了GitHub 我们可以看到我们的账户所收藏的 所有资源库 QuickStats就位于顶部 我要选择它
点击下一步 我们要使用版本1 看起来不错
我们要在这里确认 我们的app已链接 QuickStats库
我要点击完成 现在Xcode在 后台管理程序包的获取 在项目导航器中 有一个Swift程序包 依赖关系部分 我可以浏览程序包的资源 这样可以很好地理解 程序包是如何在底层运作的
现在 在我把舞台交还给Holly 把程序包整合到我们的项目中去之前 让我么快速回顾一下
(演示)
我们了解了如何在模拟器上 运行并调试app 我们还在实际设备上运行了 我们的app
然后我们向项目中添加了 Swift程序包依赖关系 那可以让我们向app中添加功能
(总结)
这些是与这个演示中所讨论的话题 相关的演讲 接下来欢迎Holly返回舞台 谢谢
(使用程序包和框架)
谢谢Honza
在这个演示中 我们将了解如何在我们的项目中使用 QuickStats程序包 然后我们将了解如何重构我们的项目 通过把模型代码移动到框架中实现
先让我们返回到Xcode中
现在我们已经添加了 QuickStats程序包 我们可以向我们的代码中导入程序包 并开始使用它的公共API Honza刚才提到了 我们想在ContentView中 给用户显示一些 与他们的冥想会话相关的统计信息
我们要使用快速打开跳转回 ContentView.swift 你可以在文件菜单下找到快速打开
在快速打开中 我可以输入任意类型名称、 方法名称、导航目的地名称 我要输入Contentview 并按回车
我要做的第一件事就是导入 QuickStats
现在我们已经准备好开始使用 这个程序包中的API了
我要在从一个代码片段中 在contentView下方添加一些代码 那会实施一个 StatisticsView 它接受一组冥想会话 并用QuickStats API 显示关于这些会话的统计信息
因为我有访问 全部程序包源代码的权限 我可以跳转到源代码实施 来了解它是如何运作的 那么如果我命令点击 QuickStats.averageDuration 并选择跳转到目的地 我现在正在查看这个方法的实际实施
我可以看到 文件位于项目导航器的哪个位置 通过点击导航、 在项目导航器中显示来实现 现在我们可以看到 我们正在程序包源代码中 我可以导航回之前的文件 通过使用调专栏中的 编辑器历史按钮实现
现在让我们向ContentView中 添加StatisticsView 但在此之前我想显示Canvas
我要放大 这样我们就能看到完整的设备
我要在占位器下添加StatisticsView
它接受一组会话 我们可以从MeditationController中 获得这组会话
现在我们可以看到StatisticsView 位于ContentView底部 现在我已经完成了UI 我再次关闭Canvas
现在我们想开始编写模型的单元测试 为了让它更简单点 我们要把模型代码移到一个 可测试的单元框架中 我可以选择使用Swift程序包 但我只想与我的团队共享这段代码 因此我要选择框架来代替程序包 我们需要创建一个新目标…
并且我可以使用过滤器来搜索框架
我要把这个框架命名为 MindKit
我想确保在单元测试内 勾选这个复选框 从而当我创建框架时 自动生成单元测试目标
现在在我迁移代码之前 我想把MindKit导入到 我所了解的需要它的所有文件中 我知道我要迁移 HealthStore.swift 这个文件有两个公共类型 在整个项目中都要使用 我要使用查找导航器 来查找要在哪里使用这两个类型 我要切换到查找导航器
查找导航器可以让我搜索整个项目 搜索文本、标志引用、正则表达式 等等 目前我想查找正则表达式…
我想搜索… HealthSession 或HealthStore 然后我按回车查看结果
我知道我要把 HealthStore.swift 和HealthStoreFactory.swift 迁移到MindKit框架中 我可以通过点击公开三角形查看结果
现在我要导航到每一个文件 并添加导入
因此我要跳转到文件的顶部…
添加导入 最后我们在ContentView.swift中 也需要它
现在我们已经准备好迁移文件了 因此我要切换回项目导航器 我提到过 我想迁移 HealthStore.swift 但我还想迁移 HealthStoreFactory.swift 我可以在项目导航器中选择多个文件 通过按住Command并点击 我想要选择的其它文件即可实现 然后我可以把这些选中的文件 拖动到MindKit群组中
当我这样做时 Xcode会自动更新 这些文件的目标成员 我们可以对此进行验证 通过显示检查器…
我们看到编辑器中打开了 文件的目标成员 即HealthStore.swift 它现在是MindKit框架的目标 而不是Mind app的目标了
现在我还没有忘记我们仍需要实施 与HealthKit相交互的 HealthStore 我们现在就做 以便我们可以开始把真正的健康数据 整合到我们的app中 我要做的第一件事 就是导入HealthKit
现在我之前从未用过 HealthKit 因此我想阅读一下文档 我可以直接在Xcode中阅读文档 打开开发者文档窗口即可实现 你可以在帮助菜单中找到文档
在这里你可以搜索来自SDK的框架 搜索特定API 或搜索编程话题 比如请求访问健康数据 因此在这里 我要搜索HealthKit
现在我可以浏览 整个框架的所有文档了 这在离线时也可用 幸运的是我已经把我所需要的 全部代码都放在了一个代码片段中 我要把它添加到文件末端
在我们开始编写单元测试之前 我想在MindKit框架中添加 我自己的API文档 从HealthStore协议开始 我可以使用一种叫做文档注释的 特殊注释实现 Xcode知道如何给声明生成 文档注释模板 这个功能在行动菜单中可用 因此我要命令点击 我想要给它添加文档的第一个API 即requestAccess 然后我要选择添加文档
现在Xcode已经插入了一个 文档注释模板 其中有占位符用于方法描述 还有它所接受的参数的描述
这个方法要求…
用户权限… 能访问冥想会话
完成参数是请求完成时 要执行的一个闭包
我知道这个方法可以异步执行 并且我想添加一个特殊注释… 用于记录这一点 我可以使用一个特殊的项目符号 来实现
现在我可以添加那个注释
现在我已经写好了文档 我可以在快速帮助中浏览它
再一次我们可以打开快速帮助弹出框 可以选择点击 我们想要浏览的文档的标志 现在我们可以看到我们刚写的描述 以及我们写的参数的描述 这在任意请求访问中都可用
要获取更多关于编写和记录 你自己的API的信息 请参看Swift API设计指南 在swift.org上可以找到它 (总结) 在这个演示中 我们了解了如何使用和导航 来自Swift程序包中的代码
我们讲了在项目中创建一个 新的框架目标 以及把现有代码迁移到那个框架中
接下来我们了解了 Xcode开发者文档窗口 最后 我们了解了如何通过文档注释 编写我们自己的文档
现在我要把舞台交给Honza 她会与大家分享测试和发布 (测试和发布) 谢谢Holly 在这部分中 我们要讲如何在Xcode中 测试我们的代码 以及一旦我们准备好发布后 要如何发布我们的app
现在因为你的app运行得不错 我们需要确保它能继续适当地运行 增加我们对app品质的自信心的 一个好方式 是通过自动化测试
我们要给我们的app 编写两大类高层级测试… 单元测试和UI测试
单元测试可以确保单一组件 比如我们的HealthStore 能正常运行通过给它特定的输入 并验证输出是否与我们的预期相匹配 来实现
另一方面的UI测试 可以确保所有组件 都进行了正确集成并且 app从用户的角度来说运行无误
让我们返回到Xcode中
Holly已经创建了 MindKit框架的单元测试目标 叫做MindKitTests 但我们仍需要把它添加到 我们的测试计划中 测试计划是一个文件…一个资源库 描述了如何创建和运行测试
查看我们的方案使用了 哪个测试计划的方式是… 点击方案并点击编辑方案
我们要切换到测试行动 在这里我们可以看到我们的方案 所采用的所有测试计划 只有一个 即默认测试计划 我们要跳转到它 点击测试计划的名字旁边的跳转箭头 即可跳转
测试计划编辑器显示了 它所使用的测试目标 这里我们已经有了UI测试目标 我们稍后再编写代码 但我们仍需要添加单元测试的目标
我们通过点击底部的加号按钮 并选择 MindKitTests实现
现在让我们实际编写我们的 单元测试代码
我要给HealthStore 编写一些单元测试 我现在要做的就是控制点击 MindKitTests群组 并点击新文件
我将使用单元测试文件模板…
并把文件测试命名为 HealthStore
看起来还不错
在这里我们要做的第一件事就是 导入MindKit 因为这是代码所在的地方
为了既测试MindKit框架 的公共界面 也测试它的内部界面 我们要在导入中添加可测试的关键字
接下来我要向我们的类中
添加两个测试 第一个在我们保存冥想之后进行验证 我们可以马上取回它
第二个测试可以确保 我们可以实际上请求访问 读取数据
我要通过进入产品、测试 来运行这些测试
现在这些测试是针对模拟器创建的 并且要在iPhone XR 模拟器上运行
现在测试已经完成 我们实际上可以在源代码编辑器中的 测试名称旁边看到 测试菱形 表明两个测试都成功了
很好 现在我们还可以在测试导航器中 看到测试等级
我们给HealthStore 添加了一些单元测试 但我们想确保app的UI也没问题 因此我们要向UI测试中 添加一些代码
我要跳转到现有的 MindUITests类 通过在测试导航器中选中它进行跳转 在这里我们要添加… UI测试代码
那会启动我们的app 开始一个新的冥想 数秒钟后 它会暂停冥想 然后最后它验证剩余时间标签 是否显示我们的预期值
因此我要再次运行我们的测试
这一次我要把模拟器带到前台来 以便我们可以观看UI测试运行
那么app已经启动 并已经开始新的冥想了 数秒钟之后 它开始暂停冥想 然后终止app 接下来我们还看到单元测试 启动了app一小段时间
现在看起来有些测试失败了 要了解具体发生了什么 我们要进入报告导航器 通过点击最右侧的导航器按钮 进入报告导航器
在这里 我选择顶部的测试行动 即最近一次的测试行动
然后我们就得到了测试报告
在这里我可以看到刚添加的UI测试 被标记为红色 意味着它失败了 要了解具体发生了什么 我要公开测试… 并深究失败的活动 从而了解失败的搜索结果显示 02:56不等于2:56
现在这开始变得有意义了 但要真正理解当失败发生时 屏幕上发生了什么 我可以公开失败自身 从而显示自动截图 我可以预览点击图标 在这里我可以清楚地看到 剩余计时器标签显示 02:56而不是 测试断言的2:56
我要关闭预览 并跳转回测试资源 可以通过点击 测试名称旁边的跳转箭头实现
在这里我们要修复这个断言 通过添加、删除零来实现
现在我要重新运行这一个测试 可以通过点击 测试名称旁边的测试菱形实现
再一次… 我们可以看到app已经启动 并开始新的冥想 数秒钟之后它暂停了 然后app被执行了 这一次… 终止了 抱歉 这一次 我们实际上可以看到测试菱形 表明测试成功 太棒了
终于 我们现在有了 一个功能性app 我们希望很多人能使用它
要在App Store或 TestFlight上发布app TestFlight是Apple beta测试服务 我们需实施存档
为此我们首先选择通用的 iOS设备运行目的地 然后选择产品存档 这会创建发布配置 并生成一个存档 我们可以用于发布我们的app
当它完成后 它会自动打开管理器 在这里当我们选择存档时 我们可以点击发布app 我们会进入把app 直接从Xcode提交到 Apple的流程
请注意要把app部署到TestFlight 或App Store 你需要注册与你的Apple ID 相关联的开发者账户
一旦app成功上传
你可以使用App Store Connect网站对它进行管理 这样你可以要求你的朋友和家人 或你的同事 使用TestFlight 下载你的app 并最终上线… 也在App Store上线
在这个演示中 我们从给app创建单元测试 和UI测试开始 然后我们了解了如何编辑 我们的测试计划 以及如何使用测试报告 来诊断测试失败 然后我们创建了存档 并讨论了如何使用管理器 把我们的app上传到TestFlight 或App Store
要了解更多关于这些话题的信息 请参考这些演讲
让我们回顾一下在过去的一小时内 我们都学到了什么内容
今天我们了解了从零创建app的 整个过程
Prachi创建了我们的项目 并介绍了Xcode UI 然后Holly向app中 添加了代码 使用源代码编辑器功能让添加 代码的过程变得非常流畅和有趣
然后我上台来讲了在模拟器和设备上 进行运行和调试 并且我们向项目中添加了一个 Swift程序包
然后Holly上台 来整合了Swift程序包 并把我们的一些代码 拆分到一个框架中
最后我们刚了解了如何 在Xcode中使用测试整合 以及如何把app发布到App Store 或TestFlight
要获取关于本场演讲的更多信息 请参看这个链接 如果你有任何疑问 在本场演讲结束后有一场演讲 (更多信息请参看 developer.apple.com/wwdc19/404) 祝你们一周愉快 非常感谢
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。