In this episode, we refactor the CurrentConditionsViewModel struct. Remember that the CurrentConditionsViewModel struct drives the CurrentConditionsView, the top section of the LocationView. The changes we need to make are small.

Refactoring the Current Conditions View Model

Open CurrentConditionsViewModel.swift and declare a private, constant property with name currently of type WeatherData.CurrentConditions.

import Foundation

struct CurrentConditionsViewModel {

    // MARK: - Properties

    private let currently: WeatherData.CurrentConditions

	...

}

Because we declare the currently property privately, we need to declare an initializer that accepts a WeatherData.CurrentConditions object as an argument. In the body of the initializer, we assign the WeatherData.CurrentConditions object to the currently property.

import Foundation

struct CurrentConditionsViewModel {

    // MARK: - Properties

    private let currently: WeatherData.CurrentConditions

	...

    // MARK: - Initialization

    init(currently: WeatherData.CurrentConditions) {
        self.currently = currently
    }

}

The next step is updating the computed summary, windSpeed, and temperature properties of the CurrentConditionsViewModel struct. In the body of the computed summary property, we return the value of the summary property of the WeatherData.CurrentConditions object.

// MARK: - Public API

var summary: String {
    data.summary
}

For the computed windSpeed and temperature properties, we need a ClearSkyFormatter object. Declare a private, constant property with name measurementFormatter. We create a ClearSkyFormatter object and assign the object to the measurementFormatter property.

private let measurementFormatter = ClearSkyFormatter()

In the computed windSpeed property, we invoke the formatWindSpeed(_:) method of the ClearSkyFormatter object, passing in the value of the windSpeed property of the WeatherData.CurrentConditions object.

var windSpeed: String {
    measurementFormatter.formatWindSpeed(data.windSpeed)
}

The implementation of the computed temperature property is similar. We invoke the formatTemperature(_:) method of the ClearSkyFormatter object, passing in the value of the temperature property of the WeatherData.CurrentConditions object.

var temperature: String {
    measurementFormatter.formatTemperature(data.temperature)
}

Updating the Location View Model

Open LocationViewModel.swift. We need to pass a WeatherData.CurrentConditions object to the initializer of the CurrentConditionsViewModel struct. We use stub data for now.

import Foundation

struct LocationViewModel {

    // MARK: - Properties

    private let location: Location

    // MARK: -

    var currentConditionsViewModel: CurrentConditionsViewModel {
        .init(currently: WeatherData.preview.currently)
    }

	...

}

Fixing the Preview

We also need to fix the preview of the CurrentConditionsView. Open CurrentConditionsView.swift and navigate to the CurrentConditionsView_Previews struct. We pass stub data to the initializer of the CurrentConditionsViewModel struct.

struct CurrentConditionsView_Previews: PreviewProvider {
    static var previews: some View {
        CurrentConditionsView(
            viewModel: .init(
                currently: WeatherData.preview.currently
            )
        )
    }
}

What's Next?

Refactoring the CurrentConditionsViewModel struct wasn't too difficult. In the next episode, we refactor the ForecastViewModel struct and the ForecastCellViewModel struct. The steps we need to take are similar.