【问题标题】:Value in UserDefaults appears only after relaunchUserDefaults 中的值仅在重新启动后出现
【发布时间】:2018-07-24 03:37:21
【问题描述】:

我将 Codable 对象和简单字符串存储在 UserDefaults 中,然后显示一个使用该值的新屏幕。出于某种原因 Codable 对象为零,直到我重新启动应用程序。字符串值立即可用。 为了调试这个问题,我试图通过点击一个按钮来检索该对象,但它总是 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 对象在重新启动之前为零

【问题讨论】:

  • 在您发布的代码中,您的问题到底在哪里?不清楚。
  • 我可以看到ContactEncodingKeys id 没有任何字符串值。键必须是字符串。这可能是一个问题。你注意到了吗?
  • 您的var user 将在此对象实例化后立即初始化。如果在设置用户默认值之前发生这种情况,那么user 将是nil。它不是一个计算变量,因此每次引用它时都不会重新评估它。您的意思是说它是一个计算变量吗?此外,无需致电synchronize
  • @Paulw11 你是对的。谢谢
  • @ShamimHossain 只要“id”的字符串值与键名相同就可以

标签: ios swift codable userdefaults


【解决方案1】:

目前如果您在设置UserDefaults 中的对象之前访问user 属性,它只会分配nil,并且在您创建此类的新对象之前不会再次计算。将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
}

【讨论】:

  • 谢谢。除了那个之外,还计算了其他对象。花这么多时间在这个愚蠢的错误上
  • @NikolaiProkofev 如果它可以帮助您解决问题,您是否介意接受答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
相关资源
最近更新 更多