SwiftUI学习100天(Day71 - 项目 14,第四部分)

原创链接:https://www.hackingwithswift.com/100/swiftui
以下内容仅供学习参考:

达到这一点需要一段时间,但今天你将使用非常少的代码来实现一些应用程序功能 - 这应该是相对容易的一天!
更具体地说,你将了解如何根据枚举的值显示不同的 UI,如何为我们从网络请求中获取的某些数据添加自定义Comparable
一致性,等等。这里有一些重要的技术,但它们确实让我们的应用程序更上一层楼。
如果你觉得这很难,那么你最好记住 William Eardley 曾经说过的话:“雄心壮志是通往成功的道路,坚持是你到达的工具。” 你在开始这门课程时表现出了雄心壮志,现在你已经到了第 71 天,你显然也表现出了毅力!
今天你有两个主题需要完成,其中你将进行网络调用、添加Comparable
一致性等等。

从维基百科下载数据
为了使整个应用程序更有用,我们将修改EditView
屏幕以显示有趣的地方。毕竟,如果游览伦敦在你的旅行清单上,你可能需要一些关于附近景点的建议。这听起来很难,但实际上我们可以使用 GPS 坐标查询维基百科,它会发回附近地点的列表。
维基百科的 API 以精确的格式发回 JSON 数据,因此我们需要做一些工作来定义Codable
能够存储所有数据的结构。结构是这样的:
主要结果将我们的查询结果包含在一个名为“query”的键中。
查询内部是一个“页面”字典,页面 ID 作为键,维基百科页面本身作为值。
每个页面都有很多信息,包括它的坐标、标题、术语等等。
我们可以使用三个链接的结构来表示,因此创建一个名为 Result.swift 的新 Swift 文件并为其提供以下内容:
我们将使用它来存储我们从维基百科获取的数据,然后立即在我们的 UI 中显示它。然而,我们需要在抓取发生时显示一些东西——一个显示“正在加载”或类似内容的文本视图应该可以解决问题。
这意味着根据当前加载状态有条件地显示不同的 UI,这意味着定义一个实际存储当前加载状态的枚举,否则我们不知道要显示什么。
首先将此嵌套枚举添加到EditView
:
这些涵盖了我们代表网络请求所需的所有状态。
接下来,我们将向 EditView
中添加两个属性
:一个表示加载状态,一个用于在获取完成后存储一组维基百科页面。所以,现在添加这两个:
在我们处理网络请求本身之前,我们还有最后一项简单的工作要做:添加到我们Form
的新部分以显示页面(如果已加载)或状态文本视图。我们可以将这些if/else if
条件或switch
语句直接放入Section
,SwiftUI 会计算出来。
因此,将此部分放在现有部分下方:
提示:请注意我们如何使用+
将文本视图一起添加?这让我们可以创建更大的文本视图来混合和匹配不同类型的格式。“此处的页面描述”只是暂时的——我们很快就会更换它。
现在是真正将所有这些结合在一起的部分:我们需要从维基百科获取一些数据,将其解码为Result
,将其页面分配给我们的pages
属性,然后设置loadingState
为.loaded
. 如果获取失败,我们将设置loadingState
为.failed
,SwiftUI 将加载适当的 UI。
警告:我们需要加载的维基百科 URL 非常长,因此与其尝试输入它,不如从文本或我的 GitHub gist 中复制粘贴:http: //bit.ly/swiftwiki。
将此方法添加到EditView
:
该请求应在视图出现后立即开始,因此task()
在现有修饰符之后添加此toolbar()
修饰符:
现在继续并再次运行该应用程序——你会发现当你放下图钉时,我们的EditView
屏幕会向上滑动并向你显示附近的所有地点。好的!



排序维基百科结果
维基百科的结果返回给我们的顺序看起来可能是随机的,但实际上是根据其内部页面 ID 排序的。但这对我们没有帮助,这就是我们使用自定义闭包对结果进行排序的原因。
很多时候,使用自定义排序功能正是你所需要的,但通常情况下,你的数据有一个自然顺序——可能首先显示最新的新闻故事,或者首先显示联系人的姓氏,等等。所以,而不是只需提供一个内联闭包给sorted()
,
我们就可以让我们的Page
结构符合Comparable
. 这实际上很容易做到,因为我们已经编写了排序代码——只需将它移动到我们的Page
结构中即可。
因此,首先将结构的定义修改为Page
:
如果你还记得,符合Comparable
只有一个要求:我们必须实现一个<
函数,它接受我们结构类型的两个参数,如果第一个应该在第二个之前排序,则返回 true。在这种情况下,我们可以直接将测试传递到title
字符串上,所以现在将此方法添加到Page
结构中:
现在 Swift 知道如何对页面进行排序,它会自动为我们提供sorted()
页面数组上的无参数方法。这意味着当我们设置fetchNearbyPlaces()
的
self.pages
时
我们现在可以添加sorted()
到末尾,如下所示:
在完成此屏幕之前,我们需要Text("Page description here")
用真实的东西替换视图。维基百科的 JSON 数据确实包含一个描述,但它被埋没了:terms
字典可能不在那里,如果它在那里它可能没有description
键,如果它有键它可能是一个description
空数组而不是包含一些文本的数组里面。
我们不希望这种混乱困扰我们的 SwiftUI 代码,因此最好的做法还是制作一个计算属性,如果存在则返回描述,否则返回固定字符串。将其添加到Page
结构中以完成它:
完成后,你可以替换Text("Page description here")
为:
这就完成了EditView
——它允许我们编辑注释视图的两个属性,它从维基百科下载和排序数据,它根据网络请求的进行方式显示不同的用户界面,它甚至仔细查看维基百科内容来决定什么可以是显示。


