Swift-简单修复“实例成员不能用于类型”错误?

时间:2018-09-13 16:15:06

标签: json swift parsing boolean decoding

这是我根据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)
}

,错误如下:

  

实例成员'status'不能用于'Instruction'类型

我想知道的是:使用 my 代码可以解决此特定问题吗?

还:是否有通常对此错误格式有效的常规解决方案?

如果问得还不太多,您能否以专业的术语解释您的答案背后的原因?


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

  

元组类型'(键:字符串,值:任何)'的值没有成员'状态'

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

状态也应适应“可解码”。 并且您应该使用如下所示的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()
    }
}