Reputation: 2572
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
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