Как преобразовать файл JSON в словарь в Swift 4? - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть JSON-сохранение в файле ("list_catalog.json"):

[
 {
  "idcatalog": 1,
  "imgbase64": "",
  "urlImg": "http://172.../page01.jpg",
  "urlPages": "http://172.../catalog_1_pages.json",
  "dt_from": "",
  "dt_to": ""
 },
 {
  "idcatalog": 2,
  "imgbase64": "",
  "urlImg": "http://172.../1.jpg",
  "urlPages": "http://172.../2_pages.json",
  "category": [
   {
    "id": 1,
    "lib": "lib"
   }
  ],
  "dt_to": ""
 }
]

Я могу получить этот файл с:

if let url = URL(string: "http://172.../list_catalogs.json") {
        do {
            let contents = try String(contentsOf: url)
            print(contents)

        } catch {
            // contents could not be loaded
        }
    }

Но я не могу перевести эту строку в словарь. Для преобразования данных в строку я использую эту функцию:

func convertToDictionary(text: String) -> [String: Any]? {
    if let data = text.data(using: .utf8) {
        do {
            return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        } catch {
            print(error.localizedDescription)
        }
    }
    return nil
}

Но для этой ситуации это не работает Кто-нибудь может мне помочь?

1 Ответ

0 голосов
/ 13 сентября 2018

Проблема с кодом, который у вас есть, состоит в том, что вы пытаетесь преобразовать массив в словарь (как правильно отметили несколько человек в комментариях Vadian, Moritz на момент написания статьи).

Таким образом, очевидным решением первого шага было бы вместо приведения к [String: Any] приведение к [[String: Any]] (массив словарей), но это все равно оставляет проблему с частью Any.Чтобы работать с этим словарем, вам нужно знать / запоминать ключи и их типы, а также приводить каждое значение по мере его использования.

Гораздо лучше использовать протокол Codable, который вместе с декодером позволяет вам в основном отображать JSON в соответствующие структуры кода.

Вот пример того, как вы можете проанализировать этот JSON, используя кодируемый протокол Swift 4 (сделано на Swift Playground)

let jsonData = """
[{
    "idcatalog": 1,
    "imgbase64": "",
    "urlImg": "http://172.../page01.jpg",
    "urlPages": "http://172.../catalog_1_pages.json",
    "dt_from": "",
    "dt_to": ""
}, {
    "idcatalog": 2,
    "imgbase64": "",
    "urlImg": "http://172.../1.jpg",
    "urlPages": "http://172.../2_pages.json",
    "category": [{
        "id": 1,
        "lib": "lib"
    }],
"dt_to": ""
}]
""".data(using: .utf8)!

struct CatalogItem: Codable {
    let idCatalog: Int
    let imgBase64: String?
    let urlImg: URL
    let urlPages: URL
    let dtFrom: String?
    let dtTo: String?
    let category: [Category]?

    enum CodingKeys: String, CodingKey {
        case idCatalog = "idcatalog"
        case imgBase64 = "imgbase64"
        case urlImg, urlPages, category
        case dtFrom = "dt_from"
        case dtTo = "dt_to"
    }
}

struct Category: Codable {
    let id: Int
    let lib: String?

    enum CodingKeys: String, CodingKey {
        case id, lib
    }
}

do {
    let decoder = JSONDecoder()
    let result = try decoder.decode([CatalogItem].self, from: jsonData)
    print(result)
} catch {
    print(error)
}

Вывод на консоль:

[__lldb_expr_118.CatalogItem (idCatalog: 1, imgBase64: необязательный (""), urlImg: http://172. .. / page01.jpg , urlPages: http://172.../catalog_1_pages.json, dtFrom: необязательный (""), dtTo: необязательный (""), категория: nil), __lldb_expr_118.CatalogItem (idCatalog: 2, imgBase64: необязательный (""), urlImg: http://172. .. / 1.jpg , urlPages: http://172. .. / 2_pages.json , dtFrom: nil, dtTo: Optional (""), категория: необязательная ([__lldb_expr_118.Category (id: 1, lib: Необязательно ("lib"))]))]

Теперь самое интересное, теперь эти данные гораздо проще использовать ...

print(result.first?.urlImg)

Выход:

Дополнительно (http://172. .. / page01.jpg )

Это работает для примера JSON, который вы предоставили, но может потребоваться больше настроек, основанных на остальной части вашего набора данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...