Архитектура маршрутизации Viper

Как создать хорошую маршрутизацию в проекте на архитектуре Viper? Я начинаю создавать файл для маршрутизации, но не понимаю, что мне делать дальше.

Я создаю файл каркаса первого контроллера и протокола каркаса:

//  ChooseLanguageWireframeProtocol.swift

import UIKit

@objc protocol ChooseLanguageWireframeProtocol {
    func presentChooseLanguageViewControllerWindow()
    func presentAuthScreenViewController()
}

в каркас файла добавляю:

//  ChooseLanguageWireframe.swift

import UIKit

class ChooseLanguageWireframe: NSObject , ChooseLanguageWireframeProtocol{

    var chooseLanguageScreenViewController: ChooseLanguageViewController?
    var window: UIWindow?

    func presentChooseLanguageViewControllerWindow() {
        let chooseLanguageViewController = UIStoryboard.init(name: "ChooseLanguage", bundle: nil).instantiateViewController(withIdentifier: "ChooseLanguage") as? ChooseLanguageViewController
        self.chooseLanguageScreenViewController = chooseLanguageViewController
        self.window!.rootViewController = chooseLanguageScreenViewController
        self.window!.makeKeyAndVisible()
    }
    func presentAuthScreenViewController() {

    }
}

После создания RootWireframe

//  RootWireframe.swift

import UIKit

class RootWireframe: NSObject {

    let chooseLanguageScreenWireframe : ChooseLanguageWireframe?

    override init() {
     //What i must init??
    }

    func application(didFinishLaunchingWithOptions launchOptions: [AnyHashable: Any]?, window: UIWindow) -> Bool  {
        self.chooseLanguageScreenWireframe?.window = window
        return true
    }

}

В файле AppDelegate меняю только

var window: UIWindow?
    let rootWireframe = RootWireframe()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.rootWireframe.application(didFinishLaunchingWithOptions: launchOptions as [NSObject : AnyObject]?, window: self.window!)
    }

Что я должен добавить или изменить для корректной работы?


person Andrei Trotsko    schedule 13.04.2017    source источник
comment
На самом деле вам просто не хватает создания и внедрения зависимостей. Viper и все другие несвязанные архитектуры основаны на внедрении зависимостей и изобретении контроля.   -  person Marco Pappalardo    schedule 17.07.2017


Ответы (2)


2 возможности:

Измените инициализацию вашего rootViewframe, чтобы принять вашу зависимость и инициализировать ее. И, кстати, ваш тип переменной должен быть не реальным типом, а протоколом, чтобы вы могли легко издеваться над ним в тестах.

let chooseLanguageScreenWireframe : ChooseLanguageWireframeProtocol?

override init(chooseLanguage: ChooseLanguageWireframeProtocol) {
self.chooseLanguageScreenWireframe = chooseLanguage
}

Затем создайте свою реализацию ChooseLanguageWireframe в делегате приложения и передайте ее в конструктор. Это делает зависимость ясной и видимой. Вы также можете удалить опцию, так как вы всегда инициализируете ее.

Или решение 2. Создайте ChooseLanguageWireframe в делегате приложения и внедрите его туда вне конструктора.

lazy var rootWireframe = {
let r = RootWireframe()
r.chooseLanguageScreenWireframe = self.chooseLanguageScreenWireframe
return r
}

В любом случае вам нужно где-то создавать экземпляры ваших зависимостей, они не могут создаваться автоматически. Обычно вы делаете это с фабриками и с помощью фреймворка внедрения зависимостей (отметьте SwiftInject или Typhoon).

Кроме того, объявите все свои зависимости с типом протоколов, целью архитектуры VIPER является упрощение тестирования и имитации с изоляцией между актерами.

person Marco Pappalardo    schedule 16.07.2017

Один из способов сделать это — наследоваться от UINavigationController и выполнить там логику маршрутизации. Вы можете получить несколько классов, выполняющих маршрутизацию в разных частях вашего приложения в зависимости от вашей задачи.

Но, как и в случае с любым громоздким модным словечком, вы должны сначала спросить себя, решает ли «решение» больше проблем, чем создает.

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

Поэтому вам действительно нужно сделать шаг назад и спросить себя, действительно ли вы хотите следовать этой громоздкой архитектуре, создавая множество классов в процессе, лабиринт, который вряд ли будет более читабельным, чем стандартный проект MVC.

Если вы не можете использовать раскадровки и хотите использовать VIPER, сделайте это, если вы можете использовать раскадровки, используйте VIPE :-)

Но в большинстве проектов модель данных настолько жалко проста, а представление настолько тесно связано, что вам не нужно разматывать UIViewController.

И я подозреваю, что лекарство, применяемое большинством адептов змей, хуже самой болезни.

person Anton Tropashko    schedule 26.05.2017
comment
Cocoa MVC очень связан. Невозможно проверить вашу бизнес-логику и т. д., используя такую ​​​​инфраструктуру, как viper, которая позволяет тестировать и поддерживать проект для вас и для всех будущих разработчиков. Это может быть полезно даже для небольших проектов, потому что вы никогда не знаете, насколько большим может стать проект, и он учит вас тому, как делать то, что будет полезно в другом более крупном проекте. архитектура — это скорее образ мышления, чем то, как вы ее программируете - person Marco Pappalardo; 17.07.2017
comment
viper — это не фреймворк, это всего лишь один из способов структурировать ваш код. Если вы были в этом районе, я уверен, что вы можете так или иначе отделить бизнес-логику, чтобы автоматизация тестирования была жизнеспособной. - person Anton Tropashko; 27.04.2021
comment
Да, @Anton Tropashko, это не фреймворк в смысле модуля, который можно скачать. в то время (4 года назад :O) я имел в виду это как способ настроить ваш код, также известный как ментальная структура. Согласен, вводящие в заблуждение слова. Кроме того, я не люблю VIPER. Это просто модные словечки и шаблоны. В любом случае, возвращаясь к сути: вы можете использовать любой тип архитектуры (это всего лишь способ структурировать код) и разделить код, чтобы его можно было протестировать. Мой комментарий состоял в том, чтобы не согласиться с предложением использовать Cocoa MVC и наследовать от UINavigationController или, что еще хуже, использовать переходы. Лучше извлечь в Координаторе - person Marco Pappalardo; 28.04.2021
comment
Балогней VIPER это. Ты сказал это. Наследование от UINavigationController было не лучшей идеей, я переключился на шаблон координатора, как вы предложили. Чтобы еще больше запутать читателей кода, я называю их Маршрутизаторами. - person Anton Tropashko; 28.04.2021