【发布时间】:2018-03-18 00:59:27
【问题描述】:
我目前正在尝试学习 Swift,但还没有走得很远,如果这是一个简单的问题,请原谅我;我已经研究了好几个小时了,还是没弄明白。
我有一个名为Person 的Codable 类。在这个类中,我有一个名为birthdate 的Date 属性。所以它看起来像这样:
class Person : Codable {
var birthdate: Date = Date()
var firstName: String = ""
var lastName: String = ""
enum CodingKeys : String, CodingKey {
case birthdate
case firstName = "first_name"
case lastName = "last_name"
}
}
我正在尝试解码我的 JSON:
[
{
"address": "302 N. 5th St.",
"base_64_image": null,
"birthdate": "2009-05-06T18:56:38.367",
"created": "2017-11-21T16:21:13",
"emergency_contact": "",
"emergency_contact_number": null,
"father_cell_number": null,
"father_home_number": null,
"father_name": null,
"first_name": "John",
"gender": 1,
"id": "d92fac59-66b9-49a5-9446-005babed617a",
"image_uri": null,
"is_inactive": false,
"last_name": "Smith",
"mother_cell_number": "1234567890",
"mother_home_number": "",
"mother_name": "His Mother",
"nickname": null,
"tenant_id": "9518352f-4855-4699-b0da-ecdc06470342",
"updated": "2018-01-20T02:11:45.9025023"
}
]
像这样:
// Fetch the data from the URL.
let headers: HTTPHeaders = [
"Accept": "application/json"
]
Alamofire.request(url, headers: headers).responseJSON { response in
if let data = response.data {
let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let people = try! decoder.decode(Array<Person>.self, from: data)
}
}
但是,我总是遇到同样的错误:
致命错误:“试试!”表达式意外引发错误:Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 47", intValue: Optional(47)), App.Person.CodingKeys.生日], debugDescription: "日期字符串与格式化程序期望的格式不匹配。", 底层错误: nil))
(“索引 47”显然不准确,因为这是我的实时 [和私人] 数据)。
如果我将 birthdate 属性从 Person 类中移除,一切都会按预期工作。
我已经用谷歌搜索并尝试了几个小时的新事物,但无论我尝试什么都无法让它发挥作用。这里有人可以帮帮我吗?
【问题讨论】:
-
不相关,但您的代码存在几个架构问题。永远不要仅仅为了避免为类创建初始化程序而给实例属性提供无意义的默认值,尤其是当这些属性应该是不可变的而不是可变的时。此外,除非您有充分的理由使用类,否则请使用结构,特别是因为您获得了与结构自动合成的成员初始化程序。您也不应该使用强制尝试,在 do-catch 块中处理
try。 -
如果您将日期格式化程序的
locale设置为Locale(identifier: "en_US_POSIX"),您的问题是否得到解决? -
您的时区也有很大的问题。每个运行您的应用程序的用户都会将该生日日期字符串解释为他们自己的当地时间。这不好。在日期字符串中指定时区,或者使用日期字符串表示的时区设置日期格式化程序的
timeZone。但是如果字符串本身包含自己的时区信息会更好。 -
@DávidPásztor 感谢您的信息。到目前为止,我所拥有的只是从 Stack Overflow 复制粘贴的,所以我肯定计划在进行过程中重构一些东西并了解更多关于 Swift 的信息。
-
“所有用户都在同一个时区,并且没有改变的机会” - 著名的遗言。最好避免这样的假设。这是一个微不足道的更改,可以防止出现意外的错误。