Tuesday, June 16, 2026
HomeiOS Developmentios - Cannot get the worth from view mannequin within the cell

ios – Cannot get the worth from view mannequin within the cell

[ad_1]

I am engaged on climate tracker and need to show some information in my ViewController, however I do not perceive why some worth from my view mannequin is on closure, however not displayed in my assortment view

JSON

{
    "cod": "200",
    "message": 0,
    "cnt": 3,
    "listing": [
        {
            "dt": 1638370800,
            "main": {
                "temp": 282.21,
                "feels_like": 279.54,
                "temp_min": 281.53,
                "temp_max": 282.21,
                "pressure": 998,
                "sea_level": 998,
                "grnd_level": 995,
                "humidity": 71,
                "temp_kf": 0.68
            },
            "weather": [
                {
                    "id": 500,
                    "main": "Rain",
                    "description": "light rain",
                    "icon": "10d"
                }
            ],
            "clouds": {
                "all": 79
            },
            "wind": {
                "velocity": 5.05,
                "deg": 288,
                "gust": 10.52
            },
            "visibility": 10000,
            "pop": 0.48,
            "rain": {
                "3h": 0.21
            },
            "sys": {
                "pod": "d"
            },
            "dt_txt": "2021-12-01 15:00:00"
        },
        {
            "dt": 1638381600,
            "major": {
                "temp": 280.71,
                "feels_like": 277.76,
                "temp_min": 279.79,
                "temp_max": 280.71,
                "stress": 1000,
                "sea_level": 1000,
                "grnd_level": 998,
                "humidity": 76,
                "temp_kf": 0.92
            },
            "climate": [
                {
                    "id": 500,
                    "main": "Rain",
                    "description": "light rain",
                    "icon": "10n"
                }
            ],
            "clouds": {
                "all": 87
            },
            "wind": {
                "velocity": 4.84,
                "deg": 20,
                "gust": 10.28
            },
            "visibility": 10000,
            "pop": 0.88,
            "rain": {
                "3h": 1.15
            },
            "sys": {
                "pod": "n"
            },
            "dt_txt": "2021-12-01 18:00:00"
        },
        {
            "dt": 1638392400,
            "major": {
                "temp": 278.21,
                "feels_like": 274.28,
                "temp_min": 278.21,
                "temp_max": 278.21,
                "stress": 1005,
                "sea_level": 1005,
                "grnd_level": 1002,
                "humidity": 72,
                "temp_kf": 0
            },
            "climate": [
                {
                    "id": 803,
                    "main": "Clouds",
                    "description": "broken clouds",
                    "icon": "04n"
                }
            ],
            "clouds": {
                "all": 73
            },
            "wind": {
                "velocity": 5.62,
                "deg": 345,
                "gust": 10.72
            },
            "visibility": 10000,
            "pop": 0.39,
            "sys": {
                "pod": "n"
            },
            "dt_txt": "2021-12-01 21:00:00"
        }
    ],
    "metropolis": {
        "id": 2643743,
        "identify": "London",
        "coord": {
            "lat": 51.5085,
            "lon": -0.1257
        },
        "nation": "GB",
        "inhabitants": 1000000,
        "timezone": 0,
        "dawn": 1638344651,
        "sundown": 1638374122
    }
}

My struct

struct TwentyFourHoursCitiesWeather: Decodable {
    let cod: String
    let message, cnt: Int
    let listing: [List]
    let metropolis: Metropolis
}

// MARK: - Metropolis
struct Metropolis: Decodable {
    let id: Int
    let identify: String
    let coord: Coord
    let nation: String
    let inhabitants, timezone, dawn, sundown: Int
}

// MARK: - Coord
struct Coord: Decodable {
    let lat, lon: Double
}

// MARK: - Listing
struct Listing: Decodable {
    let dt: Int
    let major: TwentyFourHoursMain
    let climate: [TwentyFourHoursWeather]
    let clouds: TwentyFourHoursClouds
    let wind: TwentyFourHoursWind
    let visibility: Int
    let pop: Double
    let rain: Rain?
    let sys: TwentyFourHoursSys
    let dtTxt: String

    enum CodingKeys: String, CodingKey {
        case dt, major, climate, clouds, wind, visibility, pop, rain, sys
        case dtTxt = "dt_txt"
    }
}

// MARK: - Clouds
struct TwentyFourHoursClouds: Decodable {
    let all: Int
}

// MARK: - Major
struct TwentyFourHoursMain: Decodable {
    let temp, feelsLike, tempMin, tempMax: Double
    let stress, seaLevel, grndLevel, humidity: Int
    let tempKf: Double

    enum CodingKeys: String, CodingKey {
        case temp
        case feelsLike = "feels_like"
        case tempMin = "temp_min"
        case tempMax = "temp_max"
        case stress
        case seaLevel = "sea_level"
        case grndLevel = "grnd_level"
        case humidity
        case tempKf = "temp_kf"
    }
}

// MARK: - Rain
struct Rain: Decodable {
    let the3H: Double

    enum CodingKeys: String, CodingKey {
        case the3H = "3h"
    }
}

// MARK: - Sys
struct TwentyFourHoursSys: Decodable {
    let pod: String
}

// MARK: - Climate
struct TwentyFourHoursWeather: Decodable {
    let id: Int
    let major, weatherDescription, icon: String

    enum CodingKeys: String, CodingKey {
        case id, major
        case weatherDescription = "description"
        case icon
    }
}

// MARK: - Wind
struct TwentyFourHoursWind: Decodable {
    let velocity: Double
    let deg: Int
    let gust: Double
}

My WeatherService, once I get information:

protocol ITwentyFourHoursWeatherService {
    
    func getCitiesWeather(completion: @escaping (Outcome<TwentyFourHoursCitiesWeather, Error>) -> Void)
}

enum TwentyFourHoursWeatherServiceError: Error {
    case badUrl
}

non-public extension String {
    static let url = "https://api.openweathermap.org/information/2.5/forecast?q=London&cnt=3&appid=KEY"
}
    
remaining class TwentyFourHoursWeatherService: ITwentyFourHoursWeatherService {

    func getCitiesWeather(completion: @escaping (Outcome<TwentyFourHoursCitiesWeather, Error>) -> Void) {
        guard let url = URL(string: .url) else {
            return completion(.failure(TwentyFourHoursWeatherServiceError.badUrl))
        }

        let process = URLSession.shared.dataTask(with: url) { information, response, error in
            guard let information = information, error == nil else { return }

            do {
                let outcome = attempt JSONDecoder().decode(TwentyFourHoursCitiesWeather.self, from: information)
                completion(.success(outcome))
                print("24 weatherService: (outcome.listing[0].major.temp)") <--I get information right here
            } catch {
                print("did not convert (error)")
            }
        }

        process.resume()
    }

}

My ViewModel:

class TwentyFourHoursViewModel {

// MARK: -Properties
let twentyFourHoursWeatherService: ITwentyFourHoursWeatherService

var twentyFourHoursWeather: TwentyFourHoursMainScreenWeatherModel?

init(twentyFourHoursWeatherService: ITwentyFourHoursWeatherService) {
    self.twentyFourHoursWeatherService = twentyFourHoursWeatherService
}

func twentyFourHoursViewDidLoad() {
    
    twentyFourHoursWeatherService.getCitiesWeather { [weak self] end in
        
        swap outcome {
        case .success(let outcome):
            self?.twentyFourHoursWeather = .init(
                twentyFourHoursTime: outcome.listing[2].dtTxt ,
                twentyFourHoursIcon: "sundown",
                twentyFourHoursTemp: outcome.listing[1].major.temp
            )
            self?.twentyFourHoursWeatherDidChange?()
            print("In twentyFourHoursViewModel: (outcome.listing[0].major.temp)") <-- Get information right here
        case .failure(let error):
            print(error.localizedDescription)
        }
    }
}

var twentyFourHoursWeatherDidChange: (() -> Void)?

My ViewController:

class MainScrenenViewController: UIViewController {
    
    let twentyFourHoursViewModel: TwentyFourHoursViewModel
    
    //CollectionView 
    var todayCollectionView: UICollectionView = {
        let structure = UICollectionViewFlowLayout()
        structure.scrollDirection = .horizontal
        let todayCollectionView = UICollectionView(body: .zero, collectionViewLayout: structure)
        todayCollectionView.register(TwentyFourHoursCollectionViewCell.self, forCellWithReuseIdentifier: "todayCell")
        todayCollectionView.translatesAutoresizingMaskIntoConstraints = false
        todayCollectionView.backgroundColor = .white
        return todayCollectionView
    }()
    
    //MARK: - Initialization
    
    init(twentyFourHoursViewModel: TwentyFourHoursViewModel) {
        self.twentyFourHoursViewModel = twentyFourHoursViewModel
        tremendous.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been applied")
    }
    
    //MARK: - Lifecycle
    
    override func viewDidLoad() {
        tremendous.viewDidLoad()
        
        view.backgroundColor = .white
        
        view.addSubview(todayCollectionView)
        
        todayCollectionView.dataSource = self
        todayCollectionView.delegate = self
        
        setupConstraints()
        
        twentyFourHoursViewModel.twentyFourHoursWeatherDidChange = {
            DispatchQueue.major.async {
                self.collectionView.reloadData()
                print("Значение из замыкания: (self.twentyFourHoursViewModel.twentyFourHoursWeather?.twentyFourHoursTemp)") <--And I get information right here
            }
        }
        
        twentyFourHoursViewModel.twentyFourHoursViewDidLoad()
        
    }
    
//MARK: - Assortment

extension MainScrenenViewController: UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection part: Int) -> Int {
        
            return 3
    
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
            let cellTwo = collectionView.dequeueReusableCell(withReuseIdentifier: "todayCell", for: indexPath) as! TwentyFourHoursCollectionViewCell
        
            if let temp: String? = String(twentyFourHoursViewModel.twentyFourHoursWeather?.twentyFourHoursTemp ?? 1.1) {
                cellTwo.mainTemperatureLabel.textual content = temp
                print("Значение в ячейке: (temp)") <-- There's nil right here
            }
 
        return cellTwo
}

Assortment View Cell

class TwentyFourHoursCollectionViewCell: UICollectionViewCell {
    
    var mainTemperatureLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont(identify: "Rubik-Medium", dimension: 16)
        label.textColor = .black
        label.textAlignment = .heart
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    override init(body: CGRect) {
        tremendous.init(body: body)
        
        contentView.addSubview(mainTemperatureLabel)
        
        //self.contentView.layer.cornerRadius = 10
        
        let constraints = [
            
            mainTemperatureLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            mainTemperatureLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
            mainTemperatureLabel.heightAnchor.constraint(equalToConstant: 30),
            mainTemperatureLabel.widthAnchor.constraint(equalToConstant: 30),
        
        ]
        NSLayoutConstraint.activate(constraints)
    }
    
    required init?( coder: NSCoder) {
        fatalError("init(coder:) has not been applied")
    }
    
}

enter picture description right here

[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments