我有一个使用SwiftForms的项目。
有一个导航按钮,用于执行将textFields中的信息发送到NSUserDefaults的功能。但是如果我有一个空的textField,app会崩溃,但是当填写完所有字段时会保存数据。我是否只是在函数中添加一个检查以查找NSNull
?
func submit(_: UIBarButtonItem!) {
let message = self.form.formValues()
//message is [String : AnyObject]
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(message as Dictionary, forKey: "theMessage")
print("\n Message Saved! \n")
print(message)
}
这是我点击保存时收到的错误,并且没有填写任何字段,应用程序崩溃了:
Attempt to set a non-property-list object {
birthday = "<null>";
job = "<null>";
lastName = "<null>";
name = "<null>";
segmented = "<null>";
stepper = 20;
textview = "<null>";
} as an NSUserDefaults/CFPreferences value for key theMessage
这是我填写所有字段时得到的结果 - 没有崩溃
--- Message Saved! ---
["segmented": 1, "job": Job, "lastName": Last, "birthday": 2016-07-01 22:00:12 +0000, "textview": Etiam porta sem malesuada magna mollis euismod. Vestibulum id ligula porta felis euismod semperac, vestibulum at eros., "stepper": 22, "name": First]
答案 0 :(得分:0)
Swift类现在为UserDefaults
(NSUserDefaults
是一个Objective-C类)。但是,它不能改变Swift无法在该类中存储具有nil
值的字典这一事实。因此,只需将字典首先存档为Data
。
var someDictionary: [String: String?] = ["a": nil, "b": "beta"]
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: someDictionary, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "someKey")
} catch let error {
print(error)
}
要检索字典,只需对其取消存档:
if let def = UserDefaults.standard.object(forKey: "someKey") as? Data,
let d = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(def) as? [String: String?] {
print(d) // ["a": nil, "b": Optional("beta")]
}
在上面的示例中,try?
关键字将结果作为可选内容处理。如果您希望处理错误,请使用do-try-catch模式:
if let def = UserDefaults.standard.object(forKey: "someKey") as? Data {
do {
if let d = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(def) as? [String: String?] {
print(d) // ["a": nil, "b": Optional("beta")]
}
} catch {
print(error)
}
}
只要符合NSCoding
协议,就可以将任何对象写入磁盘。
答案 1 :(得分:-1)
formValues
会返回NSNull
表示空值,而这些空值不能保存在NSDictionary
中,如 Paulw11 所示。
您可以使用此功能对其进行过滤。
let filtered = message.filter({!$1.isKindOfClass(NSNull)}).reduce([:]) { ( dic , e) -> [String:AnyObject] in
var dic = dic
dic[e.0 as! String] = e.1
return dic
}
然后将filtered
保存在userDefaults