如果字典键的空值为

时间:2016-07-01 22:16:38

标签: ios swift swift2 nsdictionary nsuserdefaults

我有一个使用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]

2 个答案:

答案 0 :(得分:0)

Swift类现在为UserDefaultsNSUserDefaults是一个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