请为您的Swift MVVM实施评分

请为您的Swift MVVM实施评分,swift,mvvm,Swift,Mvvm,我希望得到评估,以确保正确实施Swift MVVM 另外,如果还有其他可以补充的内容,请修改 1.AppDelegate.swift 在显示ViewController之前,AppDelegate指定一个ViewModel func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: A

我希望得到评估,以确保正确实施Swift MVVM

另外,如果还有其他可以补充的内容,请修改

1.AppDelegate.swift 在显示ViewController之前,AppDelegate指定一个ViewModel

   func application(_ application: UIApplication, 
    didFinishLaunchingWithOptions launchOptions: 
   [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    if let rootVC = window?.rootViewController as? ViewController {
        rootVC.viewModel = MainViewModel()
    }

    return true
}
2.ViewController.swift 在ViewController中执行数据绑定。 TableView也是使用扩展名指定的

class ViewController: UIViewController {

var viewModel: MainViewModel!

override func viewDidLoad() {
    super.viewDidLoad()

    viewModel.bind { [weak self] in
        DispatchQueue.main.async {
            print("TableView reloadData")
                // tableView reload
        }
    }

    viewModel.addText(addText: "test")
    print("count \(viewModel.count)")
  }
}

class TextListCell: UITableViewCell {

}

extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection             section: Int) -> Int {
    return viewModel.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: TextListCell = tableView.dequeueReusableCell(withIdentifier: "TextListCell", for: indexPath) as! TextListCell

    let test = viewModel.texts[indexPath.row]

    return cell
  }
}

extension ViewController: UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("\(indexPath.row.description)")
   }
}
3.梅因·斯威夫特 该模型称为数据管理。 但是,我不理解业务逻辑是由模型处理的

struct TextEditor {
let text: String
}
4.MainViewModel.swift 模型更新后,将结果通知ViewModel,并准备要在视图中显示的数据

protocol MainViewModelProtocol: class {
func bind(didChange: @escaping () -> Void)
func addText(addText: String)
var count: Int { get }
var texts: Array<TextEditor> { get }
}

class MainViewModel: MainViewModelProtocol {
private var didChange: (() -> Void)?

var texts: [TextEditor] = [] {
    didSet {
        didChange?()
    }
}

func bind(didChange: @escaping () -> Void) {
    self.didChange = didChange
}

var count: Int {
    return texts.count
}

func addText(addText: String) {
    self.texts.append(TextEditor(text: addText))
}
}
protocol主视图模型协议:类{
func绑定(didChange:@escaping()->Void)
func addText(addText:String)
变量计数:Int{get}
变量文本:数组{get}
}
类MainViewModel:MainViewModelProtocol{
private var didChange:(()->Void)?
变量文本:[TextEditor]=[]{
迪塞特{
改变了吗?()
}
}
func绑定(didChange:@escaping()->Void){
self.didChange=didChange
}
变量计数:Int{
返回文本。计数
}
func addText(addText:String){
self.text.append(文本编辑器(文本:addText))
}
}

我认为会让它变得更好的几点改进:

  • ViewModel应充当tableview的数据源

  • 协议应该易于组合,并且应该很小。我觉得您的
    MainViewModelProtocol
    非常适合您的ViewModel。尽量使你的协议,使他们可以符合其他事情也。我不知道您的项目的确切结构,但我不认为您在协议中声明的许多函数是其他ViewModels所需要的

  • cellForRowAt
    函数中,您正在执行力展开。可能只有我一个人,但强制展开对我来说太危险了
  • dequeueReusableCell
    中,您将使用标识符对单元格进行出列。尽量避免使用严格类型的API。存在的方式之一

  • 请注意,每个项目都是不同的,很多项目架构都基于团队知识、项目范围和截止日期。在这种情况下,对鹅有利的东西可能对鹅不利。请从这里删除您的问题并将其发布到那里。虽然代码审查可以产生有趣的问题,但我们不在这里处理此类问题。也许代码审查网站会更好。我会把它发布在代码审查上。谢谢你的回答。