Отображение данных JSON в розетку в быстром
Я чрезвычайно новичок в программировании и пытаюсь изучать вещи по шагам за раз. Я искал в стеке и нашел несколько отличных идей, но ничего, что отвечало бы тому, что я надеюсь выучить.
Я создал код, который извлекает данные о погоде в формате JSON с одного веб-URL. Он только делится данными о погоде для одного местоположения и не запрашивает информацию.
Я могу распечатать информацию из данных JSON! (Это был огромный шаг). Следующим шагом является отображение информации, полученной из данных JSON, в моем приложении и на моем телефоне. Я нашел много сообщений об этом в табличном представлении, но не смог заставить это работать для моего приложения, в основном потому, что многие из них требуют от вас поиска места для извлечения данных (что не применимо в моем случае).
Я хочу взять один фрагмент информации из данных JSON и отобразить его на моем экране.
Я создал метку в своей раскадровке и подключил ее к своему контроллеру представления.
У меня также есть weather.swift, который вызывает данные JSON.
Проблема, с которой я столкнулся, заключается в том, что я получаю сообщение об ошибке "Значение типа" [Погода] "не имеет члена" имя "". Это в моем представлении controller.swift в строке кода "locationOutlet.text = наблюдения Data.name".
Вот код в моем контроллере представления:
импорт UIKit
Класс ViewController: UIViewController {
@IBOutlet weak var locationOutlet: UILabel!
var observationsData = [Weather]()
override func viewDidLoad() {
super.viewDidLoad()
/* Weather.observations(withLocation: ",") { (results:[Weather]) in
for result in results {
print("\(result)\n\n")
}
*/
}
// Do any additional setup after loading the view, typically from a nib.
func loadweatherData (location:String) {
Weather.observations(withLocation: ",") { (results:[Weather]?) in
if let weatherData = results {
self.observationsData = weatherData
}
//let weatherObject = observationsData[IndexPath.row]
}
func displayweatherData (location:String) {
locationOutlet.text = observationsData.name
}
//locationOutlet?.text = observationsData.name
}
}
и вот код в weather.swift, который вызывает данные JSON.
import Foundation
struct Weather {
let name:String
let air_temp:Double
let wind_spd_kt:Double
let swell_height:Double
enum SerializationError:Error {
case missing(String)
case invalid(String, Any)
}
init(json:[String:Any]) throws {
guard let name = json["name"] as? String else{throw SerializationError.missing("Name is missing")}
guard let air_temp = json["air_temp"] as? Double else{throw SerializationError.missing("Air temp is missing")}
guard let wind_spd_kt = json["wind_spd_kt"] as? Double else{throw SerializationError.missing("Wind speed is missing")}
guard let swell_height = json["swell_height"] as? Double else{throw SerializationError.missing("Swell hight is missing")}
self.name = name
self.air_temp = air_temp
self.wind_spd_kt = wind_spd_kt
self.swell_height = swell_height
}
static let basePath = "http://www.bom.gov.au/fwo/IDN60701/IDN60701.94937.json"
static func observations (withLocation location:String, completion: @escaping ([Weather]) -> ()) {
let url = basePath //+ location
let request = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in
var observationsArray:[Weather] = []
if let data = data {
do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] {
if let currentObservations = json["observations"] as? [String:Any] {
if let currentData = currentObservations["data"] as? [[String:Any]] {
for dataPoint in currentData {
if let weatherObject = try? Weather(json: dataPoint) {
observationsArray.append(weatherObject)
}
}
}
}
}
}catch{
print(error.localizedDescription)
}
completion(observationsArray)
}
}
task.resume()
}
}
Очевидно, я учусь и пытаюсь сделать что-то, что может оказаться сложнее, чем я думал на самом деле. Любая помощь в том, как я могу заставить мой лейбл отображать данные, была бы отличной. Спасибо за ваше время!
2 ответа
Тогда все, что вам нужно сделать, это получить первый индексированный объект погоды и отобразить его свойство в метке.
Weather.observations(withLocation: ",") { (results) in
if let firstIndexWeatherData = results.first {
//As API calls are usually on background thread and Apple requires Main Thread to update the UI so set your weatherData name to label on main thread like this.
DispatchQueue.main.async {
self.locationOutlet.text = firstIndexWeatherData.name
}
}
}
Вы пытаетесь получить доступ к массиву [Weather].name
Вместо этого вы можете захотеть получить доступ Weather.name
Попробуйте получить доступ к одному объекту Weather внутри массива