目前我正在使用MVVMC架构开发iOS应用程序。我通过阅读article来了解MVVMC。作为典型的MVVM模型,我们知道所有主要的应用程序控制器(如Web服务调用)都应该在ViewModel类中调用。但是在MVVMC架构中,我们可以使用Coordinator或ViewModel来调用Web服务。我无法弄清楚最适合这个的地方。
我目前正在尝试使用UITableViewController实现应用程序的用户列表页面。以下是我的UserCoordinator和UserViewModel类的一些部分。
UserCoordinator
class UsersCoordinator: Coordinator {
var window: UIWindow
weak var delegate: UsersCoordinatorDelegate?
var selectedCity: City?
init(window: UIWindow) {
self.window = window
}
func start() {
let storyboard = UIStoryboard(name: "Users", bundle: nil)
if let vc = storyboard.instantiateViewController(withIdentifier: "list") as? UsersListController {
var viewModel = UsersListViewModel()
viewModel.delegate = self as UsersListViewModelDelegate
viewModel.veiwController = vc
vc.viewModel = viewModel
vc.coordinationDelegate = self as CoordinationDelegate
let nav = UINavigationController.init(rootViewController: vc)
window.rootViewController = nav
}
}
UserViewModel
protocol UsersListViewModelDelegate: class {
func selectUser(viewController: UIViewController, city: City)
}
struct UsersListViewModel {
var delegate: UsersListViewModelDelegate?
weak var veiwController: UsersListController!
var source = [String]()
init() {
for user in users {
source.append(user.name)
}
}
func selectRow(row: NSInteger) {
delegate?.selectUser(viewController: veiwController, user: users[row])
}
fileprivate var users: [User] {
get {
//web service call??
}
我应该在哪里拨打网络服务?正如我从理论上讲,协调器是应用程序路由的专用场所。因此,根据它,在ViewModel中调用Web服务会更好。但我觉得在协调器中调用Web服务会更好,因为它会非常快速地加载数据并填充viewModel。我该怎么办?
答案 0 :(得分:5)
您需要了解ViewModel和协调器的用途,才能知道其中应包含什么。 ViewModel 的职责是为View准备数据并处理用于准备该数据的业务逻辑。它将数据绑定到UI元素,并在数据更改后立即更改UI。因此,ViewModel应该是其中应包含该服务的对象,并且所有调用均应通过该服务进行。
协调器的职责是通过显示适当的ViewController及其所有依赖项(包括ViewModel)来处理应用程序的导航。因此,它还准备了ViewModel并将其注入服务,而不使用该服务来操纵数据。
所以,我总结一下,协调器应该是准备带有依赖项的ViewModel的人,其中包括在其中注入Web服务,而ViewModel应该是使用该服务并进行所有从持久性获取数据的调用的人。
有关更清晰的主意,您可以在 Github
上的 MVVM-C 上检查我的示例应用程序答案 1 :(得分:4)
当我通过互联网进行研究时,没有惯例可以调用您的Web服务。它完全取决于您的项目实施。您可以在Coordinator或ViewModel类上调用它们。由于我们使用协调器初始化
我在上面发布的Coordinator类中。我们可以使用相同的start()函数来调用Web服务,如下所示。
func start() {
let storyboard = UIStoryboard(name: "Users", bundle: nil)
if let vc = storyboard.instantiateViewController(withIdentifier: "list") as? UsersListController {
let uDs = UserDataService(pClient:APIClient())
uDs.getUserDetails { (response, status) in
if (status == APIClient.APIResponseStatus.Success) {
if let resArrray = response as? [User] {
var viewModel = UsersListViewModel.init(userList: resArrray)
viewModel.delegate = self as UsersListViewModelDelegate
viewModel.veiwController = vc
vc.viewModel = viewModel
vc.coordinationDelegate = self as CoordinationDelegate
let nav = UINavigationController.init(rootViewController: vc)
self.window.rootViewController = nav
}
} else {
//error alert
}
}
}
}
最好在Coordinator类中调用Web服务调用。因为根据响应调用Web服务后我们可以控制视图导航。如果响应成功,我们可以创建一个ViewController类并加载它。否则我们可以加载错误弹出窗口。与此同时,我们可以花足够的时间进行Web服务调用,并将这些数据填充到viewModel。
基于我通过互联网找到的内容,我使用MVVM-C架构实现了一个示例项目。我在GitHub中托管了它。您可以在here中找到它。
通过引用此poroject,您可以清楚地了解如何使用MVVM-C模式实现视图导航,如何调用Web服务,如何从数据中填充viewModel等。
答案 2 :(得分:2)
在建筑方面,没有银弹。 牢记这一点MVVM-C是最干净,易于测试和模块化的模式之一,所以你继续使用它是很棒的。
您可以自由定制架构以满足您的要求。 话虽如此,考虑到您当前的设计,我认为最好创建一个Service类,称之为WebService。该课程将在协调员的监督下执行网络操作。协调员将