AltBrian
AltBrian

Reputation: 2572

Trying seque data from UIViewController to Weather API

I am trying to pass data from a UIViewController to a SecondViewController that is getting data from a WeatherAPI.

 import UIKit

class ViewController: UIViewController {

@IBOutlet weak var raceTextField: UITextField!


let races = ["Melbourne", "Bahrain", "Shanghai", "Baku",
             "Barcelona", "Monaco", "Montreal","Le Castellet","Speilberg",
             "Silverstone","Hockenheimring","Budapest","Spa-Francorchamps","Monza","Singapore","Sochi","Suzuka","Austin","Interlagos","Abu Dhabi"]
var selectedRace: String?

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    createRacesPicker()
    createToolbar()
}


@IBAction func sendButtonPressed(_ sender: Any) {
    performSegue(withIdentifier: "getWeather", sender: self)
}

func createRacesPicker() {
    let racePicker = UIPickerView()
    racePicker.delegate = self
    raceTextField.inputView = racePicker
}
func createToolbar() {
    let toolBar = UIToolbar()
    toolBar.sizeToFit()
    let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.dismissKeyboard))
    toolBar.setItems([doneButton], animated: false)
    toolBar.isUserInteractionEnabled = true
    raceTextField.inputAccessoryView = toolBar
}
@objc func dismissKeyboard(){
    view.endEditing(true)
}
}
 //MARK: - UIPickerView Delegate extension
 /***************************************************************/
//UIPickerView here
 extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource{
   func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
   }

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: 
Int) -> Int {
    return races.count
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return races[row]
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    selectedRace = races[row]
    raceTextField.text = selectedRace
}
//Write the PrepareForSegue Method here
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "getWeather" {
        let weatherVC = segue.destination as! WeatherViewController

        weatherVC.city = raceTextField.text!
       }
     }
   }

Now what I want to do is update this screen with weather data. Below is my code to update the weatherData. So basically segue the city chosend from the view controller to the WeatherViewController

import UIKit
import CoreLocation
import Alamofire
import SwiftyJSON

class WeatherViewController: UIViewController {

//constants
let weatherDataModel = WeatherDataModel()

var city = ""

@IBOutlet weak var cityLabel: UILabel!
@IBOutlet weak var weatherIcon: UIImageView!
@IBOutlet weak var temperatureLabel: UILabel!

let WEATHER_URL = "http://api.openweathermap.org/data/2.5/weather"
let APP_ID = "8a99df7bf7ef4a4a202732c392b2d240"

override func viewDidLoad() {
    super.viewDidLoad()
    cityLabel.text = city
    // Do any additional setup after loading the view.
}

//MARK: - Networking
/***************************************************************/

//Write the getWeatherData method here:
func getWeatherData(url: String, parameters: [String : String]) {
    Alamofire.request(url, method: .get, parameters: parameters).responseJSON {
        response in
        if response.result.isSuccess {
            print("Success we got the weather data!")
            let weatherJSON : JSON = JSON(response.result.value!)
            self.updateWeatherData(json: weatherJSON)

        } else {
            print("Error \(String(describing: response.result.error))")
            //self because of the closure.  Therefore you have to specify the function.
            self.cityLabel.text = "Connection Issues"
        }

    }
}

//MARK: - JSON Parsing
/***************************************************************/
//updateweatherdata method here

func updateWeatherData(json: JSON) {
    if let tempResult = json["main"]["temp"].double {
        weatherDataModel.temperature = Int(tempResult - 273)
        weatherDataModel.city = json["name"].stringValue
        weatherDataModel.condition = json["weather"][0]["id"].intValue
        weatherDataModel.weatherIconName = weatherDataModel.updateWeathericon(condition: weatherDataModel.condition)
        userEnteredNewCityName(city: city)
        updateUIWithWeatherData()
    } else {
        cityLabel.text = "No data available"
    }

}

func userEnteredNewCityName(city: String){
    let params : [String : String] = ["q" : city, "appid" : APP_ID]
    getWeatherData(url: WEATHER_URL, parameters: params)
}

 //Write the updateUIWithWeatherData method here:


func updateUIWithWeatherData() {
    cityLabel.text = weatherDataModel.city
    temperatureLabel.text = String(weatherDataModel.temperature)
    weatherIcon.image = UIImage()
  }

 }

The weatherDataModel is in a seperate class. So I am trying to add MVC into the app. I can't seem to see what I am missing. It's probably something really simple. Any help would be appreciated.

Upvotes: 0

Views: 39

Answers (1)

vadian
vadian

Reputation: 285270

You have to call the method to load the data in viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    cityLabel.text = city
    userEnteredNewCityName(city: city)
}

and delete the line

userEnteredNewCityName(city: city)

in updateWeatherData otherwise you'll run into an infinite loop

Upvotes: 1

Related Questions