Я пытаюсь преобразовать данные 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()
}
Добавьте JSON response
, который вы получаете от API.
@ShubhamBakshi Ну, я не знал, что это может работать без CodingKeys ... Спасибо!
А какая у вас dataSource
недвижимость в self?.dataSource = try! JSONDecoder().decode([User_Hosting].self, from: data)
?
В Swift мы предпочитаем Camel Case (camelCase), а не Snake Case (snake_case). Итак, вы можете использовать эту строку let decoder = JSONDecoder() decoder.decordingStrategy = .convertFromSnakeCase
, а затем использовать let company_name as let companyName
.
Не делайте try!
, используйте правильный do {...} catch { print(error) }
, чтобы не пропустить ошибки, которые могут возникнуть при декодировании. Ответ на ваш вопрос вполне может быть в этом заявлении для печати. И сделайте расшифровку перед DispatchQueue.main.async
@ShubhamBakshi, что вы имеете в виду под свойством dataSource?
@Rob Спасибо за помощь! Но где мне использовать этот код?
Я не думаю, что здесь можно использовать DispatchQueue.main.async
, поскольку вы не обновляете какой-либо компонент пользовательского интерфейса.
@ShubhamBakshi Я использую его для TableView. Я не знаю, правильный ли это ответ.
Я не думаю, что это так работает, вам нужно обновить массив, который вы используете для заполнения tableView
из и не сам источник данных
@ShubhamBakshi Я хочу поместить алфавитный указатель в правую часть UITableview и отсортировать по нему только название компании, но я не знаю, в каком массиве находятся данные.
@AmedLMAB Как я уже сказал, вы можете использовать его выше декодирования из вашего Codable.
Ваши 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)
для более подробного сообщения об ошибке.
@AamirRq Я хочу поместить алфавитный указатель в правую часть UITableview и отсортировать по нему только название компании, но я не знаю, в каком массиве находятся данные.
Почему вы используете
CodingKeys
, когда имена свойств структуры и имена свойств с сервера идентичны