Skip to content

第52天 项目 10 第四部分

我们在这里开展的每个新项目,都会先单独向你介绍新概念,然后再结合实际应用场景进行讲解。这样做的目的是,在不同情境下两次展示同一内容,能帮助你更深刻地将其存入长期记忆。

但如今,我们的应用已经完成,是时候进入长期学习过程中另一个重要环节了:检验你的记忆成果,并通过一些挑战帮助你进一步提升。无论你是否愿意,这一步都至关重要——正如宇航员约翰·杨曾经说过的:“进步最大的敌人,是自以为懂了的错觉。”

请相信我:确定自己理解某件事,远胜于认为自己理解它。这就是我不断向你强调基础知识的原因:我希望你对Form的使用熟悉到几乎能自己编写这门课程的程度;我希望你看到Codable时,能准确明白它的含义以及背后的工作原理,再也不会觉得它带有某种“魔力”。

我们在这里打下的所有基础,都将陪伴你多年。这意味着,你在此之上构建的一切——未来学到的知识、创造的成果——都不会建立在对某段内容一知半解的基础上,而是能让你拥有真正持久的信心。

今天,你应当完成第10个项目的总结章节,完成相关复习,然后攻克所有三个挑战。

  • 纸杯蛋糕店(Cupcake Corner):总结
  • 第10个项目复习:纸杯蛋糕店(Cupcake Corner)

纸杯蛋糕店(Cupcake Corner):总结

作者:Paul Hudson 2024年4月11日

希望这个项目能让你学会如何运用已掌握的技能——SwiftUI中的表单(Form)、选择器(Picker)、步进器(Stepper)和导航功能——构建一个能将用户所有数据发送到服务器并处理响应的应用。

你现在可能还没意识到,这个项目中学到的技能,对绝大多数iOS开发者来说都是最重要的:收集用户数据、发送到服务器并处理响应,这一流程可能占据了现有半数以上非简单应用的核心功能。诚然,发送的数据内容以及更新用户界面(UI)的方式会有很大差异,但背后的核心概念是完全相同的。

复习所学内容

任何人都能看完一个教程,但要记住所学内容,就需要付出实际努力了。我的职责是确保你能从这些教程中收获尽可能多的知识,完成后面的练习题可以帮助你检验学习成果。

挑战

学习编程最好的方法之一,就是尽可能多地自己编写代码。因此,我为你准备了三种扩展这个应用的方式,确保你能完全理解其中的原理。

  1. 目前,我们的地址字段只要包含任何内容(即便是纯空格),就会被视为有效。请改进验证逻辑,确保纯空格字符串被判定为无效。
  2. 如果调用placeOrder()失败(例如没有网络连接),请向用户显示一条提示性弹窗。要测试这一点,可以尝试注释掉代码中的request.httpMethod = "POST"这一行,这样就能强制让请求失败。
  3. 这是一个更有挑战性的任务:尝试更新Order类,使其能将用户的配送地址等数据保存到UserDefaults中。这需要一些思考,因为@AppStorage在此处无法使用,而且你会发现,使用 getter 和 setter 会对Codable支持造成问题。你能找到一个折中方案吗?

【练习题】纸杯蛋糕店(Cupcake Corner)

问题1/12:以下哪些表述是正确的?

  • 选项1:如果一个Swift结构体仅由符合Codable协议的属性组成,那么整个结构体本身也可以符合Codable协议。
  • 选项2:当disabled()修饰符的条件为false时,它所附加的视图将停止响应用户交互。

问题2/12:以下哪些表述是正确的?

  • 选项1:我们可以创建一个枚举来为某个类型定义特定的编码键(coding keys),但该枚举的名称必须是CodingKeys
  • 选项2:异步函数在完成工作的过程中可以暂停(sleep)。

问题3/12:以下哪些表述是正确的?

  • 选项1:Swift的数组使用泛型(generics)。
  • 选项2:我们可以使用“或”(OR)操作符检查两个布尔值中是否有一个或两个为true,例如booleanA OR booleanB

问题4/12:以下哪些表述是正确的?

  • 选项1@Observable宏仅适用于类(class)。
  • 选项2disabled()修饰符可以读取任何类型的属性,但不能与方法(method)一起使用。

问题5/12:以下哪些表述是正确的?

  • 选项1:如果异步函数不会暂停(sleep),调用时就不需要使用await
  • 选项2:通过字符串创建URL时,返回的是可选类型(optional)的URL

问题6/12:以下哪些表述是正确的?

  • 选项1:字符串(String)、整数(Int)和布尔值(Bool)本身已符合Codable协议。
  • 选项2URLRequest可以使用共享队列(shared queue)从互联网获取数据。

问题7/12:以下哪些表述是正确的?

  • 选项1CodingKey协议允许我们通过枚举案例(enum case)列出想要归档(archive)和反归档(unarchive)的属性。
  • 选项2:所有使用@Observable的类都会自动符合Codable协议。

问题8/12:以下哪些表述是正确的?

  • 选项1:我们可以在任何时候使用Task { … }创建一个新任务。
  • 选项2:MIME类型是由喜欢假装自己被困在箱子里的无声戏剧演员发明的。

问题9/12:以下哪些表述是正确的?

  • 选项1:通常更倾向于使用URLSessionshared属性,而不是自己创建一个新的会话(session)。
  • 选项2:如果可以选择,采用“字符串类型化”(stringly typed)的API总是更优的选择。

问题10/12:以下哪些表述是正确的?

  • 选项1:HTTP的GET请求用于读取数据,POST请求用于写入数据。
  • 选项2:HTTP的POST请求用于读取数据,GET请求用于写入数据。

问题11/12:以下哪些表述是正确的?

  • 选项1:初始化器(initializer)必须始终接受与类中属性匹配的参数。
  • 选项2:当URLSession的下载任务完成时,会返回下载的数据以及所有附加的元数据(metadata)。

问题12/12:以下哪些表述是正确的?

  • 选项1:异步函数调用总会有一定时间的暂停(sleep)。
  • 选项2Codable协议实际上是Encodable协议和Decodable协议的组合。

本站使用 VitePress 制作