Reputation: 83
Any idea why my if statement always gives else answer? I noticed from the print that the object is stored as "optional()", maybe this optional state is different from nil?
class ViewController: UIViewController {
@IBOutlet weak var phoneLabel: UITextField!
@IBOutlet weak var phoneDisplayLabel: UILabel!
@IBAction func storeButton(_ sender: Any) {
UserDefaults.standard.removeObject(forKey: "Nb")
UserDefaults.standard.set("\(phoneLabel.text!)", forKey: "Nb")
print(UserDefaults.standard.object(forKey: "Nb") as Any)
}
@IBAction func retrieveButton(_ sender: Any) {
let phoneNB = UserDefaults.standard.value(forKey: "Nb")
if let phoneNbDisplay = phoneNB as? String {
if UserDefaults.standard.object(forKey: "Nb") != nil {
phoneDisplayLabel.text = "Your NB is \(phoneNbDisplay)"
}
else {
phoneDisplayLabel.text = "enter a number first"
}
}
}
}
Upvotes: 0
Views: 2482
Reputation: 131
You might forget to call synchronize while storing value.You can try this.
@IBAction func storeButton(_ sender: Any) {
UserDefaults.standard.removeObject(forKey: "Nb")
UserDefaults.standard.set("\(phoneLabel.text!)", forKey: "Nb")
UserDefaults.standard.synchronize()
print (UserDefaults.standard.object(forKey: "Nb") as Any)
}
@IBAction func retrieveButton(_ sender: Any) {
if let phoneNB = UserDefaults.standard.string(forKey: "Nb"){
phoneDisplayLabel.text = "Your NB is \(phoneNB)"
}else {
phoneDisplayLabel.text = "enter a number first"
}
}
Upvotes: -1
Reputation: 285064
The recommended way (by Apple!) is to register key/value pairs in UserDefaults
to provide – as the class name implies – default values. Those default values are considered until the value is changed the first time.
The Swift benefit is that there is always a (non-optional) value which can be unwrapped safely.
As soon as possible (e.g. applicationWillFinishLaunching
) add these lines. They are supposed to be executed every time the application launches. The key Nb
is registered with an empty string default value.
let defaultValues = ["Nb" : ""]
UserDefaults.standard.register(defaults: defaultValues)
In storeButton
don't remove the key and don't use String Interpolation for a String
but check if the text property is nil
and save an empty string in this case. The print line is nonsensical because reading from UserDefaults
right after writing will not get the changes and you know what's been written
@IBAction func storeButton(_ sender: Any) {
UserDefaults.standard.set(phoneLabel.text ?? "", forKey: "Nb")
}
In retrieveButton
get the string with the dedicated method string(forKey
, unwrap it (due to registering the key there is always a value) and only check for empty string. And don't read the (same) value 3 times.
@IBAction func retrieveButton(_ sender: Any) {
let phoneNbDisplay = UserDefaults.standard.string(forKey: "Nb")!
if phoneNbDisplay.isEmpty {
phoneDisplayLabel.text = "enter a number first"
} else {
phoneDisplayLabel.text = "Your NB is \(phoneNbDisplay)"
}
}
Upvotes: 2
Reputation: 904
try this
if (UserDefaults.standard.value(forKey: "etc") != nil)
{
if (UserDefaults.standard.value(forKey: "etc") as! String).character.count == 0
{
//value is ""
}else{
//having some value
}
}
Upvotes: 0
Reputation: 47886
As vadian commented, you should not and have no need to use KVC method value(forKey:)
in this case.
Try this:
@IBAction func storeButton(_ sender: Any) {
UserDefaults.standard.removeObject(forKey: "Nb")
UserDefaults.standard.set(phoneLabel.text ?? "", forKey: "Nb") //<-You have no need to use String Interpolation.
print (UserDefaults.standard.object(forKey: "Nb") as Any)
}
@IBAction func retrieveButton(_ sender: Any) {
if let phoneNB = UserDefaults.standard.string(forKey: "Nb") {
if !phoneNB.isEmpty {
phoneDisplayLabel.text = "Your NB is \(phoneNB)"
} else {
phoneDisplayLabel.text = "enter a number first"
}
} else {
//### What do you want to do if "Nb" is not set?
}
}
Upvotes: 1