iOS: суперкласс MVVM-C ViewController

Имею арку MVVM-C. Каждый UIViewController имеет ViewModel и уведомить Coordinatorкогда необходимо выполнить навигацию. Код, создающий VC, повторяется, и я подумал, что было бы здорово создать суперкласс для унификации всех статических функций, которые создают VC. Нравится:

      import UIKit

class MVVMCViewController: UIViewController {
    
    weak var coordinatorDelegate: CoordinatorDelegate?
    var viewModel: Modelling?
    
    static func initVC(storyboard: Storyboard,
                       coordinatorDelegate: CoordinatorDelegate?,
                       viewModel: Modelling?) -> Self {
        let viewController = Self.instantiate(in: storyboard)
        viewController.coordinatorDelegate = coordinatorDelegate
        viewController.viewModel = viewModel
        return viewController
    }
}

Все CoordinatorDelegateProtocols унаследует от CoordinatorDelegate и все ViewModels будет унаследован от Modelling

Но создание подклассов не работает гладко.

Любые идеи?

2 ответа

Решение

Привет, эта модель не будет работать.

MVVMCViewController имеет жестко запрограммированные протоколы в качестве типа переменной, поэтому у вас должно быть то же самое в вашем childVC.

Чтобы он работал так, как вы хотите, чтобы MVVMCViewController show был общим (но с ним может быть много проблем), например

      class MVVMCViewController<T: Modelling, U: CoordinatorDelegate>: UIViewController {
    
    weak var coordinatorDelegate: U?
    var viewModel: T?

}

или добавьте только что приведенные свойства в ConnectViewController

      class ConnectViewController: MVVMCViewController {
    
    weak var coordinatorDelegate: CoordinatorDelegate?
    var viewModel: Modelling?
    var currentDelegate: ConnectViewControllerCoordinatorDelegate? {
         coordinatorDelegate as? ConnectViewControllerCoordinatorDelegate
    }
    var currentVM: ConnectViewModel? {
         viewModel as? ConnectViewModel
    }
}

Ваш суперкласс MVVMCViewController определяет два свойства coordinatorDelegate и viewModel. Если вам просто нужно получить к ним доступ в своем дочернем классе, просто обращайтесь к нему обычным образом. Вам не нужно определять это снова.

Кроме того, в родительском классе у вас есть weak var coordinatorDelegate: CoordinatorDelegate?. Но в вашем дочернем классе ( ConnectViewController), вы повторно объявляете свойство с другим типом ( ConnectViewControllerCoordinatorDelegate?). Это незаконно, даже если это подкласс CoordinatorDelegate.

Следовательно, либо

  1. Переименуйте свойство в дочернем классе, чтобы избежать конфликта
  2. Сохраните имя и тип, но добавьте override ключевое слово для свойства, если вы планируете добавить дополнительные функции в свой дочерний класс
  3. Не объявляйте свойство снова в дочернем классе, если вам не нужно добавлять к нему дополнительные функции. Просто получите доступ к нему напрямую.

Обратитесь к тому, как наследование работает в Swift здесь: https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html

Другие вопросы по тегам