Создать массив из JSON в Swift

Я пытаюсь преобразовать данные JSON в массив, но я действительно не знаю, как это сделать.

Я получаю данные и сохраняю их в виде строк, а также могу показать их на дисплее.

struct User_Hosting: Codable {
    let company_name: String
    let website: String
    let street: String
    let housenumber: String
    let zip: String
    let city: String    

    enum CodingKeys: String, CodingKey {
        case company_name = "company_name"
        case website = "website"
        case street = "street"
        case housenumber = "housenumber"
        case zip = "zip"
        case city = "city"
    }
}

А вот и другие коды:

let url = URL(string: "myURL.com")

        URLSession.shared.dataTask(with: url!, completionHandler: { [weak self] (data, response, error) in
            guard let data = data, error == nil else {
                print(error?.localizedDescription ?? "An error occurred")
                return
            }
            DispatchQueue.main.async {
                self?.dataSource = try! JSONDecoder().decode([User_Hosting].self, from: data)
            }
        }).resume()
    }

Почему вы используете CodingKeys, когда имена свойств структуры и имена свойств с сервера идентичны

Shubham Bakshi 27.05.2019 08:51

Добавьте JSON response, который вы получаете от API.

PGDev 27.05.2019 08:54

@ShubhamBakshi Ну, я не знал, что это может работать без CodingKeys ... Спасибо!

Amed LM AB 27.05.2019 08:54

А какая у вас dataSource недвижимость в self?.dataSource = try! JSONDecoder().decode([User_Hosting].self, from: data)?

Shubham Bakshi 27.05.2019 08:58

В Swift мы предпочитаем Camel Case (camelCase), а не Snake Case (snake_case). Итак, вы можете использовать эту строку let decoder = JSONDecoder() decoder.decordingStrategy = .convertFromSnakeCase, а затем использовать let company_name as let companyName.

Rob 27.05.2019 08:59

Не делайте try!, используйте правильный do {...} catch { print(error) }, чтобы не пропустить ошибки, которые могут возникнуть при декодировании. Ответ на ваш вопрос вполне может быть в этом заявлении для печати. И сделайте расшифровку перед DispatchQueue.main.async

Joakim Danielson 27.05.2019 09:23

@ShubhamBakshi, что вы имеете в виду под свойством dataSource?

Amed LM AB 27.05.2019 11:01

@Rob Спасибо за помощь! Но где мне использовать этот код?

Amed LM AB 27.05.2019 11:02

Я не думаю, что здесь можно использовать DispatchQueue.main.async, поскольку вы не обновляете какой-либо компонент пользовательского интерфейса.

Shubham Bakshi 27.05.2019 11:05

@ShubhamBakshi Я использую его для TableView. Я не знаю, правильный ли это ответ.

Amed LM AB 27.05.2019 11:06

Я не думаю, что это так работает, вам нужно обновить массив, который вы используете для заполнения tableView из и не сам источник данных

Shubham Bakshi 27.05.2019 11:08

@ShubhamBakshi Я хочу поместить алфавитный указатель в правую часть UITableview и отсортировать по нему только название компании, но я не знаю, в каком массиве находятся данные.

Amed LM AB 27.05.2019 11:25

@AmedLMAB Как я уже сказал, вы можете использовать его выше декодирования из вашего Codable.

Rob 27.05.2019 11:40
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
13
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваши CodingKeys совпадают с именами свойств, поэтому вы можете вообще избавиться от enum

struct UserHosting: Codable {
    let companyName: String
    let website: String
    let street: String
    let housenumber: String
    let zip: String
    let city: String    
}

Поскольку у вас есть несколько ключей змеиного случая в JSON, вы можете изменить JSONDecoder.keyDecodingStrategy на convertFromSnakeCase, например

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

Приведенный выше декодер будет обрабатывать такие ключи, как company_name, как назначенные свойству companyName вашей структуры.

Наконец, вы можете декодировать свой JSON в блоке do-catch, поэтому в случае ошибки у нас будет сообщение о том, что пошло не так.

do {
    self.dataSource = try decoder.decode([UserHosting].self, from: data)
} catch {
    print("JSON Decoding Error \(error)")
}

Как уже неоднократно указывалось ранее, не делайте вместо этого использует localizedDescription do print(error) для более подробного сообщения об ошибке.

Joakim Danielson 27.05.2019 11:11

@AamirRq Я хочу поместить алфавитный указатель в правую часть UITableview и отсортировать по нему только название компании, но я не знаю, в каком массиве находятся данные.

Amed LM AB 27.05.2019 11:24

Другие вопросы по теме