Как декодировать .keys из словаря, используя Coadable - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть ответ ниже JSON.И я хочу получить все «данные», которые [[правила], «предпочтения», «цели»]] с использованием метода .keys.Но я не мог получить массив allkeys, используя функцию .keys.Я также приложил свой фрагмент кода.если вы сталкивались с этим, предложите мне избавиться от этой проблемы.

Хотя я могу получить эти allKeys, используя ObjectMapper и нативные объекты Dictionary.Мне просто нужно знать, почему я не смог добиться этого с помощью Codable.

Мой ответ json

{
    "statusCode": 200,
    "status": "success",
    "message": null,
    "data": {
        "rules": {
            "goals": {
                "min": "1",
                "max": "3"
            }
        },
        "preference": [
            1,
            2,
            3
        ],
        "goals": {
            "total": 4,

            "data": []
        }
    }
}

Мой код Фрагмент кода:

struct MeetingsDataModal: Codable {
    let statusCode: Int?
    let status: String?
    let message: String?
    let data: Results?
    enum CodingKeys: String, CodingKey {
        case statusCode = "statusCode"
        case status = "status"
        case message = "message"
        case data = "data"
    }
    func allkeys() {

    }
}

struct Results : Codable {
    let rules: Rules?
    let preference: [Preference]?
    let goals: Goals?
    enum CodingKeys: String, CodingKey {
        case rules = "rules"
        case preference = "preference"
        case goals = "goals"
    }
}

struct Rules : Codable {
}
struct Preference : Codable {
}
struct Goals : Codable {
}

Мои ожидания

let content = try JSONDecoder().decode(MeetingsDataModal.self, from: (response as? Data)!)
print(content.data.keys)

Но я получаю,

Значение типа 'Results?'не имеет членских «ключей»

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Возможно, я плохо понимаю вопрос, но ваши "ключи" определены вашим протоколом Codable - поэтому они известны. Если вы используете Swift 4.2+, вы можете воспользоваться CaseIterable протоколом

struct Results: Codable {
    let testOne: Int
    let testTwo: String
    enum CodingKeys: String, CodingKey, CaseIterable {
        case testOne
        case testTwo
    }
}

Results.CodingKeys.allCases.map { $0.rawValue }
0 голосов
/ 14 ноября 2018

Если вам нужны ключи.Можно добавить двухстрочный код:

   struct Results : Codable {
        let rules: Rules?
        let preference: [Preference]?
        let goals: Goals?
        enum CodingKeys: String, CodingKey {
            case rules = "rules"
            case preference = "preference"
            case goals = "goals"
        }

        var keys : [String]{
            return["rules", "preference","goals"]
        }
    }

На самом деле, если вам не нравится способ кодирования / декодирования, у нас есть еще один традиционный объект JSON, который может помочь вам обработать неструктурированный JSON.

    let obj =   try JSONSerialization.jsonObject(with: response!, options: JSONSerialization.ReadingOptions.allowFragments)

    print((((obj as! [String: Any?])["data"]) as! [String: Any?]).keys)

Вот один из способов расшифровки вашей структуры данных.

           let d = """
        {
            "statusCode": 200,
            "status": "success",
            "message": null,
            "data": {
                "rules": {
                    "goals": {
                        "min": "1",
                        "max": "3"
                    }
                },
                "preference": [
                1,
                2,
                3
                ],
                "goals": {
                    "total": 4,

                    "data": []
                }
            }
        }
        """.data(using: .utf8)!


        struct MeetingsDataModal: Decodable {
            let statusCode: Int
            let status: String
            let message: String?
            let data: Results
        }

        struct Results : Decodable {
            let rules: Rules
            let preference: [Int]
            let goals: Goals
        }

        struct Rules : Decodable {
            let goals : DirectData
        }
        struct DirectData : Decodable{
            let min : String
            let max : String
        }
        struct Goals : Decodable {
            let total : Int
            let data : [String]
        }

        let data0 = try JSONDecoder().decode(MeetingsDataModal.self, from: d)
        print(data0)
...