SwiftUI:使用UserDefaults存储用户设置

译自 Storing user settings with UserDefaults

可以说,网站和应用程序之间的最大区别在于它们对用户数据的处理方式。一方面,网站会通过跟踪Cookie,投放营销广告并查看我们的行为来尽最大努力侵犯我们的隐私,因此很少有用户希望通过更多数据来信任他们。另一方面,我们非常希望应用程序能够存储我们的数据,而如果每个应用程序启动时都弹出GDPR的“我们可以为您提供Cookie吗?”的提示,这会很奇怪。

因此,iOS为我们提供了几种读取和写入用户数据的方式也就不足为奇了,我想在这里看看其中两种。

第一个称为UserDefaults,它允许我们存储直接附加到我们应用程序的少量用户数据。“少量”没有具体的限制,但是请记住,存储在UserDefaults中的所有内容都会在应用启动时自动加载——如果在其中存储很多,则应用启动速度会变慢。给你至少一个建议,您应该在其中存储不超过512KB的内容。

提示:##如果您要考虑“ 512KB?那能存储多少数据?”让我给您一个大概的估计:它的文字数量与您迄今为止在本书中阅读的所有章节一样多。

UserDefaults非常适合存储用户设置和其他重要数据——您可能会跟踪用户上次启动该应用程序的时间,他们上次阅读的新闻报道或其他被动收集的信息。

但是,有一个陷阱:它是字符串类型。这有点像个玩笑的名字,因为“强类型”是指像Swift这样的类型安全语言,其中每个常量和变量都具有特定类型(例如IntString),而“字符串类型”则是指代码会在某些地方使用字符串,那是可能会引起问题的地方。

让我们看一些代码。这是一个带有按钮的视图,其中显示了点击次数,并且每次点击按钮时都会递增计数:

struct ContentView: View {
    @State private var tapCount = 0

    var body: some View {
        Button("Tap count: \(tapCount)") {
            self.tapCount += 1
        }
    }
}

因为这显然是一个非常重要的应用程序,所以我们希望保存用户的点击次数,因此,当他们将来再次使用该应用程序时,可以从上次停止的地方继续。

好吧,做到这一点只需要做两个改变。首先,只要有变化,就需要将计数写入UserDefaults,因此请将其添加到self.tapCount + = 1行之后:

UserDefaults.standard.set(self.tapCount, forKey: "Tap")

在那一行代码中,您可以看到三件事:

  1. 我们需要使用UserDefaults.standard。这是附加到我们应用程序的UserDefaults的内置实例,但是在更高级的应用程序中,您可以创建自己的实例。例如,如果要在多个应用程序扩展中共享默认设置,则可以创建自己的UserDefaults实例。
  2. 有一个set()方法可以接受任何类型的数据——整数,布尔值,字符串等。
  3. 我们在此数据上附加一个字符串名称作为存储Key,在本例中为“Tap”。该Key与常规Swift字符串一样区分大小写,并且很重要——我们需要使用相同的键来从UserDefaults中读取数据。

说回读数据,而不是从tapCount设置为0开始,我们应该这样使它从UserDefaults中读回值:

@State private var tapCount = UserDefaults.standard.integer(forKey: "Tap")

注意它如何使用完全相同的键名,以确保它读取相同的整数值。

继续并尝试一下该应用程序,你看到了什么——您应该能够轻按几次按钮,返回Xcode,再次运行该应用程序,然后看到上一次的数字。

在该代码中看不到两件事,但两者都很重要。首先,如果我们没有设置“Tap”键会怎样?第一次运行应用程序时会是这种情况,但是正如您刚刚看到的那样,它可以正常工作——如果找不到密钥,它将返回0。

有时使用默认值(例如0)会有所帮助,但有时可能会造成混淆。例如,使用布尔值时,如果boolean(forKey :)找不到您要的键,则返回false但这是您自己设置的值,还是意味着根本没有值?

其次,iOS需要一些时间才能将您的数据写入永久存储——将更改实际保存到设备中。他们不会立即写更新,因为您可能连续几次进行更新,所以他们会等待一段时间,然后立即写出所有更改。我们不知道还有多少时间,但是应该花几秒钟的时间。

因此,如果您点击该按钮,然后从Xcode快速重新启动该应用程序,则会发现最近的点击计数未被保存。过去曾经有一种强制立即写入更新的方法,但是这毫无意义——同步线程在保存大量数据的时候退出APP仍然可能导致数据丢失。

SwiftUI:使用onDelete() 删除项目 Hacking with iOS: SwiftUI Edition 使用Codable归档Swift对象

赏我一个赞吧~~~

你可能感兴趣的:(SwiftUI:使用UserDefaults存储用户设置)