swiftuitableviewuserdefaults

Struggling to implement specific variables into a table view cell because of user default values missing


I have been working to make a weather feature in my app, which takes API data from Visual Crossing.

The issue is that the data is extracted into my app in a seperate function then that which sets my table view cells in my app.

Here is the code I have so far:

let date1ForTableView = UserDefaults.standard

func didUpdateWeather(weather: WeatherModel) {
    
        DispatchQueue.main.async {
              
                self.date1ForTableView.set(weather.datetime1, forKey: "Date1")
    ...
}

...

var WeatherForecastCells: [WeatherCell] = [
        
        
        WeatherCell(image: "", date: date1ForTableView.string(forKey: "Date1")!, low: "18°", high: "31°"),
      ...
   ]

...

extension WeatherFeatures: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return WeatherForecastCells.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "WeatherCellsForWeatherFeature", for: indexPath) as! WeatherForecastTableViewCell

        
        cell.WeatherDetails.text = "\(WeatherForecastCells[indexPath.row].date) - Low: \(WeatherForecastCells[indexPath.row].low) High: \(WeatherForecastCells[indexPath.row].high)"
        
        
        return cell
    }
}

Here is how it works: in the didUpdateWeather() function, the date is saved to a user default value. It is automatically set when the location is entered in the app. For context, we have the data.

What seems to then happen is when I try to set the value in WeatherForecastCells is I get the error "Cannot use instance member 'date1ForTableView' within property initialiser; property initialisers run before 'self' is available" How can I get rid of the above error?


Solution

  • The error is pretty clear. It means you're attempting to get date1ForTableView before self is available. You can take one of the following approaches:

    1. Using lazy to ensure that the initial value is valid before self:
    private lazy var WeatherForecastCells: [WeatherCell] = [
        WeatherCell(image: "", date: date1ForTableView.string(forKey: "Date1")!, low: "18°", high: "31°"),
        ...
    ]
    
    1. Because your date1ForTableView is simply a get for UserDefaults.standard, you may want to replace it with a computed property:
    private var date1ForTableView: UserDefaults {
        .standard
    }
    
    private var WeatherForecastCells: [WeatherCell] = [
        WeatherCell(
            image: "", 
            date: date1ForTableView.string(forKey: "Date1")!, //<- ✅ here
            low: "18°", 
            high: "31°"),
        ...
    ]