这是我基于isSteamDown JSON页面做的JSON“解码”/解析:
struct Instruction: Decodable {
let statuses: [Status]
let message, messageURL: String
let status: Bool
let load, time: Int
enum CodingKeys: String, CodingKey {
case statuses, message
case messageURL = "message_url"
case status, load, time
}
}
以下是我编写的用于尝试解码的代码:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = "https://issteamdown.com/status.json"
let urlObj = URL(string: url)
URLSession.shared.dataTask(with: urlObj!) {(data, response, error) in
do {
guard let json = (try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else {
return
}
for statusCheck in json {
print(Instruction.status)
}
} catch {
print(error)
}
}.resume()
}
}
我遇到的错误是打印线:
for statusCheck in json {
print(Instruction.status)
}
错误如下:
实例成员“状态”不能用于“指令”类型
我想知道的是:我的代码解决这个特定问题的方法是什么?
另外:是否有一般的解决方案通常适用于此错误格式?
另外,如果问题不是太多,你能不能用尽可能的外行解释你的答案背后的原因?
编辑:我尝试将“Instruction.status”更改为“statusCheck.status”并返回错误:
元组类型的值'(键:字符串,值:任意)'没有成员'状态'
状态也应该适应Decodable ..你应该使用如下的JSONDecodable方法。
struct Status: Decodable {
let title: String
let code: Int
let status: Bool
let time: Int
}
struct Instruction: Decodable {
let statuses: [Status]
let message, messageURL: String
let load: Int
enum CodingKeys: String, CodingKey {
case statuses, message
case messageURL = "message_url"
case load
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = "https://issteamdown.com/status.json"
let urlObj = URL(string: url)
URLSession.shared.dataTask(with: urlObj!) {(data, response, error) in
guard let data = data else { return }
do {
let json = try JSONDecoder().decode(Instruction.self, from: data)
json.statuses.forEach { status in
print(status)
}
} catch {
print(error)
}
}.resume()
}
}
对于JSONDecoder
类型,最好使用JSONSerialization
而不是Decodable
。
let decoder = JSONDecoder()
guard let instruction = try decoder.decode(Instruction.self, from: data!) else { return }
print(instruction.status) // no need for 'for' loop!
以下是您现有代码的上下文代码:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = "https://issteamdown.com/status.json"
let urlObj = URL(string: url)
URLSession.shared.dataTask(with: urlObj!) {(data, response, error) in
do {
// write the above code here
} catch {
print(error)
}
}.resume()
}
}