Showing property in tablecell

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

}

Answered by OOPer in 369478022

But I can show a value set in


That has nothing to do with IBOutlet connection.


You need to open the storyboard editor and connect your Table View in design canvas to the IBOutlet `tableView` in the code.

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
    }

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.

When you say: Your code shows nothing.

What do you get as result of print ?


        print("weatherDataModel.city", weatherDataModel.city)


Could you show the complete code of the viewController ? To see where each function is called.

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.

I am not at my computer right now, and will send the complete code when I am.


when I print out your code I get the string ”weatherDataModel.city” but not the value.


In ”updateWeatherData” I do get the values from the JSON-file but not in the TableView as it seems.


I don’t understand why.

I print out your code I get the string ”weatherDataModel.city” but not the value.


I guess it's for Claude31's reply and not for John368's.

Anyway readers don't understand what's happening without your code. Waiting for enough code.

Just means that the value is empty

print("weatherDataModel.city", weatherDataModel.city)


So, you get only "weatherDataModel.city"


So, we need to inspect your code to understand why, at this stage, weatherDataModel.city is empty string. Do you confirm that you get the cityname elsewhere ?

"Do you confirm that you get the cityname elsewhere ?"


Yes, I get weatherDataModel.city in updateUIWithWeatherData()

Well, show the complete code as soon as you get access to your computer.

I have tried to show the viewController but it said something about being moderated.
Is it visible to others?

No, not visible.


have you just copied the text ?


It should not contain URL or at least they must be edited as

h ttps://

Yes, just copied the text.


Have removed the links now (for the API)
Let me know if it is visible or what I else can do.

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"

}


}

}

import UIKit


class TrainDataModel {

//Declare your model variables here

var station : String = ""

//var arrivalTime : Date? = nil

var arrivalTime : String = ""

}

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()

}

//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

}

}

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.

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



}

}






>

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.

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.

Thanks! I will try your suggestions when I am at my computer again. I am kind of a beginner and haven’t fully graspt everything. My approach is to make my own app while learning.

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.

Showing property in tablecell
 
 
Q