UserDefaults 中的值仅在重新启动后出现

Value in UserDefaults appears only after relaunch

我将 Codable 对象和简单字符串存储在 UserDefaults 中,然后显示一个使用该值的新屏幕。出于某种原因,在我重新启动该应用程序之前,Codable 对象为 nil。字符串值立即可用。 为了调试这个问题,我尝试通过点击一个按钮来检索该对象,但它总是 nil 并且在我尝试获取该值时无关紧要。重启后才会出现

var user: Contact? = {
    if let contactData = UserDefaults.standard.data(forKey: Constants.UserDefaultsKey.currentUser),
        let contact = try? JSONDecoder().decode(Contact.self, from: contactData) {
        return contact
    }
    return nil
}()

func storeUser(_ user: Contact) {
    do {
        let encodedUser = try JSONEncoder().encode(user)
        UserDefaults.standard.set(encodedUser, forKey: Constants.UserDefaultsKey.currentUser)
        UserDefaults.standard.set(true, forKey: Constants.UserDefaultsKey.isLoggedIn)
        UserDefaults.standard.synchronize()
    } catch {
        print(error.localizedDescription)
    }
}

struct Contact {
    var id: String?
    var email: String?
}

extension Contact: Codable {

enum ContactEncodingKeys: String, CodingKey {
    case id
    case email = "email_address_work"
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: ContactEncodingKeys.self)
    try container.encode(id, forKey: .id)
    try container.encode(email, forKey: .email)
}

init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: ContactEncodingKeys.self)
    id = try container.decode(String.self, forKey: .id)
    email = try container.decode(String?.self, forKey: .email)
}
}

因此 user 对象在重新启动之前为 nil

目前,如果您在 UserDefaults 中设置对象之前访问 user 属性,它只会分配 nil 并且不会再次计算,直到您创建一个新的class 的对象。将 user 属性 更改为如下计算。

var user: Contact? {
    if let contactData = UserDefaults.standard.data(forKey: Constants.UserDefaultsKey.currentUser),
        let contact = try? JSONDecoder().decode(Contact.self, from: contactData) {
        return contact
    }
    return nil
}