【问题标题】:Store Decodable struct to Userdefaults将 Decodable 结构存储到 Userdefaults
【发布时间】:2018-01-11 13:10:35
【问题描述】:

我有一个像这样的Decodable 结构......

struct BestWishes: Decodable {

    private enum CodingKeys : String, CodingKey {
        case customerID = "customer_id"
        case birthDate = "birth_date"
         case type = "type"
        case customerName = "customer_name"
        case mobileNo = "mobile_number"
    }
    let customerID: Int
    let date: String
    let type: String
    let customerName : String
    let mobileNumber: Int

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        customerID = try container.decode(Int.self, forKey: .customerID)
        type = try container.decode(String.self, forKey: .type)
        if type == "anniversary_date" {
            date = try container.decode(String.self, forKey: .anniversaryDate)
        } else {
            date = try container.decode(String.self, forKey: .birthDate)
        }
        customerName = try container.decode(String.self, forKey: .customerName)
        mobileNumber = try container.decode(Int.self, forKey: .mobileNo)
    }
}

并且其中的所有数据都存储在这样的数组中..

var bestWishesArr = [BestWishes]()
self.bestWishesArr.append(contentsOf: result.bestWishes) 

现在我想将bestWishesArr 存储到 Userdefaults。不知道如何实现...

【问题讨论】:

  • 使用keyarchiver。请参考以下stackoverflow.com/a/37983027/1142743
  • 不,@Vinodh 它似乎不起作用。我的结构是 Decodable 类型的
  • 有可能然后你接受了答案。在不知道/尝试任何事情的情况下,不要说这是不可能的

标签: ios swift


【解决方案1】:

添加Codable 协议的后半部分。为了与init 方法兼容,date 属性的保存方式因type 而不同

struct BestWish: Codable {

    private enum CodingKeys : String, CodingKey {
        case customerID = "customer_id"
        case birthDate = "birth_date"
        case anniversaryDate = "anniversary_date"
        case type
        case customerName = "customer_name"
        case mobileNumber = "mobile_number"
    }
    let customerID: Int
    let date: String
    let type: String
    let customerName : String
    let mobileNumber: Int

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        customerID = try container.decode(Int.self, forKey: .customerID)
        type = try container.decode(String.self, forKey: .type)
        if type == "anniversary_date" {
            date = try container.decode(String.self, forKey: .anniversaryDate)
        } else {
            date = try container.decode(String.self, forKey: .birthDate)
        }
        customerName = try container.decode(String.self, forKey: .customerName)
        mobileNumber = try container.decode(Int.self, forKey: .mobileNumber)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(customerID, forKey: .customerID)
        try container.encode(type, forKey: .type)
        if type == "anniversary_date" {
            try container.encode(date, forKey: .anniversaryDate)
        } else {
            try container.encode(date, forKey: .birthDate)
        }
        try container.encode(customerName, forKey: .customerName)
        try container.encode(mobileNumber, forKey: .mobileNumber)
    }
}

然后对数组进行编码并将Data对象写入UserDefaults

do {
    let jsonData = try JSONEncoder().encode(bestWishesArr)
    UserDefaults.standard.set(jsonData, forKey:"bestWishes")
} catch { print(error) }

【讨论】:

  • 再次感谢@vadian。答案真的很有帮助!给了 。也赞成...:)
  • 只是一个疑问..json中是否有isExist之类的方法来检查某个键是否存在...?
  • 要么使属性可选,要么decodeIfPresent阅读有关 JSON 编码/解码的文档。这是值得的。
  • @v.bw 不要使用 UserDefaults 来存储您的应用数据。 UserDefaults 用于存储您的应用程序设置(即 UISwitch 状态)。只需将生成的 JSON 数据写入 App 支持目录中的 json 文件
  • 顺便说一句,您还应该使用正确的 dateStrategyDecoding 选项将日期存储为 Date 并将手机号码存储为字符串。
猜你喜欢
  • 2017-12-06
  • 1970-01-01
  • 2019-01-12
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
  • 1970-01-01
相关资源
最近更新 更多