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

tktrz96b  于 2023-05-05  发布在  Swift
关注(0)|答案(1)|浏览(119)

我写的天气应用程序,其中包含两个控制器和两个视图模型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
    }
}

}
class 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中,这样它就可以向WeatherVewModel发送数据。我的问题是,我这样做是否正确?有一种感觉,将一个视图模型嵌入另一个视图模型是不正确的。

kx7yvsdv

kx7yvsdv1#

每个视图应该具有其自己的视图模型,
SearchViewController应该有(知道)-〉SearchViewModel和WeatherViewController应该有(知道)-〉WeatherViewModel
当你从SearchViewModel获取数据时,如果你应该呈现或显示另一个视图,例如push:

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")
    }
}

相关问题