将 Decodable 结构存储到 Userdefaults
Posted
技术标签:
【中文标题】将 Decodable 结构存储到 Userdefaults【英文标题】:Store Decodable struct to 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。请参考以下***.com/a/37983027/1142743 不,@Vinodh 它似乎不起作用。我的结构是 Decodable 类型的 有可能然后你接受了答案。在不知道/尝试任何事情的情况下,不要说这是不可能的 【参考方案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 并将手机号码存储为字符串。以上是关于将 Decodable 结构存储到 Userdefaults的主要内容,如果未能解决你的问题,请参考以下文章
核心数据-[Decodable.Address initWithCoder:]:发送到实例的无法识别的选择器
Swift 4 Decodable - 将 JSON 对象解码为“数据”
使用 Swift 4 Decodable 将字符串 JSON 响应转换为布尔值
在 SwiftUI 中将 ObservableObject 链接到 DatePicker