路由毒蛇架构
Routing Viper architecture
如何在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!)
}
我必须添加或更改什么才能正常工作?
一种方法是继承 UINavigationController 并在其中执行路由逻辑。根据您的任务,您最终可能会在应用程序的不同部分进行多次 类 路由。
但是就像使用任何流行的流行语一样,您首先必须问问自己
如果 "solutuon" 解决的问题多于它造成的问题。
当你看到两打屏幕并开始迷失时,它就开始有意义了
很久以前通过将故事板添加到
普通的旧 xibs。
所以你真的要退一步问问自己是否真的要跟
这个 cromulent 架构在这个过程中创造了很多很多 类,
一个与标准 MVC 项目相比几乎没有可读性的迷宫。
如果你不能使用情节提要但想使用 VIPER,请这样做,
如果你可以使用故事板做 VIPE :-)
但在大多数项目中,数据模型简单得可怜,而且
演示文稿是如此紧密耦合,你有零需要
UIViewController 去脂.
而且我怀疑大多数毒蛇爱好者采用的治疗方法是
比死亡本身更糟糕。
2 种可能性:
更改 rootViewframe 的 init 以接受您的依赖项并对其进行初始化。
顺便说一句,你的变量类型不应该是真正的类型,而是协议,所以你可以在测试中轻松地模拟它
let chooseLanguageScreenWireframe : ChooseLanguageWireframeProtocol?
override init(chooseLanguage: ChooseLanguageWireframeProtocol) {
self.chooseLanguageScreenWireframe = chooseLanguage
}
然后在 appdelegate 中创建您的 chooseLanguageWireframe 实现并将其传递到构造函数中。
这使得依赖关系清晰可见。您也可以删除可选性,因为您总是对其进行初始化。
或者解决方案2
在 appdelegate 中创建 chooseLanguageWireframe 并将其注入到构造函数之外
lazy var rootWireframe = {
let r = RootWireframe()
r.chooseLanguageScreenWireframe = self.chooseLanguageScreenWireframe
return r
}
无论如何,您需要在某处实例化您的依赖项,它们无法自动创建。
您通常会在依赖注入框架的帮助下使用工厂(检查 SwiftInject 或 Typhoon)
此外,使用协议类型声明所有依赖项,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!)
}
我必须添加或更改什么才能正常工作?
一种方法是继承 UINavigationController 并在其中执行路由逻辑。根据您的任务,您最终可能会在应用程序的不同部分进行多次 类 路由。
但是就像使用任何流行的流行语一样,您首先必须问问自己 如果 "solutuon" 解决的问题多于它造成的问题。
当你看到两打屏幕并开始迷失时,它就开始有意义了 很久以前通过将故事板添加到 普通的旧 xibs。
所以你真的要退一步问问自己是否真的要跟 这个 cromulent 架构在这个过程中创造了很多很多 类, 一个与标准 MVC 项目相比几乎没有可读性的迷宫。
如果你不能使用情节提要但想使用 VIPER,请这样做, 如果你可以使用故事板做 VIPE :-)
但在大多数项目中,数据模型简单得可怜,而且 演示文稿是如此紧密耦合,你有零需要 UIViewController 去脂.
而且我怀疑大多数毒蛇爱好者采用的治疗方法是 比死亡本身更糟糕。
2 种可能性:
更改 rootViewframe 的 init 以接受您的依赖项并对其进行初始化。 顺便说一句,你的变量类型不应该是真正的类型,而是协议,所以你可以在测试中轻松地模拟它
let chooseLanguageScreenWireframe : ChooseLanguageWireframeProtocol?
override init(chooseLanguage: ChooseLanguageWireframeProtocol) {
self.chooseLanguageScreenWireframe = chooseLanguage
}
然后在 appdelegate 中创建您的 chooseLanguageWireframe 实现并将其传递到构造函数中。 这使得依赖关系清晰可见。您也可以删除可选性,因为您总是对其进行初始化。
或者解决方案2 在 appdelegate 中创建 chooseLanguageWireframe 并将其注入到构造函数之外
lazy var rootWireframe = {
let r = RootWireframe()
r.chooseLanguageScreenWireframe = self.chooseLanguageScreenWireframe
return r
}
无论如何,您需要在某处实例化您的依赖项,它们无法自动创建。 您通常会在依赖注入框架的帮助下使用工厂(检查 SwiftInject 或 Typhoon)
此外,使用协议类型声明所有依赖项,VIPER 架构的目的是通过参与者之间的隔离来简化测试和模拟