我目前正在使用Swift开发的iOS应用程序,需要在设备上存储一些用户创建的内容,但似乎找不到一种简单快捷的方法来在设备上存储/接收用户内容。
有人可以解释如何存储和访问本地存储吗?
想法是在用户执行操作时存储数据,并在应用程序启动时接收数据。
我目前正在使用Swift开发的iOS应用程序,需要在设备上存储一些用户创建的内容,但似乎找不到一种简单快捷的方法来在设备上存储/接收用户内容。
有人可以解释如何存储和访问本地存储吗?
想法是在用户执行操作时存储数据,并在应用程序启动时接收数据。
Answers:
如果仅存储两个字符串NSUserDefaults
,最简单的解决方案是,在Swift 3中,将该类重命名为just UserDefaults
。
最好将密钥存储在全局某个位置,以便您可以在代码的其他位置重用它们。
struct defaultsKeys {
static let keyOne = "firstStringKey"
static let keyTwo = "secondStringKey"
}
// Setting
let defaults = UserDefaults.standard
defaults.set("Some String Value", forKey: defaultsKeys.keyOne)
defaults.set("Another String Value", forKey: defaultsKeys.keyTwo)
// Getting
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
}
// Setting
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Some String Value", forKey: defaultsKeys.keyOne)
defaults.setObject("Another String Value", forKey: defaultsKeys.keyTwo)
// Getting
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
}
对于比次要配置,标志或基本字符串更严重的事情,您应该使用某种持久存储-目前流行的选择是Realm,但您也可以使用SQLite或Apple自己的CoreData。
setValue(_:forKey:)
将数据保存到UserDefaults。使用(在Swift 3中)提供的UserDefaults
方法set(_:forKey:)
。
他们说使用NSUserDefaults
当我第一次实现长期(应用关闭后)数据存储时,我在网上阅读的所有内容都指向NSUserDefaults。但是,我想存储一个字典,尽管可能,但事实证明这很痛苦。我花了几个小时试图消除类型错误。
NSUserDefaults也受功能限制
进一步的阅读显示了NSUserDefaults的读/写如何真正迫使应用程序一次读/写所有内容或什么都不做,因此效率不高。然后我了解到检索数组不是直接的。我意识到,如果要存储多个字符串或布尔值,NSUserDefaults确实不是理想的选择。
它也是不可扩展的。如果您要学习编码,请学习可扩展方式。仅将NSUserDefaults用于存储与首选项相关的简单字符串或布尔值。使用Core Data存储阵列和其他数据,并不像他们所说的那么难。从小开始。
更新:另外,如果您添加了Apple Watch支持,则还有另一个潜在的考虑因素。您应用的NSUserDefaults现在会自动发送到Watch Extension。
使用核心数据
因此,我忽略了有关核心数据是更困难的解决方案的警告,并开始阅读。三个小时之内,我就开始工作了。我将表数组保存在Core Data中,并在备份应用程序后重新加载数据!教程代码很容易适应,我能够进行标题和详细信息数组的存储,而只需要进行一些额外的实验。
因此,对于阅读此帖子的任何人,他们都在解决NSUserDefault类型问题,或者需要的不仅仅是存储字符串,请考虑花一两个小时来处理核心数据。
这是我阅读的教程:
http://www.raywenderlich.com/85578/first-core-data-app-using-swift
如果您未选中“核心数据”
如果您在创建应用时未选中“核心数据”,则可以在之后添加它,只需五分钟即可:
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
如何从核心数据列表中删除
好的,感谢@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"
}
对于太复杂的数据,使用NSCoding和NSKeyedArchiver是另一个不错的选择NSUserDefaults
,但对于CoreData而言,这太过分了。它还为您提供了更明确地管理文件结构的机会,如果您要使用加密,那就非常好。
斯威夫特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 }
对于Swift 3
UserDefaults.standard.setValue(token, forKey: "user_auth_token")
print("\(UserDefaults.standard.value(forKey: "user_auth_token")!)")
对于由于某些原因不希望处理UserDefaults的用户,还有另一个选项-NSKeyedArchiver和NSKeyedUnarchiver。它有助于使用存档器将对象保存到文件中,并将存档文件加载到原始对象中。
// 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
迅捷5+
没有一个答案能真正详细地涵盖默认的内置本地存储功能。它可以做的不仅仅是字符串。
您可以直接从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 set(Any?, forKey: String)
and func object(forKey: String) -> Any?
setter和getter 来存储自己的类和对象。
希望这可以进一步阐明UserDefaults类用于存储本地数据的功能。
就说明你应该多少存储和频率,Hardy_Germany介绍了,在这个好答案后,这里是从它报价
正如已经提到的许多:我不知道将数据存储在.plist中的任何SIZE限制(物理内存除外)(例如UserDefaults)。因此,这不是如何的问题。
真正的问题应该是您如何经常编写新的/更改的值...这与写入将导致的电池消耗有关。
如果更改单个值,IOS就没有机会避免物理写入“磁盘”,只是为了保持数据完整性。关于UserDefaults,这将导致整个文件重写到磁盘。
这会为“磁盘”加电,并使其保持更长的供电时间,并防止IOS进入低功耗状态。
用户Mohammad Reza Farahani在本文中提到的其他要注意的是userDefaults 的异步和同步性质。
设置默认值时,它将在您的流程中同步更改,并异步更改为持久性存储和其他流程。
例如,如果保存并快速关闭程序,您可能会注意到它没有保存结果,这是因为它是异步持久化的。您可能不会一直注意到这一点,因此,如果您打算在退出程序之前进行保存,则可能需要花一些时间来解决这个问题。
也许有人对此有一些不错的解决方案,可以在评论中分享?
NsUserDefaults仅保存较小的变量大小。如果要保存许多对象,可以将CoreData用作本机解决方案,或者我创建了一个库,可帮助您像.save()函数一样轻松地保存对象。它基于SQLite。
查看并告诉我您的评论