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

Ios 如何在Swift应用程序中保存本地数据?,ios,swift,nsuserdefaults,Ios,Swift,Nsuserdefaults,我目前正在开发一款用Swift开发的iOS应用程序,我需要在设备上存储一些用户创建的内容,但我似乎找不到一种简单快捷的方法在设备上存储/接收用户内容 有人能解释一下如何存储和访问本地存储吗? 其思想是在用户执行操作时存储数据,并在应用程序启动时接收数据。如果只存储两个字符串,最简单的解决方案是NSUserDefaults,在Swift 3中,该类已重命名为justUserDefaults 最好将密钥全局存储在某个位置,以便在代码中的其他位置重用它们。 struct defaultsKeys {

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

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


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

如果只存储两个字符串,最简单的解决方案是
NSUserDefaults
,在Swift 3中,该类已重命名为just
UserDefaults

最好将密钥全局存储在某个位置,以便在代码中的其他位置重用它们。

struct defaultsKeys {
    static let keyOne = "firstStringKey"
    static let keyTwo = "secondStringKey"
}
Swift 3.0、4.0和5.0 Swift 2.0 对于比次要配置、标志或基本字符串更重要的内容,您应该使用某种持久性存储—目前流行的选择是,但您也可以使用或Apple自己的。

好的,谢谢和

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

let defaults = NSUserDefaults.standardUserDefaults()

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

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

我在这里对它进行了总结

他们说使用NSUserDefaults

当我第一次实施长期(应用程序关闭后)数据存储时,我在网上读到的所有内容都指向默认值。然而,我想储存一本字典,虽然可能,但这证明是一件痛苦的事。我花了几个小时试图消除输入错误

NSUserDefaults的功能也受到限制

进一步的阅读揭示了NSUserDefaults的读/写实际上是如何迫使应用程序一次读/写所有内容或什么都不读/写的,因此它没有效率。然后我了解到检索数组并不是一件简单的事情。我意识到,如果存储的字符串或布尔数超过几个,NSUserDefaults就不理想了

它也是不可伸缩的。如果您正在学习如何编码,请学习可伸缩的方式。仅使用NSUserDefaults存储与首选项相关的简单字符串或布尔值。使用核心数据存储阵列和其他数据,并不像他们说的那么难。从小事做起

更新:另外,如果您添加Apple Watch支持,还有另一个潜在的考虑因素。您的应用程序的NSUserDefaults现在自动发送到Watch扩展

使用核心数据

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

所以,对于那些读过与NSUserDefault类型问题有关的人,或者他们需要的不仅仅是存储字符串,考虑花一两个小时玩核心数据。

以下是我阅读的教程:

如果未选中“核心数据”

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

 defaults.synchronize()
如果在创建应用程序时未选中“核心数据”,则可以在之后添加,只需五分钟:

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

对于那些对于
NSUserDefaults
来说过于复杂的数据,使用是另一个很好的选择,但是对于这些数据,CoreData可能会有点过头。它还为您提供了更明确地管理文件结构的机会,如果您想使用加密,这一点非常好。

对于Swift 3

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

Swift 3.0

设置器:本地存储

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

 defaults.synchronize()
Getter:本地存储

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

//perform your task on success }

对于出于某些原因不愿意处理用户默认值的人,还有另一个选项-NSKeyedArchiver&NSKeyedUnarchiver。它有助于使用archiver将对象保存到文件中,并将存档文件加载到原始对象中

// 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)
}
我用上面的示例代码编写了一个简单的实用程序来保存/加载本地存储中的对象。你可能想看看这个。

对于Swift 4.0,这变得更容易:

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

NsUserDefaults仅保存小的可变大小。 如果您想保存许多对象,可以将CoreData用作本机解决方案,或者我创建了一个库,它可以帮助您像.save()函数一样轻松地保存对象。它基于SQLite


查看并告诉我您的评论

Swift 5+

所有答案都没有详细介绍默认内置的本地存储功能。它可以做的远远不止是字符串。

struct defaultsKeys {
    static let keyOne = "firstStringKey"
    static let keyTwo = "secondStringKey"
}
您可以直接从apple文档中获得以下选项,用于从默认设置中“获取”数据

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的有趣之处在于dictionaryRepresentation,这个方便的getter将获取所有数据类型,不管它们是什么,并将它们放入一个很好的字典中,您可以通过它的字符串名称访问它,并在您请求返回时给出正确的对应数据类型,因为它是“any”类型

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

希望这更清楚地说明UserDefaults类存储本地数据的能力

关于你应该存储多少和存储频率,Hardy_Germany对此给出了一个很好的答案,这里引用了它的一段话

正如许多人已经提到的:我不知道任何尺寸限制 (物理内存除外)将数据存储在.plist中(例如。 用户默认值)。所以这不是一个多少钱的问题

真正的问题应该是你多久写一次新的/改变的 价值观这与电池的耗电量有关 原因