如何在 MVVM、iOS、UIKit 中连接两个 ViewModels

问题描述 投票:0回答:1

我正在编写天气应用程序,其中包含两个控制器和两个视图模型 WeatherViewModel 和 SearchViewModel

类 WeatherViewModel {

var searchViewModel: SearchViewModel
var bindableWeather = Bindable<OverallWeatherModel>()


init(searchViewModel: SearchViewModel){
    self.searchViewModel = searchViewModel
    searchViewModel.bindableSearchWeather.bind { [weak self] weather in
        self?.bindableWeather.value = weather
    }
}

}

类 SearchViewModel {

var bindableSearchWeather = Bindable<OverallWeatherModel>()
var searchCity: String? {didSet {fetchCityData(city: searchCity ?? "")}}

fileprivate var overallWeatherModel =  OverallWeatherModel()

fileprivate func fetchCityData(city: String) {
    Service.shared.fetchCityData(city: city) {[weak self] cityGroup in
        guard let city = cityGroup.first else {return}
        self?.overallWeatherModel.city = city.name
        self?.overallWeatherModel.country = city.country
        self?.fetchWeatherData(lat: city.lat, long: city.lon)
    }
}

fileprivate func fetchWeatherData(lat: Double, long: Double) {
    Service.shared.fetchTempData(lat: lat, long: long) {[weak self] weatherGroup in
        self?.overallWeatherModel.date = DateFormat.shared.currentDate()
        self?.overallWeatherModel.temp = Int(weatherGroup.main.temp - 273)
        let weatherIcon = "http://openweathermap.org/img/w/\(weatherGroup.weather?.first?.icon ?? "").png"
        self?.overallWeatherModel.weatherIconUrl = URL(string: weatherIcon)
        self?.overallWeatherModel.windStatus = Int(weatherGroup.wind.speed)
        self?.overallWeatherModel.humidity = weatherGroup.main.humidity
        self?.overallWeatherModel.visibility = weatherGroup.visibility
        self?.overallWeatherModel.airPressure = weatherGroup.main.pressure
        self?.fetchNextWeekData(lat: lat, long: long)
    }
}
fileprivate func fetchNextWeekData(lat: Double, long: Double) {
    Service.shared.fetchTempDataForWeek(lat: lat, long: long) { [weak self] nextweek in
        self?.overallWeatherModel.temp1 = Int(nextweek.list[0].main.temp - 273)
        self?.overallWeatherModel.temp2 = Int(nextweek.list[1].main.temp - 273)
        self?.overallWeatherModel.temp3 = Int(nextweek.list[2].main.temp - 273)
        self?.overallWeatherModel.temp4 = Int(nextweek.list[3].main.temp - 273)
        self?.overallWeatherModel.temp5 = Int(nextweek.list[4].main.temp - 273)
        let weatherIcon1 = "http://openweathermap.org/img/w/\(nextweek.list[0].weather.first?.icon ?? "").png"
        let weatherIcon2 = "http://openweathermap.org/img/w/\(nextweek.list[1].weather.first?.icon ?? "").png"
        let weatherIcon3 = "http://openweathermap.org/img/w/\(nextweek.list[2].weather.first?.icon ?? "").png"
        let weatherIcon4 = "http://openweathermap.org/img/w/\(nextweek.list[3].weather.first?.icon ?? "").png"
        let weatherIcon5 = "http://openweathermap.org/img/w/\(nextweek.list[4].weather.first?.icon ?? "").png"
        self?.overallWeatherModel.icon1 = URL(string: weatherIcon1)
        self?.overallWeatherModel.icon2 = URL(string: weatherIcon2)
        self?.overallWeatherModel.icon3 = URL(string: weatherIcon3)
        self?.overallWeatherModel.icon4 = URL(string: weatherIcon4)
        self?.overallWeatherModel.icon5 = URL(string: weatherIcon5)
        self?.overallWeatherModel.date1 = DateFormat.shared.nextDate(day: 1)
        self?.overallWeatherModel.date2 = DateFormat.shared.nextDate(day: 2)
        self?.overallWeatherModel.date3 = DateFormat.shared.nextDate(day: 3)
        self?.overallWeatherModel.date4 = DateFormat.shared.nextDate(day: 4)
        self?.overallWeatherModel.date5 = DateFormat.shared.nextDate(day: 5)
        self?.bindableSearchWeather.value = self?.overallWeatherModel
    }
}

}

SearchViewModel 正在创建 API 调用并获取数据,然后我将此数据发送到 WeatherVewModel,它负责更改其控制器上的视图。为了传递数据,我使用 Observable/Bindable 并将 SearchViewModel 嵌入到 WeatherVewModel 中,以便它可以向它发送数据。我的问题是我这样做是否正确?感觉将一个视图模型嵌入另一个视图模型是不对的。

ios swift mvvm uikit viewmodel
1个回答
0
投票

每个视图都应该有自己的视图模型,

SearchViewController 应该有(了解)-> SearchViewModel 和 WeatherViewController 应该有(了解)-> WeatherViewModel

当您从 SearchViewModel 获取数据时,如果您应该呈现或显示另一个视图,例如推送:

let weatherViewModel = WeatherViewModel(weatherParamsYouFetchInSearchViewModel: ...x..)
let vc = WeatherViewController(viewModel: weatherViewModel)
push(vc, animated: true)

你的 WeatherViewController 应该有这个初始化

class WeatherViewController: UIViewController {
    let viewModel: WeatherViewModel!
    
    init(viewModel: WeatherViewModel) {
        self.viewModel = viewModel
        super.init(nibName: WeatherViewModel.nameOfClass, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.