Отображение данных 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 внутри массива

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