Swift - "Instance member cannot be used on type" 错误的简单修复?

Swift - Simple fix for "Instance member cannot be used on type" error?

这是我根据 isSteamDown JSON 页面所做的 JSON "decoding"/解析:

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)
}

错误如下:

Instance member 'status' cannot be used on type 'Instruction'

我想知道的是:使用 my 代码解决这个特定问题的方法是什么?

另外:是否有通常适用于这种错误格式的通用解决方案?

另外,如果问的不过分,能否请您尽可能通俗地解释一下您的回答背后的原因?


编辑:我尝试将 "Instruction.status" 更改为 "statusCheck.status" 并返回错误:

Value of tuple type '(key: String, value: Any)' has no member 'status'

对于 Decodable 类型,最好使用 JSONDecoder 而不是 JSONSerialization

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()
    }
}

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()
    }
}