32 Replies
      Latest reply on Jul 3, 2019 5:24 PM by net777
      net777 Level 1 Level 1 (0 points)

        I am following a course and am trying so test myself.

        I have a model and I give values to properties from a json-file.

        (If Im showing code wrong please tell me how I shoud do it)

         

        This works:

        func updateUIWithWeatherData() {

              

                cityLabel.text = weatherDataModel.city

                temperatureLabel.text = String(weatherDataModel.temperature)

                weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)

              

              

            }

         

        But here it doesn't. Test shows but not the city.

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

                let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")

              

                cell.textLabel?.text = weatherDataModel.city

              

                //cell.textLabel?.text = "test"

              

                return cell

            }

        • Re: Showing property in tablecell
          Claude31 Level 8 Level 8 (6,595 points)

          Could you explain where is updateUIWithWeatherData located ?

          Where is weatherDataModel defined ?

           

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

           

          But here it doesn't. Test shows but not the city.

          Do you mean that the following shows "test" in cell ?

           

          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                  let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
          
                 //  cell.textLabel?.text = weatherDataModel.city
                  cell.textLabel?.text = "test"
          
                  return cell
              }

           

          If so, could you add a print:

          Normally, cells should be dequeued ; so test with the following (and add the print statement to check city value):

           

          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                  
                  let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
          
                  cell.textLabel?.text = weatherDataModel.city
                  print("weatherDataModel.city", weatherDataModel.city)
                  //cell.textLabel?.text = "test"
          
          
                  return cell
              }
            • Re: Showing property in tablecell
              net777 Level 1 Level 1 (0 points)

              updateUIWithWeatherData is located before the tableview function.

               

              So I have this:

               

              func updateWeatherData(json : JSON) {

                    

                      if let tempResult = json["main"]["temp"].double {

                    

                          weatherDataModel.temperature = Int(tempResult - 273.15)

                    

                          weatherDataModel.city = json["name"].stringValue

                    

                          weatherDataModel.condition = json["weather"][0]["id"].intValue

                    

                          weatherDataModel.weatherIconName = weatherDataModel.updateWeatherIcon(condition: weatherDataModel.condition)

                        

                          updateUIWithWeatherData() //Here I call working function

                      }

                      else {

                          cityLabel.text = "No data"

                      }

                  }

               

              Then updateUIWithWeatherData()

              And then tableView function.

              The text "test" does show.

              Your code shows nothing.

              So seems like the property "city" isn't set here.


            • Re: Showing property in tablecell
              John368 Level 1 Level 1 (0 points)

              Usually we need also to use the indexPath in the function tableView (tableView: , cellForRowAt indexPath:). For example:

               

              cell.textLabel?.text = weatherDataModel.city[indexPath.row]

               

              But in your case probably you are not getting values from JSON file.

              • Re: Showing property in tablecell
                net777 Level 1 Level 1 (0 points)

                Trying to post bit by bit instead.

                import UIKit

                 

                class WeatherDataModel {

                 

                    //Declare your model variables here

                    var temperature : Int = 0

                    var condition : Int = 0

                    var city : String = ""

                    var weatherIconName : String = ""

                  

                  

                    //This method turns a condition code into the name of the weather condition image

                  

                    func updateWeatherIcon(condition: Int) -> String {

                      

                    switch (condition) {

                  

                        case 0...300 :

                            return "tstorm1"

                      

                        case 301...500 :

                            return "light_rain"

                      

                        case 501...600 :

                            return "shower3"

                      

                        case 601...700 :

                            return "snow4"

                      

                        case 701...771 :

                            return "fog"

                      

                        case 772...799 :

                            return "tstorm3"

                      

                        case 800 :

                            return "sunny"

                      

                        case 801...804 :

                            return "cloudy2"

                      

                        case 900...903, 905...1000  :

                            return "tstorm3"

                      

                        case 903 :

                            return "snow5"

                      

                        case 904 :

                            return "sunny"

                      

                        default :

                            return "dunno"

                        }

                 

                    }

                }

                  • Re: Showing property in tablecell
                    net777 Level 1 Level 1 (0 points)

                    import UIKit

                     

                    class TrainDataModel {

                      

                        //Declare your model variables here

                        var station : String = ""

                        //var arrivalTime : Date? = nil

                        var arrivalTime : String = ""

                    }

                      • Re: Showing property in tablecell
                        net777 Level 1 Level 1 (0 points)

                        import UIKit

                        import CoreLocation

                        import Alamofire

                        import SwiftyJSON

                         

                         

                        class WeatherViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource {

                          

                          

                            //Constants

                            let APP_ID_TRAIN2 =

                            let APP_ID_SEARCH_STATION =

                            let WEATHER_URL = "

                            let TRAIN_URL = "

                            //let TRAIN_URL =

                            let TRAIN_URL2 =

                            let TRAIN_URL3 =

                            let APP_ID =

                          

                          

                         

                         

                            //TODO: Declare instance variables here

                            let locationManager = CLLocationManager()

                            let weatherDataModel = WeatherDataModel()

                            let trainDataModel = TrainDataModel() //Object

                          

                            //Pre-linked IBOutlets

                            @IBOutlet weak var weatherIcon: UIImageView!

                            @IBOutlet weak var cityLabel: UILabel!

                            @IBOutlet weak var temperatureLabel: UILabel!

                         

                          

                            override func viewDidLoad() {

                                super.viewDidLoad()

                              

                              

                                //TODO:Set up the location manager here.

                                locationManager.delegate = self

                                locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters

                                locationManager.requestWhenInUseAuthorization()

                                locationManager.startUpdatingLocation()

                              

                              

                            }

                          • Re: Showing property in tablecell
                            net777 Level 1 Level 1 (0 points)

                            //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! Got the weather data")

                                          

                                            let weatherJSON : JSON = JSON(response.result.value!)

                                            self.updateWeatherData(json: weatherJSON)

                                            //print(weatherJSON)

                                        }

                                        else {

                                            print("Error \(String(describing: response.result.error))")

                                            self.cityLabel.text = "Connection problem"

                                        }

                                    }

                                }

                              

                              

                                func getTrainData(url: String) {

                                  

                                    Alamofire.request(url).responseJSON {

                                        response in

                                        if response.result.isSuccess {

                                            //print("Success! Got the train data")

                                          

                                            let trainJSON : JSON = JSON(response.result.value!)

                                            self.updateTrainData(json: trainJSON)

                                            //print(trainJSON)

                                        }

                                        else {

                                            print("Error \(String(describing: response.result.error))")

                                            self.cityLabel.text = "Connection problem"

                                        }

                                    }

                              

                                }

                              • Re: Showing property in tablecell
                                net777 Level 1 Level 1 (0 points)

                                //MARK: - JSON Parsing

                                    /***************************************************************/

                                 

                                  

                                    //Write the updateWeatherData method here:

                                    func updateWeatherData(json : JSON) {

                                      

                                      

                                        //let tempResult = json["main"]["temp"]

                                      

                                        //print("Test", tempResult)

                                      

                                        if let tempResult = json["main"]["temp"].double {

                                      

                                            weatherDataModel.temperature = Int(tempResult - 273.15)

                                      

                                            weatherDataModel.city = json["name"].stringValue

                                      

                                            weatherDataModel.condition = json["weather"][0]["id"].intValue

                                      

                                            weatherDataModel.weatherIconName = weatherDataModel.updateWeatherIcon(condition: weatherDataModel.condition)

                                          

                                            updateUIWithWeatherData()

                                        }

                                        else {

                                            cityLabel.text = "Väderdata kunde inte visas"

                                        }

                                    }

                                    //Write the updateWeatherData method here:

                                    func updateTrainData(json : JSON) {

                                      

                                        //let tempResult = json["StopLocation"][2]["name"]

                                        //let tempResult = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].string

                                        //print("Train", tempResult)

                                 

                                      

                                 

                                        if let tempResult = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].string {

                                          

                                            trainDataModel.station = tempResult

                                          

                                            trainDataModel.arrivalTime = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["arrTime"].stringValue

                                          

                                            print(trainDataModel.arrivalTime)

                                          

                                            updateUIWithTrainData()

                                        }

                                        else {

                                            cityLabel.text = "Tågdata kunde inte visas"

                                        }

                                      

                                    }

                                  • Re: Showing property in tablecell
                                    net777 Level 1 Level 1 (0 points)

                                    //MARK: - UI Updates

                                        /***************************************************************/

                                      

                                      

                                        //Write the updateUIWithWeatherData method here:

                                      

                                        func updateUIWithWeatherData() {

                                          

                                            cityLabel.text = weatherDataModel.city

                                            temperatureLabel.text = String(weatherDataModel.temperature)

                                            weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)

                                          

                                          

                                        }

                                      

                                        func updateUIWithTrainData() {

                                          

                                            //cityLabel.text = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].stringValue

                                            //temperatureLabel.text = String(weatherDataModel.temperature)

                                            //weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)

                                          

                                            //cityLabel.text = trainDataModel.station

                                            //temperatureLabel.text = trainDataModel.arrivalTime

                                          

                                        }

                                      • Re: Showing property in tablecell
                                        net777 Level 1 Level 1 (0 points)

                                        //MARK: - Location Manager Delegate Methods

                                            /***************************************************************/

                                          

                                          

                                            //Write the didUpdateLocations method here:

                                            func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

                                                let location  = locations[locations.count - 1] //tar sista vördet

                                                if location.horizontalAccuracy > 0 {

                                                    locationManager.stopUpdatingLocation()

                                                    locationManager.delegate = nil

                                                  

                                                    print("longitude = \(location.coordinate.longitude), latitude = \(location.coordinate.latitude)")

                                                  

                                                    let latitude = String(location.coordinate.latitude)

                                                    let longitude = String(location.coordinate.longitude)

                                                  

                                                    let params : [String : String] = ["lat" : latitude, "lon" : longitude, "appid" : APP_ID]

                                                  

                                                    getWeatherData(url : WEATHER_URL, parameters: params)

                                                  

                                                    getTrainData(url: TRAIN_URL)

                                                  

                                                  

                                                   // cityLabel.text = "Hittade plats!"

                                                  

                                                }

                                            }

                                          

                                          

                                            //Write the didFailWithError method here:

                                            func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

                                                print(error)

                                                cityLabel.text = "Hittar ej plats"

                                            }

                                          

                                          

                                            //MARK: - Change City Delegate methods

                                            /***************************************************************/

                                          

                                          

                                            //Write the userEnteredANewCityName Delegate method here:

                                          

                                         

                                          

                                            //Write the PrepareForSegue Method here

                                          

                                          

                                          

                                            //MARK: - TableView methods

                                            /***************************************************************/

                                          

                                            func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

                                                return 3

                                            }

                                          

                                            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

                                              

                                               let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")

                                          

                                                cell.textLabel?.text = weatherDataModel.city

                                             

                                                //cell.textLabel?.text = "test"

                                              

                                                return cell

                                              

                                              

                                            }

                                        }

                                          • Re: Showing property in tablecell
                                            OOPer Level 8 Level 8 (5,415 points)

                                            Thanks for showing your code.

                                             

                                            As far as I checked your currently visible code:

                                             

                                            - Your WeatherViewController lacks the property holding the UITableView, you usually make it an IBOutlet and connect it on the storyboard.

                                            class WeatherViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource {
                                                //...
                                                
                                                @IBOutlet weak var tableView: UITableView! //<-
                                            
                                                //...
                                            }
                                            

                                            - You are not setting the delegate and the dataSource of the table view in code. You can do it on the storyboard, but I recommend you to do it by code.

                                                override func viewDidLoad() {
                                                    super.viewDidLoad()
                                                    
                                                    tableView.delegate = self   //<-
                                                    tableView.dataSource = self //<-
                                            
                                                    //...
                                                }
                                            

                                             

                                            - You are not calling `reloadData()` when the models are updated.

                                                func updateUIWithWeatherData() {
                                                    
                                                    cityLabel.text = weatherDataModel.city
                                                    temperatureLabel.text = String(weatherDataModel.temperature)
                                                    weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)
                                                    
                                                    tableView.reloadData() //<-
                                                }
                                                
                                                func updateUIWithTrainData() {
                                                    
                                                    //cityLabel.text = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].stringValue
                                                    //temperatureLabel.text = String(weatherDataModel.temperature)
                                                    //weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)
                                                    
                                                    //cityLabel.text = trainDataModel.station
                                                    //temperatureLabel.text = trainDataModel.arrivalTime
                                                    
                                                    tableView.reloadData() //<-
                                                }
                                            
                                            

                                             

                                            Of course your `tableView(_:cellForRowAt:)` should be updated as suggested by Claude31.

                                          • Re: Showing property in tablecell
                                            Claude31 Level 8 Level 8 (6,595 points)

                                            OK, I copied in a single file and use code formatter to make it easier to read

                                             

                                             

                                            import UIKit
                                            
                                            class WeatherDataModel {
                                              
                                                //Declare your model variables here
                                                var temperature : Int = 0
                                                var condition : Int = 0
                                                var city : String = ""
                                                var weatherIconName : String = ""
                                              
                                                //This method turns a condition code into the name of the weather condition image
                                              
                                                func updateWeatherIcon(condition: Int) -> String {
                                                  
                                                    switch (condition) {
                                                      
                                                    case 0...300 :
                                                        return "tstorm1"
                                                      
                                                    case 301...500 :
                                                        return "light_rain"
                                                      
                                                    case 501...600 :
                                                        return "shower3"
                                                      
                                                    case 601...700 :
                                                        return "snow4"
                                                      
                                                    case 701...771 :
                                                        return "fog"
                                                      
                                                    case 772...799 :
                                                        return "tstorm3"
                                                      
                                                    case 800 :
                                                        return "sunny"
                                                      
                                                    case 801...804 :
                                                        return "cloudy2"
                                                      
                                                    case 900...903, 905...1000  :
                                                        return "tstorm3"
                                                      
                                                    case 903 :
                                                        return "snow5"
                                                      
                                                    case 904 :
                                                        return "sunny"
                                                      
                                                    default :
                                                        return "dunno"
                                                    }
                                                  
                                                }
                                            }
                                            
                                            class TrainDataModel {
                                              
                                                //Declare your model variables here
                                                var station : String = ""
                                                //var arrivalTime : Date? = nil
                                                var arrivalTime : String = ""
                                            }
                                            
                                            import CoreLocation
                                            
                                            class WeatherViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource {
                                              
                                                //Constants
                                                let APP_ID_TRAIN2 = ""
                                                let APP_ID_SEARCH_STATION = ""
                                                let WEATHER_URL =  ""
                                                let TRAIN_URL =  ""
                                                //let TRAIN_URL =
                                                let TRAIN_URL2 = ""
                                                let TRAIN_URL3 = ""
                                                let APP_ID = ""
                                              
                                                //TODO: Declare instance variables here
                                                let locationManager = CLLocationManager()
                                                let weatherDataModel = WeatherDataModel()
                                                let trainDataModel = TrainDataModel() //Object
                                              
                                                //Pre-linked IBOutlets
                                                @IBOutlet weak var weatherIcon: UIImageView!
                                                @IBOutlet weak var cityLabel: UILabel!
                                                @IBOutlet weak var temperatureLabel: UILabel!
                                               
                                                override func viewDidLoad() {
                                                    super.viewDidLoad()
                                                   
                                                    //TODO:Set up the location manager here.
                                                    locationManager.delegate = self
                                                    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
                                                    locationManager.requestWhenInUseAuthorization()
                                                    locationManager.startUpdatingLocation()
                                            }
                                            
                                            
                                                //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! Got the weather data")
                                                          
                                                            let weatherJSON : JSON = JSON(response.result.value!)
                                                            self.updateWeatherData(json: weatherJSON)
                                                            //print(weatherJSON)
                                                        }
                                                        else {
                                                            print("Error \(String(describing: response.result.error))")
                                                            self.cityLabel.text = "Connection problem"
                                                        }
                                                    }
                                                }
                                              
                                              
                                                func getTrainData(url: String) {
                                                  
                                                    Alamofire.request(url).responseJSON {
                                                        response in
                                                        if response.result.isSuccess {
                                                            //print("Success! Got the train data")
                                                          
                                                            let trainJSON : JSON = JSON(response.result.value!)
                                                            self.updateTrainData(json: trainJSON)
                                                            //print(trainJSON)
                                                        }
                                                        else {
                                                            print("Error \(String(describing: response.result.error))")
                                                            self.cityLabel.text = "Connection problem"
                                                        }
                                                    }
                                                  
                                            }
                                            
                                                //MARK: - JSON Parsing
                                                /***************************************************************/
                                              
                                              
                                                //Write the updateWeatherData method here:
                                                func updateWeatherData(json : JSON) {
                                                  
                                                  
                                                    //let tempResult = json["main"]["temp"]
                                                  
                                                    //print("Test", tempResult)
                                                  
                                                    if let tempResult = json["main"]["temp"].double {
                                                      
                                                        weatherDataModel.temperature = Int(tempResult - 273.15)
                                                      
                                                        weatherDataModel.city = json["name"].stringValue
                                                      
                                                        weatherDataModel.condition = json["weather"][0]["id"].intValue
                                                      
                                                        weatherDataModel.weatherIconName = weatherDataModel.updateWeatherIcon(condition: weatherDataModel.condition)
                                                      
                                                        updateUIWithWeatherData()
                                                    }
                                                    else {
                                                        cityLabel.text = "Väderdata kunde inte visas"
                                                    }
                                                }
                                            
                                                //Write the updateWeatherData method here:
                                                func updateTrainData(json : JSON) {
                                                  
                                                    //let tempResult = json["StopLocation"][2]["name"]
                                                    //let tempResult = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].string
                                                    //print("Train", tempResult)
                                                  
                                                    if let tempResult = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].string {
                                                      
                                                        trainDataModel.station = tempResult
                                                      
                                                        trainDataModel.arrivalTime = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["arrTime"].stringValue
                                                      
                                                        print(trainDataModel.arrivalTime)
                                                      
                                                        updateUIWithTrainData()
                                                    }
                                                    else {
                                                        cityLabel.text = "Tågdata kunde inte visas"
                                                    }
                                                  
                                            }
                                            
                                                //MARK: - UI Updates
                                                /***************************************************************/
                                              
                                                //Write the updateUIWithWeatherData method here:
                                              
                                                func updateUIWithWeatherData() {
                                                  
                                                    cityLabel.text = weatherDataModel.city
                                                    temperatureLabel.text = String(weatherDataModel.temperature)
                                                    weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)
                                                }
                                              
                                                func updateUIWithTrainData() {
                                                  
                                                    //cityLabel.text = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].stringValue
                                                    //temperatureLabel.text = String(weatherDataModel.temperature)
                                                    //weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)
                                                  
                                                    //cityLabel.text = trainDataModel.station
                                                    //temperatureLabel.text = trainDataModel.arrivalTime
                                                  
                                                 }          // Closing } missing here ?
                                            }

                                             

                                            Several questions: this is not the exact copy of your code ? It cannot compile.

                                             

                                            1. Is all this inside the class WeatherViewController ?

                                            If so, you need an } to end the class (added line 215)

                                             

                                            2. Const are not defined (lines 70 to 77)

                                            I added = ""

                                             

                                            3. weatherDataModel.city is only set line 158 in updateWeatherData, which is called in getWeatherData

                                            Are you sure you get there ? Could you reset the comments lines 109 and 113 and tell what you get ?

                                             

                                            4. You have not included the func tableView()  functions.

                                             

                                            So, please post the complete and real code of the class, not skipping some parts that are critical, and use the code formatter (<>) to make it easier to read.

                                              • Re: Showing property in tablecell
                                                net777 Level 1 Level 1 (0 points)

                                                Well, I had trouble to post. I'll try again.

                                                1. I think you missed some which is easy because of the way I posted. I probably missed the end of class.

                                                2. The const I left out are the URL for the JSON-call. I try to leave the in using your proposed method. I leave some out that I only used for testing.

                                                 

                                                3. Yes, I'm sure I get there. In updateUIWithWeatherData() print out the value in a label, and that works.

                                                4. I think I had that but as I said easy to miss. Placed the two functions needed for TableView last in the file.

                                                Thank you for showing a way to easier show the code.

                                                 

                                                <

                                                //

                                                //  ViewController.swift

                                                //  WeatherApp

                                                //

                                                //  Created by Angela Yu on 23/08/2015.

                                                //  Copyright (c) 2015 London App Brewery. All rights reserved.

                                                //

                                                 

                                                import UIKit

                                                import CoreLocation

                                                import Alamofire

                                                import SwiftyJSON

                                                 

                                                 

                                                class WeatherViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource {

                                                 

                                                 

                                                    //Constants

                                                    let APP_ID_TRAIN2 = "9ad33f89-ad4d-4705-a7e9-b48a654064c6"

                                                    let APP_ID_SEARCH_STATION = "332b6bdc-5bb8-4ff3-8e71-870e78bb465c"

                                                    let WEATHER_URL = "h t t p: / / a p i.openweathermap.org/data/2.5/weather"

                                                    let TRAIN_URL = "h t t ps : / / a p i  .resrobot.se/v2/trip?key=332b6bdc-5bb8-4ff3-8e71-870e78bb465c&originId=740098548&destId=740000006&format=json&products=16" //Sök mellan två platser

                                                 

                                                 

                                                    let APP_ID = "9b1864136739f58051bf9949784b3497"

                                                 

                                                 

                                                 

                                                    //TODO: Declare instance variables here

                                                    let locationManager = CLLocationManager()

                                                    let weatherDataModel = WeatherDataModel()

                                                    let trainDataModel = TrainDataModel() //Object

                                                 

                                                    //Pre-linked IBOutlets

                                                    @IBOutlet weak var weatherIcon: UIImageView!

                                                    @IBOutlet weak var cityLabel: UILabel!

                                                    @IBOutlet weak var temperatureLabel: UILabel!

                                                 

                                                 

                                                    override func viewDidLoad() {

                                                        super.viewDidLoad()

                                                 

                                                 

                                                        //TODO:Set up the location manager here.

                                                        locationManager.delegate = self

                                                        locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters

                                                        locationManager.requestWhenInUseAuthorization()

                                                        locationManager.startUpdatingLocation()

                                                 

                                                 

                                                    }

                                                 

                                                 

                                                    //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! Got the weather data")

                                                  

                                                                let weatherJSON : JSON = JSON(response.result.value!)

                                                                self.updateWeatherData(json: weatherJSON)

                                                                print(weatherJSON)

                                                            }

                                                            else {

                                                                print("Error \(String(describing: response.result.error))")

                                                                self.cityLabel.text = "Connection problem"

                                                            }

                                                        }

                                                    }

                                                 

                                                 

                                                    func getTrainData(url: String) {

                                                 

                                                        Alamofire.request(url).responseJSON {

                                                            response in

                                                            if response.result.isSuccess {

                                                                //print("Success! Got the train data")

                                                  

                                                                let trainJSON : JSON = JSON(response.result.value!)

                                                                self.updateTrainData(json: trainJSON)

                                                                //print(trainJSON)

                                                            }

                                                            else {

                                                                print("Error \(String(describing: response.result.error))")

                                                                self.cityLabel.text = "Connection problem"

                                                            }

                                                        }

                                                 

                                                    }

                                                 

                                                 

                                                 

                                                    //MARK: - JSON Parsing

                                                    /***************************************************************/

                                                 

                                                 

                                                    //Write the updateWeatherData method here:

                                                    func updateWeatherData(json : JSON) {

                                                 

                                                 

                                                        //let tempResult = json["main"]["temp"]

                                                 

                                                        //print("Test", tempResult)

                                                 

                                                        if let tempResult = json["main"]["temp"].double {

                                                 

                                                            weatherDataModel.temperature = Int(tempResult - 273.15)

                                                 

                                                            weatherDataModel.city = json["name"].stringValue

                                                 

                                                            weatherDataModel.condition = json["weather"][0]["id"].intValue

                                                 

                                                            weatherDataModel.weatherIconName = weatherDataModel.updateWeatherIcon(condition: weatherDataModel.condition)

                                                 

                                                            updateUIWithWeatherData()

                                                        }

                                                        else {

                                                            cityLabel.text = "Väderdata kunde inte visas"

                                                        }

                                                    }

                                                    //Write the updateWeatherData method here:

                                                    func updateTrainData(json : JSON) {

                                                 

                                                        //let tempResult = json["StopLocation"][2]["name"]

                                                        //let tempResult = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].string

                                                        //print("Train", tempResult)

                                                 

                                                 

                                                 

                                                        if let tempResult = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].string {

                                                 

                                                            trainDataModel.station = tempResult

                                                 

                                                            trainDataModel.arrivalTime = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["arrTime"].stringValue

                                                 

                                                            print(trainDataModel.arrivalTime)

                                                 

                                                            updateUIWithTrainData()

                                                        }

                                                        else {

                                                            cityLabel.text = "Tågdata kunde inte visas"

                                                        }

                                                 

                                                    }

                                                 

                                                 

                                                    //MARK: - UI Updates

                                                    /***************************************************************/

                                                 

                                                 

                                                    //Write the updateUIWithWeatherData method here:

                                                 

                                                    func updateUIWithWeatherData() {

                                                 

                                                        cityLabel.text = weatherDataModel.city

                                                        temperatureLabel.text = String(weatherDataModel.temperature)

                                                        weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)

                                                 

                                                 

                                                    }

                                                 

                                                    func updateUIWithTrainData() {

                                                 

                                                        //cityLabel.text = json["Trip"][0]["LegList"]["Leg"][0]["Stops"]["Stop"][1]["name"].stringValue

                                                        //temperatureLabel.text = String(weatherDataModel.temperature)

                                                        //weatherIcon.image = UIImage(named: weatherDataModel.weatherIconName)

                                                 

                                                        //cityLabel.text = trainDataModel.station

                                                        //temperatureLabel.text = trainDataModel.arrivalTime

                                                 

                                                    }

                                                 

                                                 

                                                    //MARK: - Location Manager Delegate Methods

                                                    /***************************************************************/

                                                 

                                                 

                                                    //Write the didUpdateLocations method here:

                                                    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

                                                        let location  = locations[locations.count - 1] //tar sista vördet

                                                        if location.horizontalAccuracy > 0 {

                                                            locationManager.stopUpdatingLocation()

                                                            locationManager.delegate = nil

                                                 

                                                            print("longitude = \(location.coordinate.longitude), latitude = \(location.coordinate.latitude)")

                                                 

                                                            let latitude = String(location.coordinate.latitude)

                                                            let longitude = String(location.coordinate.longitude)

                                                 

                                                            let params : [String : String] = ["lat" : latitude, "lon" : longitude, "appid" : APP_ID]

                                                 

                                                            getWeatherData(url : WEATHER_URL, parameters: params)

                                                 

                                                            getTrainData(url: TRAIN_URL)

                                                 

                                                 

                                                          // cityLabel.text = "Hittade plats!"

                                                 

                                                        }

                                                    }

                                                 

                                                 

                                                    //Write the didFailWithError method here:

                                                    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

                                                        print(error)

                                                        cityLabel.text = "Hittar ej plats"

                                                    }

                                                 

                                                 

                                                    //MARK: - Change City Delegate methods

                                                    /***************************************************************/

                                                 

                                                 

                                                    //Write the userEnteredANewCityName Delegate method here:

                                                 

                                                 

                                                 

                                                    //Write the PrepareForSegue Method here

                                                 

                                                 

                                                 

                                                    //MARK: - TableView methods

                                                    /***************************************************************/

                                                 

                                                    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

                                                        return 3

                                                    }

                                                 

                                                    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

                                                 

                                                      let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")

                                                 

                                                        cell.textLabel?.text = weatherDataModel.city

                                                 

                                                        //cell.textLabel?.text = "test"

                                                 

                                                        return cell

                                                 

                                                 

                                                    }

                                                }

                                                 

                                                 

                                                 

                                                 

                                                 

                                                >

                                                • Re: Showing property in tablecell
                                                  net777 Level 1 Level 1 (0 points)

                                                  Hi! I really appreciate your help.

                                                  I am trying to post in one file but keep getting the message "being moderated"

                                                  Thinking that the links are the problem I removed som of the link for weather_URL and TRAIN_URL.

                                                  Weather_URL are from the course I'm following and TRAIN_URL are my own testing.

                                                  If the file is approved I have tried to anwer your question.

                                                   

                                                  The removal of the links didn't seem to help, and you need the links anyway. Adding space didn't seem to help-

                                                  If you doesn't have a solution I just have to wait until it is approved.

                                    • Re: Showing property in tablecell
                                      net777 Level 1 Level 1 (0 points)

                                      So this is what I get after trying the suggestions from OOPer.


                                      Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

                                      I think I somewhat understand Optionals but not entirely.

                                      It does suggest I guess that the object in tableView is empty. I don't understand why since.it's set in updateWeatherData.

                                      I have already connected to delegate and source in storyboard if that matters.

                                        • Re: Showing property in tablecell
                                          OOPer Level 8 Level 8 (5,415 points)

                                          When you get Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value, the first thing you need to do is finding on which line this runtime-error has occurred.

                                           

                                          Something is nil, that should not be nil included in the line.

                                           

                                          For example, if you get that error on this line:

                                          tableView.delegate = self

                                          Then `tableView` is nil, that should not be nil. This happens when you do not connect the IBOutlet properly.

                                           

                                          So, on which line that is happening?

                                            • Re: Showing property in tablecell
                                              net777 Level 1 Level 1 (0 points)

                                              Yes, it is at the line

                                              tableView.delegate = self 
                                              That the error fist occurs.

                                              But I can show a value set in

                                              func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

                                               

                                              But not the value from the model.

                                              So I can do

                                               

                                              cell.textLabel?.text = "test"

                                               

                                              But not

                                               

                                              cell.textLabel?.text = self.weatherDataModel.city

                                               

                                              But I know that the value is set in function

                                               

                                              updateWeatherData

                                               

                                               

                                          • Re: Showing property in tablecell
                                            net777 Level 1 Level 1 (0 points)

                                            It worked!

                                             

                                            Thank you both!

                                            I'm sorry that I couldn't mark both as correct answers.

                                            Clearly I have to learn more about the basics.

                                            One question: Could I have made this connection completely in code?

                                             

                                            Question two: I want to display two values in one cell. The staition from the API on the left and the time on the right.

                                             

                                            Without explaining everything, could you give me a hint to the right solution?