如何将 JSON 解码成不同的类型?
How to decode JSON Into different types?
我有这个本地 JSON 文件,其中包含标题、开头和结尾。我想从开始键和结束键创建日期,但标题是字符串,所以我可以创建事件 objects。现在我已经将所有内容解码为字符串。所以我试图创建一个自定义初始化,但错误不断出现“Return 来自初始化程序而不初始化所有存储的属性”。不确定我做错了什么
这是我的事件模型和我的 JSON文件
struct Event: Decodable & Equatable {
let title : String
let start : Date
let end : Date
//Custom decoding init
init(from decoder : Decoder) throws {
let container = try decoder.singleValueContainer()
let stringType = try container.decode(String.self)
switch stringType {
case "title":
self.title = try container.decode(String.self)
case "start":
self.start = try container.decode(Date.self)
case "end":
self.end = try container.decode(Date.self)
default:
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Not valid date \(stringType)")
}
}
}
JSON
[{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"}, {"title": "Nap Break", "start": "November 8, 2018 12:30 PM", "end": "November 8, 2018 1:30 PM"}, {"title": "Football Game", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}, {"title": "Evening Cookout with Friends", "start": "November 6, 2018 5:00 PM", "end": "November 6, 2018 10:00 PM"}, {"title": "Roller Derby", "start": "November 7, 2018 12:00 PM", "end": "November 7, 2018 2:30 PM"}, {"title": "Basketball Game", "start": "November 8, 2018 7:30 PM", "end": "November 8, 2018 10:30 PM"}, {"title": "Local Pub with Friends", "start": "November 1, 2018 7:30 PM", "end": "November 1, 2018 11:00 PM"}, {"title": "Dentist Appointment", "start": "November 10, 2018 1:45 PM", "end": "November 10, 2018 2:30 PM"}, {"title": "Free Donuts", "start": "November 9, 2018 3:00 PM", "end": "November 9, 2018 4:00 PM"}, {"title": "TV Show Marathon", "start": "November 9, 2018 4:30 PM", "end": "November 9, 2018 9:00 PM"}, {"title": "Lunch with Friends", "start": "November 8, 2018 11:30 AM", "end": "November 8, 2018 1:00 PM"}, {"title": "SF Coffee Festival","start": "November 6, 2018 6:00 PM","end": "November 6, 2018 9:00 PM"}, {"title": "Beer with Friends", "start": "November 9, 2018 8:00 PM", "end": "November 9, 2018 9:30 PM"}, {"title": "Yoga", "start": "November 1, 2018 6:00 PM", "end": "November 1, 2018 7:30 PM"}, {"title": "Rock Concert", "start": "November 7, 2018 6:30 PM", "end": "November 7, 2018 11:00 PM"}, {"title": "Lunch Meeting", "start": "November 9, 2018 12:30 PM", "end": "November 9, 2018 2:30 PM"}, {"title": "Bicycling with Friends", "start": "November 1, 2018 6:00 AM", "end": "November 1, 2018 9:30 AM"}, {"title": "Birthday Party", "start": "November 10, 2018 12:30 PM", "end": "November 10, 2018 8:30 PM"}, {"title": "Football Tailgate with John", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}]
-> 首先你需要接受正确的 JSON 数据
let json = """
{
"data" : [{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"}, {"title": "Nap Break", "start": "November 8, 2018 12:30 PM", "end": "November 8, 2018 1:30 PM"}, {"title": "Football Game", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}, {"title": "Evening Cookout with Friends", "start": "November 6, 2018 5:00 PM", "end": "November 6, 2018 10:00 PM"}, {"title": "Roller Derby", "start": "November 7, 2018 12:00 PM", "end": "November 7, 2018 2:30 PM"}, {"title": "Basketball Game", "start": "November 8, 2018 7:30 PM", "end": "November 8, 2018 10:30 PM"}, {"title": "Local Pub with Friends", "start": "November 1, 2018 7:30 PM", "end": "November 1, 2018 11:00 PM"}, {"title": "Dentist Appointment", "start": "November 10, 2018 1:45 PM", "end": "November 10, 2018 2:30 PM"}, {"title": "Free Donuts", "start": "November 9, 2018 3:00 PM", "end": "November 9, 2018 4:00 PM"}, {"title": "TV Show Marathon", "start": "November 9, 2018 4:30 PM", "end": "November 9, 2018 9:00 PM"}, {"title": "Lunch with Friends", "start": "November 8, 2018 11:30 AM", "end": "November 8, 2018 1:00 PM"}, {"title": "SF Coffee Festival","start": "November 6, 2018 6:00 PM","end": "November 6, 2018 9:00 PM"}, {"title": "Beer with Friends", "start": "November 9, 2018 8:00 PM", "end": "November 9, 2018 9:30 PM"}, {"title": "Yoga", "start": "November 1, 2018 6:00 PM", "end": "November 1, 2018 7:30 PM"}, {"title": "Rock Concert", "start": "November 7, 2018 6:30 PM", "end": "November 7, 2018 11:00 PM"}, {"title": "Lunch Meeting", "start": "November 9, 2018 12:30 PM", "end": "November 9, 2018 2:30 PM"}, {"title": "Bicycling with Friends", "start": "November 1, 2018 6:00 AM", "end": "November 1, 2018 9:30 AM"}, {"title": "Birthday Party", "start": "November 10, 2018 12:30 PM", "end": "November 10, 2018 8:30 PM"}, {"title": "Football Tailgate with John", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}]
}
"""
-> 然后你需要创建一个可编码的 class 或一个结构
struct Main: Codable {
var data: [MYStruct]?
}
// MARK: - Datum
struct MYStruct: Codable {
var title, start, end: String?
}
-> 如果密钥 “开始”:“2018 年 11 月 3 日 6:00 下午” 这里的“开始”推迟了,你可以像这样使用 codingKey
struct MYStruct: Codable {
var title, start, end: String?
enum CodingKeys: String, CodingKey {
case title = "title" // key name as string
case startDate = "start"
case endDate = "end"
}
-> 然后创建一个 JSON 解码器来解码 jsonData
override func viewDidLoad() {
super.viewDidLoad()
let jsonData = Data(json.utf8)
let decoder = JSONDecoder()
let loadedData = try? decoder.decode(Main.self, from: jsonData) // 1st parameter object name 2nd parameter JsonData
print(loadedData?.data?[0].title)
}
-> 请记住,您 json 始终是正确的策略并以 {}
结尾
-> 始终应该在密钥对值
中
-> 输出
Optional("Evening Picnic")
没有不同的类型,所有字典中的所有值始终具有相同的类型String
。
因此 singleValueContainer
是错误的方法,根本不需要自定义初始化程序。
要将字符串日期解码为 Date
只需添加适当的日期解码策略
let jsonString = """
[{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"}, {"title": "Nap Break", "start": "November 8, 2018 12:30 PM", "end": "November 8, 2018 1:30 PM"}, {"title": "Football Game", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}, {"title": "Evening Cookout with Friends", "start": "November 6, 2018 5:00 PM", "end": "November 6, 2018 10:00 PM"}, {"title": "Roller Derby", "start": "November 7, 2018 12:00 PM", "end": "November 7, 2018 2:30 PM"}, {"title": "Basketball Game", "start": "November 8, 2018 7:30 PM", "end": "November 8, 2018 10:30 PM"}, {"title": "Local Pub with Friends", "start": "November 1, 2018 7:30 PM", "end": "November 1, 2018 11:00 PM"}, {"title": "Dentist Appointment", "start": "November 10, 2018 1:45 PM", "end": "November 10, 2018 2:30 PM"}, {"title": "Free Donuts", "start": "November 9, 2018 3:00 PM", "end": "November 9, 2018 4:00 PM"}, {"title": "TV Show Marathon", "start": "November 9, 2018 4:30 PM", "end": "November 9, 2018 9:00 PM"}, {"title": "Lunch with Friends", "start": "November 8, 2018 11:30 AM", "end": "November 8, 2018 1:00 PM"}, {"title": "SF Coffee Festival","start": "November 6, 2018 6:00 PM","end": "November 6, 2018 9:00 PM"}, {"title": "Beer with Friends", "start": "November 9, 2018 8:00 PM", "end": "November 9, 2018 9:30 PM"}, {"title": "Yoga", "start": "November 1, 2018 6:00 PM", "end": "November 1, 2018 7:30 PM"}, {"title": "Rock Concert", "start": "November 7, 2018 6:30 PM", "end": "November 7, 2018 11:00 PM"}, {"title": "Lunch Meeting", "start": "November 9, 2018 12:30 PM", "end": "November 9, 2018 2:30 PM"}, {"title": "Bicycling with Friends", "start": "November 1, 2018 6:00 AM", "end": "November 1, 2018 9:30 AM"}, {"title": "Birthday Party", "start": "November 10, 2018 12:30 PM", "end": "November 10, 2018 8:30 PM"}, {"title": "Football Tailgate with John", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}]
"""
struct Event : Decodable {
let title : String
let start, end : Date
}
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "MMMM dd, yyyy h:mm a"
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
let result = try decoder.decode([Event].self, from: Data(jsonString.utf8))
print(result)
} catch {
print(error)
}
我有这个本地 JSON 文件,其中包含标题、开头和结尾。我想从开始键和结束键创建日期,但标题是字符串,所以我可以创建事件 objects。现在我已经将所有内容解码为字符串。所以我试图创建一个自定义初始化,但错误不断出现“Return 来自初始化程序而不初始化所有存储的属性”。不确定我做错了什么
这是我的事件模型和我的 JSON文件
struct Event: Decodable & Equatable {
let title : String
let start : Date
let end : Date
//Custom decoding init
init(from decoder : Decoder) throws {
let container = try decoder.singleValueContainer()
let stringType = try container.decode(String.self)
switch stringType {
case "title":
self.title = try container.decode(String.self)
case "start":
self.start = try container.decode(Date.self)
case "end":
self.end = try container.decode(Date.self)
default:
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Not valid date \(stringType)")
}
}
}
JSON
[{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"}, {"title": "Nap Break", "start": "November 8, 2018 12:30 PM", "end": "November 8, 2018 1:30 PM"}, {"title": "Football Game", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}, {"title": "Evening Cookout with Friends", "start": "November 6, 2018 5:00 PM", "end": "November 6, 2018 10:00 PM"}, {"title": "Roller Derby", "start": "November 7, 2018 12:00 PM", "end": "November 7, 2018 2:30 PM"}, {"title": "Basketball Game", "start": "November 8, 2018 7:30 PM", "end": "November 8, 2018 10:30 PM"}, {"title": "Local Pub with Friends", "start": "November 1, 2018 7:30 PM", "end": "November 1, 2018 11:00 PM"}, {"title": "Dentist Appointment", "start": "November 10, 2018 1:45 PM", "end": "November 10, 2018 2:30 PM"}, {"title": "Free Donuts", "start": "November 9, 2018 3:00 PM", "end": "November 9, 2018 4:00 PM"}, {"title": "TV Show Marathon", "start": "November 9, 2018 4:30 PM", "end": "November 9, 2018 9:00 PM"}, {"title": "Lunch with Friends", "start": "November 8, 2018 11:30 AM", "end": "November 8, 2018 1:00 PM"}, {"title": "SF Coffee Festival","start": "November 6, 2018 6:00 PM","end": "November 6, 2018 9:00 PM"}, {"title": "Beer with Friends", "start": "November 9, 2018 8:00 PM", "end": "November 9, 2018 9:30 PM"}, {"title": "Yoga", "start": "November 1, 2018 6:00 PM", "end": "November 1, 2018 7:30 PM"}, {"title": "Rock Concert", "start": "November 7, 2018 6:30 PM", "end": "November 7, 2018 11:00 PM"}, {"title": "Lunch Meeting", "start": "November 9, 2018 12:30 PM", "end": "November 9, 2018 2:30 PM"}, {"title": "Bicycling with Friends", "start": "November 1, 2018 6:00 AM", "end": "November 1, 2018 9:30 AM"}, {"title": "Birthday Party", "start": "November 10, 2018 12:30 PM", "end": "November 10, 2018 8:30 PM"}, {"title": "Football Tailgate with John", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}]
-> 首先你需要接受正确的 JSON 数据
let json = """
{
"data" : [{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"}, {"title": "Nap Break", "start": "November 8, 2018 12:30 PM", "end": "November 8, 2018 1:30 PM"}, {"title": "Football Game", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}, {"title": "Evening Cookout with Friends", "start": "November 6, 2018 5:00 PM", "end": "November 6, 2018 10:00 PM"}, {"title": "Roller Derby", "start": "November 7, 2018 12:00 PM", "end": "November 7, 2018 2:30 PM"}, {"title": "Basketball Game", "start": "November 8, 2018 7:30 PM", "end": "November 8, 2018 10:30 PM"}, {"title": "Local Pub with Friends", "start": "November 1, 2018 7:30 PM", "end": "November 1, 2018 11:00 PM"}, {"title": "Dentist Appointment", "start": "November 10, 2018 1:45 PM", "end": "November 10, 2018 2:30 PM"}, {"title": "Free Donuts", "start": "November 9, 2018 3:00 PM", "end": "November 9, 2018 4:00 PM"}, {"title": "TV Show Marathon", "start": "November 9, 2018 4:30 PM", "end": "November 9, 2018 9:00 PM"}, {"title": "Lunch with Friends", "start": "November 8, 2018 11:30 AM", "end": "November 8, 2018 1:00 PM"}, {"title": "SF Coffee Festival","start": "November 6, 2018 6:00 PM","end": "November 6, 2018 9:00 PM"}, {"title": "Beer with Friends", "start": "November 9, 2018 8:00 PM", "end": "November 9, 2018 9:30 PM"}, {"title": "Yoga", "start": "November 1, 2018 6:00 PM", "end": "November 1, 2018 7:30 PM"}, {"title": "Rock Concert", "start": "November 7, 2018 6:30 PM", "end": "November 7, 2018 11:00 PM"}, {"title": "Lunch Meeting", "start": "November 9, 2018 12:30 PM", "end": "November 9, 2018 2:30 PM"}, {"title": "Bicycling with Friends", "start": "November 1, 2018 6:00 AM", "end": "November 1, 2018 9:30 AM"}, {"title": "Birthday Party", "start": "November 10, 2018 12:30 PM", "end": "November 10, 2018 8:30 PM"}, {"title": "Football Tailgate with John", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}]
}
"""
-> 然后你需要创建一个可编码的 class 或一个结构
struct Main: Codable {
var data: [MYStruct]?
}
// MARK: - Datum
struct MYStruct: Codable {
var title, start, end: String?
}
-> 如果密钥 “开始”:“2018 年 11 月 3 日 6:00 下午” 这里的“开始”推迟了,你可以像这样使用 codingKey
struct MYStruct: Codable {
var title, start, end: String?
enum CodingKeys: String, CodingKey {
case title = "title" // key name as string
case startDate = "start"
case endDate = "end"
}
-> 然后创建一个 JSON 解码器来解码 jsonData
override func viewDidLoad() {
super.viewDidLoad()
let jsonData = Data(json.utf8)
let decoder = JSONDecoder()
let loadedData = try? decoder.decode(Main.self, from: jsonData) // 1st parameter object name 2nd parameter JsonData
print(loadedData?.data?[0].title)
}
-> 请记住,您 json 始终是正确的策略并以 {}
结尾-> 始终应该在密钥对值
中-> 输出
Optional("Evening Picnic")
没有不同的类型,所有字典中的所有值始终具有相同的类型String
。
因此 singleValueContainer
是错误的方法,根本不需要自定义初始化程序。
要将字符串日期解码为 Date
只需添加适当的日期解码策略
let jsonString = """
[{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"}, {"title": "Nap Break", "start": "November 8, 2018 12:30 PM", "end": "November 8, 2018 1:30 PM"}, {"title": "Football Game", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}, {"title": "Evening Cookout with Friends", "start": "November 6, 2018 5:00 PM", "end": "November 6, 2018 10:00 PM"}, {"title": "Roller Derby", "start": "November 7, 2018 12:00 PM", "end": "November 7, 2018 2:30 PM"}, {"title": "Basketball Game", "start": "November 8, 2018 7:30 PM", "end": "November 8, 2018 10:30 PM"}, {"title": "Local Pub with Friends", "start": "November 1, 2018 7:30 PM", "end": "November 1, 2018 11:00 PM"}, {"title": "Dentist Appointment", "start": "November 10, 2018 1:45 PM", "end": "November 10, 2018 2:30 PM"}, {"title": "Free Donuts", "start": "November 9, 2018 3:00 PM", "end": "November 9, 2018 4:00 PM"}, {"title": "TV Show Marathon", "start": "November 9, 2018 4:30 PM", "end": "November 9, 2018 9:00 PM"}, {"title": "Lunch with Friends", "start": "November 8, 2018 11:30 AM", "end": "November 8, 2018 1:00 PM"}, {"title": "SF Coffee Festival","start": "November 6, 2018 6:00 PM","end": "November 6, 2018 9:00 PM"}, {"title": "Beer with Friends", "start": "November 9, 2018 8:00 PM", "end": "November 9, 2018 9:30 PM"}, {"title": "Yoga", "start": "November 1, 2018 6:00 PM", "end": "November 1, 2018 7:30 PM"}, {"title": "Rock Concert", "start": "November 7, 2018 6:30 PM", "end": "November 7, 2018 11:00 PM"}, {"title": "Lunch Meeting", "start": "November 9, 2018 12:30 PM", "end": "November 9, 2018 2:30 PM"}, {"title": "Bicycling with Friends", "start": "November 1, 2018 6:00 AM", "end": "November 1, 2018 9:30 AM"}, {"title": "Birthday Party", "start": "November 10, 2018 12:30 PM", "end": "November 10, 2018 8:30 PM"}, {"title": "Football Tailgate with John", "start": "November 3, 2018 6:00 PM", "end": "November 3, 2018 10:00 PM"}]
"""
struct Event : Decodable {
let title : String
let start, end : Date
}
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "MMMM dd, yyyy h:mm a"
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
let result = try decoder.decode([Event].self, from: Data(jsonString.utf8))
print(result)
} catch {
print(error)
}