有一种方法可以使我的可编码结构使用 code 功能, 我面临的问题是我可以从网络对其进行编码,但不能从userdefaults进行解码。这是该结构的实现。
struct profile: Codable{
var id: Int?
var firstName: String?
var lastName: String?
var description: String?
var gender: String?
var birthDate: Date?
var smoke: Bool?
var findHouse: Bool?
var hasRoom: Bool?
var sociable: Int?
var ordered: Int?
var athlete: Int?
var party: Int?
var domestic:Int?
var gamer: Int?
var usersId: Int?
var imageId: Int?
var createdAt: Date?
var updatedAt: Date?
var image: imageModel?
var tags: [String]?
enum CodingKeys: String, CodingKey {
case id
case firstName = "first_name"
case lastName = "last_name"
case description
case gender
case birthDate = "birth_date"
case smoke
case findHouse = "find_house"
case hasRoom = "has_room"
case sociable
case ordered
case athlete
case party
case domestic
case gamer
case usersId = "users_id"
case imageId = "image_id"
case createdAt = "created_at"
case updatedAt = "updated_at"
case image
case tags
}
init(){
}
init(from decoder: Decoder) throws {
print("going to decode from decoder showing results")
let values = try decoder.container(keyedBy: CodingKeys.self)
self.id = (try values.decodeIfPresent(Int.self, forKey: .id))
print("id value \(self.id)")
self.firstName = (try values.decodeIfPresent(String.self, forKey: .firstName))
print("name value \(self.firstName)")
self.lastName = (try values.decodeIfPresent(String.self, forKey: .lastName))
print("lastname value \(lastName)")
self.description = (try values.decodeIfPresent(String.self, forKey: .description))
print("description value \(description)")
self.gender = (try values.decodeIfPresent(String.self, forKey: .gender))
print("gender value \(gender)")
if let date = try values.decodeIfPresent(String.self, forKey: .birthDate){
print("date value \(date)")
self.birthDate = Date(fromString: String(date.dropLast(10)), format: .custom("yyyy-MM-dd"))
print("after conversion \(self.birthDate)")
}else{
self.birthDate = nil
}
self.smoke = (try values.decodeIfPresent(Int.self, forKey: .smoke)) == 0 ? false : true
print("smoke value \(smoke)")
self.findHouse = (try values.decodeIfPresent(Int.self, forKey: .findHouse)) == 0 ? false : true
print("findhouse value \(findHouse)")
self.hasRoom = (try values.decodeIfPresent(Int.self, forKey: .hasRoom)) == 0 ? false : true
print("has romm value \(hasRoom)")
self.sociable = (try values.decodeIfPresent(Int.self, forKey: .sociable))
print("sociable value\(sociable)")
self.ordered = (try values.decodeIfPresent(Int.self, forKey: .ordered))
print("orderder value \(ordered)")
self.athlete = (try values.decodeIfPresent(Int.self, forKey: .athlete))
print("athlete value \(athlete)")
self.party = (try values.decodeIfPresent(Int.self, forKey: .party))
self.domestic = (try values.decodeIfPresent(Int.self, forKey: .domestic))
self.gamer = (try values.decodeIfPresent(Int.self, forKey: .gamer))
self.usersId = (try values.decodeIfPresent(Int.self, forKey: .usersId))
self.imageId = (try values.decodeIfPresent(Int.self, forKey: .imageId))
if let date = try values.decodeIfPresent(String.self, forKey: .createdAt){
self.createdAt = Date(fromString: String(date.dropLast(10)), format: .custom("yyyy-MM-dd"))
}else {
self.createdAt = nil
}
if let date = try values.decodeIfPresent(String.self, forKey: .updatedAt){
self.updatedAt = Date(fromString: String(date.dropLast(10)), format: .custom("yyyy-MM-dd"))
}else{
self.updatedAt = nil
}
self.image = (try values.decodeIfPresent(imageModel.self, forKey: .image))
self.tags = (try values.decodeIfPresent([String].self, forKey: .tags))
}
}
这是保存到userdefaults.standard的代码:
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(requestManager.instance.user) {
UserDefaults.standard.set(encoded, forKey: "user")
if let json = String(data: encoded, encoding: .utf8) {
print("reading value in userDefault \(json)")
}
}
所以当我尝试使用以下代码从userDefaults解码时:
let decoder = JSONDecoder()
if let user = UserDefaults.standard.data(forKey: "user"){
print("data for user \(user)")
do{
let question = try decoder.decode(profile.self, from: user)
print("birthDate from decoder \(question.birthDate)")
print("id from decoder \(question.id)")
print("name from decoder \(question.firstName)")
if question.id != nil {
print("the id is not Nil \(question)")
requestManager.instance.user = question
}
}catch{
print(error.localizedDescription)
print("el valor de birthDate in \(requestManager.instance.user.birthDate)")
}
}
此后,我在控制台中收到了这些消息
要从解码器解码。 id值可选(3)。 名称值Optional(“ Yoel”)。 无法读取数据,因为格式不正确。
我猜想是birthDate,createdAt和updatedAt字段中的日期类型。
所以我想尝试的是创建一个自定义编码器,因为在解码器中期望使用String并应返回Date值。
答案 0 :(得分:0)
日期本身符合可编码协议。为什么要尝试在init(from decoder: Decoder)
中自己进行一些自定义解码?您不应尝试将其解码为字符串。我只是尝试了一个非常小的实现,例如:
//: Playground - noun: a place where people can play
import Foundation
var str = "Hello, playground"
struct Person:Codable {
var name:String
var birthDate:Date
}
func test (){
let pascal = Person(name: "Pascal", birthDate: Date(timeIntervalSinceNow: -26.6 * 365 * 24 * 3600))
print(pascal)
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(pascal) {
UserDefaults.standard.set(encoded, forKey: "person")
}
let decoder = JSONDecoder()
guard let data = UserDefaults.standard.data(forKey: "person"),
let person = try? decoder.decode(Person.self, from: data) else {
print("damn")
return
}
print(person)
}
test()