如何在 Swift 应用程序中保存本地数据?

我目前正在开发一个用 Swift 开发的 iOS 应用程序,我需要在设备上存储一些用户创建的内容,但是我似乎找不到一个简单快速的方法来在设备上存储/接收用户的内容。

有人能解释一下如何存储和访问本地存储吗?

其思想是在用户执行操作时存储数据,并在应用程序启动时接收数据。

202601 次浏览

存储几个字符串或公共类型的最简单解决方案是 用户默认值

UserDefault 类提供了访问浮点数、双精度数、整数、布尔值和 URL 等常见类型的便利方法。

UserDefaults允许我们根据自己选择的密钥来存储对象。把这些密钥存储在可访问的地方是个好主意,这样我们就可以重用它们。

钥匙

struct DefaultsKeys {
static let keyOne = "firstStringKey"
static let keyTwo = "secondStringKey"
}

设定

let defaults = UserDefaults.standard
defaults.set("Some String Value", forKey: DefaultsKeys.keyOne)
defaults.set("Another String Value", forKey: DefaultsKeys.keyTwo)

得到

let defaults = UserDefaults.standard
if let stringOne = defaults.string(forKey: DefaultsKeys.keyOne) {
print(stringOne) // Some String Value
}
if let stringTwo = defaults.string(forKey: DefaultsKeys.keyTwo) {
print(stringTwo) // Another String Value
}

Swift 2.0

在 Swift 2.0中,UserDefaults被称为 NSUserDefaults,setter 和 getter 的命名略有不同:

设定

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Some String Value", forKey: DefaultsKeys.keyOne)
defaults.setObject("Another String Value", forKey: DefaultsKeys.keyTwo)

得到

let defaults = NSUserDefaults.standardUserDefaults()
if let stringOne = defaults.stringForKey(DefaultsKeys.keyOne) {
print(stringOne) // Some String Value
}
if let stringTwo = defaults.stringForKey(DefaultsKeys.keyTwo) {
print(stringTwo) // Another String Value
}

对于任何比次要配置更严重的情况,您应该考虑使用更健壮的持久存储:

好的,所以感谢 @ bploat和链接到 http://www.codingexplorer.com/nsuserdefaults-a-swift-introduction/

我发现对于一些基本的字符串存储来说,答案非常简单。

let defaults = NSUserDefaults.standardUserDefaults()


// Store
defaults.setObject("theGreatestName", forKey: "username")


// Receive
if let name = defaults.stringForKey("username")
{
print(name)
// Will output "theGreatestName"
}

我总结在这里 http://ridewing.se/blog/save-local-data-in-swift/

他们说使用 NSU 默认值

当我第一次实现长期(应用程序关闭后)数据存储时,我在线阅读的所有内容都指向 NSUserDefault。然而,我想要存储一本字典,尽管可能,但这被证明是一件痛苦的事情。我花了好几个小时试图消除打字错误。

NSUserDefault 在功能上也是有限的

进一步的阅读揭示了 NSUserDefault 的读/写是如何真正迫使应用程序同时读/写所有内容或者什么都不读,所以效率不高。然后我发现恢复数组并不简单。我意识到,如果存储的字符串或布尔值不止一个,那么 NSUserDefault 实际上并不理想。

它也是不可扩展的。如果您正在学习如何编写代码,请学习可伸缩的方法。只有在存储与首选项相关的简单字符串或布尔值时才使用 NSUserDefault。使用核心数据存储数组和其他数据,没有他们说的那么难。从小事做起。

更新: 此外,如果你添加了苹果手表的支持,还有另一个潜在的考虑。您的应用程序的 NSUserDefault 现在自动发送到手表扩展。

使用核心数据

因此,我忽略了关于核心数据是一个更困难的解决方案的警告,并开始阅读。不到三个小时,我就把它修好了。我有我的表数组被保存在核心数据和重新加载的数据后,打开应用程序回来了!教程代码很容易调整,我可以让它存储标题和细节数组,只需要一点额外的实验。

因此,对于那些正在努力解决 NSUserDefault 类型问题或者需要不只是存储字符串的人来说,可以考虑花一两个小时来处理核心数据。

下面是我读过的教程:

Http://www.raywenderlich.com/85578/first-core-data-app-using-swift

如果您没有选中“ Core Data”

如果你在创建应用程序时没有检查“核心数据”,你可以在之后添加它,只需要5分钟:

Http://craig24.com/2014/12/how-to-add-core-data-to-an-existing-swift-project-in-xcode/

Http://blog.zeityer.com/post/119012600864/adding-core-data-to-an-existing-swift-project

如何从核心数据列表中删除

从 Coredata Swift 删除数据

对于对于 NSUserDefaults来说过于复杂的数据,使用 NSCoding 和 NSKeyedArchiver是另一个很好的选择,但是对于 CoreData 来说就太过了。它还为您提供了更明确地管理文件结构的机会,如果您希望使用加密,这非常好。

为了 Swift 3

UserDefaults.standard.setValue(token, forKey: "user_auth_token")
print("\(UserDefaults.standard.value(forKey: "user_auth_token")!)")

Swift 3.0

Setter: 本地存储

let authtoken = "12345"
// Userdefaults helps to store session data locally
let defaults = UserDefaults.standard
defaults.set(authtoken, forKey: "authtoken")


defaults.synchronize()

本地存储

 if UserDefaults.standard.string(forKey: "authtoken") != nil {


//perform your task on success }

对于那些由于某些原因不喜欢处理 UserDefault 的用户,还有另一个选项—— NSKeyedArchiver & NSKeyedUnarchive。它有助于使用归档器将对象保存到文件中,并将归档文件加载到原始对象。

// To archive object,
let mutableData: NSMutableData = NSMutableData()
let archiver: NSKeyedArchiver = NSKeyedArchiver(forWritingWith: mutableData)
archiver.encode(object, forKey: key)
archiver.finishEncoding()
return mutableData.write(toFile: path, atomically: true)


// To unarchive objects,
if let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
let object = unarchiver.decodeObject(forKey: key)
}

我已经编写了一个简单的实用程序,用于在本地存储中保存/加载对象,使用了上面的示例代码。你可能想看看这个。 Https://github.com/dragoncherry/localstorage

对于 Swift 4.0来说,这就变得更容易了:

let defaults = UserDefaults.standard
//Set
defaults.set(passwordTextField.text, forKey: "Password")
//Get
let myPassword = defaults.string(forKey: "Password")

NsUserDefault 只保存小的可变大小。 如果您想要保存许多对象,您可以使用 CoreData 作为本机解决方案,或者我创建了一个库,它可以帮助您像下面这样轻松地保存对象。Save ()函数。它是基于 SQLite 的。

SundeedQLite

看看这个,然后告诉我你的评论

Swift 5 +

没有一个答案真正详细地介绍了内置在本地存储能力中的默认设置

您可以直接从苹果文档中获得以下选项,以便从默认值中“获取”数据。

func object(forKey: String) -> Any?
//Returns the object associated with the specified key.


func url(forKey: String) -> URL?
//Returns the URL associated with the specified key.


func array(forKey: String) -> [Any]?
//Returns the array associated with the specified key.


func dictionary(forKey: String) -> [String : Any]?
//Returns the dictionary object associated with the specified key.


func string(forKey: String) -> String?
//Returns the string associated with the specified key.


func stringArray(forKey: String) -> [String]?
//Returns the array of strings associated with the specified key.


func data(forKey: String) -> Data?
//Returns the data object associated with the specified key.


func bool(forKey: String) -> Bool
//Returns the Boolean value associated with the specified key.


func integer(forKey: String) -> Int
//Returns the integer value associated with the specified key.


func float(forKey: String) -> Float
//Returns the float value associated with the specified key.


func double(forKey: String) -> Double
//Returns the double value associated with the specified key.


func dictionaryRepresentation() -> [String : Any]
//Returns a dictionary that contains a union of all key-value pairs in the domains in the search list.

下面是“设置”的选项

func set(Any?, forKey: String)
//Sets the value of the specified default key.


func set(Float, forKey: String)
//Sets the value of the specified default key to the specified float value.


func set(Double, forKey: String)
//Sets the value of the specified default key to the double value.


func set(Int, forKey: String)
//Sets the value of the specified default key to the specified integer value.


func set(Bool, forKey: String)
//Sets the value of the specified default key to the specified Boolean value.


func set(URL?, forKey: String)
//Sets the value of the specified default key to the specified URL.

如果是存储的东西,如 偏好不是大数据设置这些是完全不错的选择。

双重例子 :

场景:

let defaults = UserDefaults.standard
var someDouble:Double = 0.5
defaults.set(someDouble, forKey: "someDouble")

获得:

let defaults = UserDefaults.standard
var someDouble:Double = 0.0
someDouble = defaults.double(forKey: "someDouble")

有趣的是,其中一个 getter 是 字典代表,这个方便的 getter 将获取所有的数据类型,不管它们是什么,并将它们放入一个漂亮的字典,你可以通过它的字符串名访问它,并给出正确的对应数据类型,当你要求返回,因为它的类型是 任何

还可以使用 func set(Any?, forKey: String)func object(forKey: String) -> Any? setter 和 getter 相应地存储自己的类和对象。

希望这将进一步阐明 UserDefault 类在存储本地数据方面的强大功能。

关于你应该存储多少和多久存储一次,哈代 _ 德国在这个 邮寄上给出了一个很好的答案,这里是它的一个报价

正如许多人已经提到的: 我没有意识到任何尺寸限制 (物理内存除外)在. plist 中存储数据(例如。 所以这不是多少钱的问题。

真正的问题应该是你多久写一次新的或者改变的东西 价值... 这是相关的电池消耗,这写将 原因。

IOS 没有机会避免对“磁盘”进行物理写入 值更改,只是为了保持数据完整性 这导致整个文件重写到磁盘。

这将启动“磁盘”,并使其保持较长时间的电源供应 防止 IOS 进入低功耗状态。

正如用户 Mohammad Reza Farahani 在此 邮寄中提到的,还需要注意 userDefault 的 异步的同步特性。

设置默认值时,它将在您的 进程,并异步到持久存储和其他进程。

例如,如果您保存并快速关闭程序,您可能会注意到它没有保存结果,这是因为它是异步持久化的。你可能不会一直注意到这一点,所以如果你计划在退出程序之前储蓄,你可能要考虑到这一点,给它一些时间来完成。

也许有人对此有一些不错的解决方案,他们可以在评论中分享?

这对如何在 Swift 5: https://www.hackingwithswift.com/example-code/system/how-to-save-user-settings-using-userdefaults中做到这一点给出了很好的解释

摘要:

设置值:

let defaults = UserDefaults.standard
defaults.set("value", forKey: "key")

获取 String 值:

let key = defaults.object(forKey: "StringKey") as? [String] ?? [String]()

要获得整数值:

let key = defaults.integer(forKey: "IntegerKey")