John Murcielago John Murcielago - 5 months ago 23
Swift Question

NSUserDefaults optionals in Swift

I'm trying to deal with compiler in case of optional values. Task is very simple, my func fetches user defaults to appear them in tableview. If user launches app for the first time, it setts default values. Setting default values works fine (checked with print log), but fetching causes:


fatal error: unexpectedly found nil while unwrapping an Optional value


I'm already worked with optionals for a long time, but, perhaps I'm still confused about them, 'cos I see that everything seems to be correct and even compiler says, that everything is ok.

func getFiltersSetts() -> [String] {
let userDefs = NSUserDefaults.standardUserDefaults()
var defsArray = [String]()
if (userDefs.objectForKey("gender") != nil) {
defsArray.append((userDefs.objectForKey("gender")?.stringValue)!)
defsArray.append((userDefs.objectForKey("age")?.stringValue)!)
defsArray.append((userDefs.objectForKey("online")?.stringValue)!)
}
else {
userDefs.setObject("Male", forKey: "gender")
userDefs.setObject("21-30", forKey: "age")
userDefs.setObject("Online", forKey: "online")
}
return defsArray
}

Answer

You are force unwrapping your optionals, and you should get them as strings before appending them to your array.

A cleaner way to set the defaults would be to coalesce the unwrapping of your optionals, Try the following approach:

func getFiltersSetts() -> [String] {
    let userDefs = NSUserDefaults.standardUserDefaults()
    var defsArray = [String]()
    defsArray.append(userDefs.stringForKey("gender") ?? "Male")
    defsArray.append(userDefs.stringForKey("age") ?? "21-30")
    defsArray.append(userDefs.stringForKey("online") ?? "Online")
    return defsArray
}

The code above uses the coalesce (??) operator. If your optional, say userDefs.stringfForKey("gender"), returns nil, the coalesce operator will use the default value "Male".

Then at a later time you can save your user defaults (or create them) if they haven't been set before.

Also, is worth noticing that you should be unwrapping your optionals using the if let notation. Instead of comparing if its != nil, as this will prevent you from force unwrapping them inside the code block.

I hope this helps!

Comments