ios - 服务管理器未填充 ViewModel
问题描述
你好开发人员现在我学习 mvvm。我想在我的 viewModel 中填充数据,并将我的服务创建为单例。但不知何故,在我的uilabel中它不起作用。相反,我的 uilabel 文本消失了,我不知道我的设置 viewModel 是否错误。我应该分开模型吗,因为我的视图模型中有两个模型对象。在这里,我向您展示我的代码。
class ProfileViewModel {
private var infos: InfoResult?
private var cities = [City]()
private var religions = [Religion]()
private let services: BasicInfoServices
var profileID: String {
return infos?.id ?? ""
}
var imageURL: String {
let imageUrl = infos?.docAwsUrl ?? ""
return imageUrl
}
var fullName: String {
return infos?.fullName ?? ""
}
var phoneNumber: String {
return infos?.phoneNumber ?? ""
}
var email: String {
return infos?.email ?? ""
}
var cityOfBirth: String {
var cityName = ""
cities.forEach { city in
if infos?.pobId == city.id {
cityName = city.name ?? ""
}
}
return cityName
}
var dateOfBirth: String {
return infos?.dob ?? ""
}
var religion: String {
var religionName = ""
religions.forEach { religion in
if infos?.religionId == religion.id {
religionName = religion.name
}
}
return religionName
}
init(services: BasicInfoServices) {
self.services = services
populateProfile()
}
}
extension ProfileViewModel {
func populateProfile() {
// Basic Info
self.services.getBasicInfo { [weak self] result in
switch result {
case .success(let profile):
self?.infos = profile
case .failure(let error):
print(error)
}
}
// City
self.services.getCity { [weak self] result in
switch result {
case .success(let cities):
self?.cities = cities
case .failure(let error):
print(error)
}
}
// Religion
self.services.getReligion { [weak self] result in
switch result {
case .success(let religions):
self?.religions = religions
case .failure(let error):
print(error)
}
}
}
}
// I initialise it in viewController
var viewModel: ProfileViewModel!
var services = BasicInfoServices()
// than I test it in viewDidLoad
viewModel = ProfileViewModel(services: services)
profileLbl.text = viewModel.fullName // when set this my profileLbl place holder disappear.
profileImage.getUserImage(urlString: viewModel.imageURL)
解决方案
1) 在这一行,您发出 API 请求,因此这是一个异步进程
viewModel = ProfileViewModel(services: services)
2)不等待成功响应,您尝试在下一行使用响应数据
profileLbl.text = viewModel.fullName
给你的提示
1) 您应该使用闭包来检测 API 响应。
class ProfileViewModel {
var info: InfoResult?
private let services: BasicInfoServices
init(services: BasicInfoServices) {
self.services = services
}
func loadData(success: (()->()), failure: ((String)->())){
self.services.getBasicInfo { [weak self] result in
switch result {
case .success(let infoResult):
self?.info = infoResult
success()
case .failure(let error):
print(error)
failure(error.localizedDescription)
}
}
}
}
2) 收到数据后,可以在视图上显示。
class ViewController: UIViewController {
let viewModel = ProfileViewModel(services: BasicInfoServices())
@IBOutlet weak var lblProfileID:UILabel!
@IBOutlet weak var lblFullName:UILabel!
@IBOutlet weak var lblPhoneNumber:UILabel!
@IBOutlet weak var lblEmail:UILabel!
@IBOutlet weak var lblDataOfBirth:UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel.loadData(success: {
self.populateUserData()
}, failure: { errorString in
print(errorString)
})
}
func populateUserData(){
self.lblProfileID.text = self.viewModel.info?.id
self.lblFullName.text = self.viewModel.info?.fullName
self.lblPhoneNumber.text = self.viewModel.info?.phoneNumber
self.lblEmail.text = self.viewModel.info?.email
self.lblDataOfBirth.text = self.viewModel.info?.dob
}
}
推荐阅读
- asynchronous - TCL中的fileevent非常慢
- android - 模拟 SharedPreferences.Editor.putString()
- tfs - 为什么 tfs 2018 部署组阶段将在前一个部分失败后运行?
- python - 如何使用 python 从 sqlite 获取数据?
- javascript - 无需jQuery UI即可在分隔符的拖放上调整Div大小
- batch-file - 批处理 - 功能 - 参数不起作用
- android - 在我的应用中显示受保护的版权视频
- html - 默认隐藏RPubs文档中的工具栏
- github - 在应用程序 GUI 上注释 github 问题
- c++ - 在 C++ 中初始化邻接矩阵