UserDefaults 检查 nil 值不起作用

UserDefaults checking for nil value not working

知道为什么我的 if 语句总是给出 else 答案吗? 我从打印中注意到对象存储为 "optional()",也许这个可选状态与 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"
            }
        }
    }
}

试试这个

if (UserDefaults.standard.value(forKey: "etc") != nil)
{
    if (UserDefaults.standard.value(forKey: "etc") as! String).character.count == 0
    {
        //value is ""
    }else{
        //having some value
    }
}

正如 vadian 评论的那样,在这种情况下你不应该也没有必要使用 KVC 方法value(forKey:)

试试这个:

@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?
    }
}

推荐的方法(由 Apple 提供!)是在 UserDefaults 中注册 key/value 对以提供 - 正如 class 名称所暗示的那样 - 默认值。在第一次更改值之前,将考虑这些默认值。

Swift 的好处是总有一个(非可选的)值可以安全地展开。

尽快(例如 applicationWillFinishLaunching)添加这些行。它们应该在每次应用程序启动时执行。密钥 Nb 已注册为空字符串默认值。

let defaultValues = ["Nb" : ""]
UserDefaults.standard.register(defaults: defaultValues)

storeButton不要删除键并且不要对String使用字符串插值但是检查文本属性 是 nil 并在这种情况下保存一个空字符串。打印行是无意义的,因为在写入后立即从 UserDefaults 读取不会得到更改,并且您 知道 写入的内容

@IBAction func storeButton(_ sender: Any) {
    UserDefaults.standard.set(phoneLabel.text ?? "", forKey: "Nb")
}

retrieveButton 中使用专用方法 string(forKey 获取字符串,将其解包(由于注册密钥总是有一个值)并且只检查空字符串。并且不要读取(相同的)值 3 次。

@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)"
    }
}

你可能忘记在存储时调用同步value.You可以试试这个。

@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"
    }
}