ios - 如何在 VIPER 设计模式中将 ViewController 引用传递给路由器?
问题描述
PS:
这不是一个自以为是的问题。在 VIPER 中连接各种模块是一个合理的疑问。这是一个理论问题,所以没有附加代码。我只需要知道在这种特定情况下我们如何连接 View-Presenter-Router 而不打破基本规则VIPER
我是第一次尝试使用 VIPER。这是我对VIPER的基本理解。
视图:应该显示 UI 控件并捕获IBActions
并调用其演示者的委托方法来处理事件
Presenter:将处理所有与 UI 相关的数据,并为渲染准备数据并将数据交还给 View。每当需要屏幕转换时,它都会调用其路由器并要求路由器执行转换
PS: Presenter 中不会有任何 UIComponents。所以没有import UIKit
在presenter中声明。
路由器:负责执行屏幕转换,通常在线框的帮助下完成(可选但在应用程序中有这样的类很好)
Interactor:包含所有业务逻辑。Presenter 将在需要基于业务逻辑进行处理时调用 Interactor。
实体: POJO 类(简单的 Swift 对象或核心数据实体)。
现在问题来了:
如果我的假设是正确的,Presenter 应该是一个没有UIKit
访问权限的普通 Swift 类。
如果为真,假设我按下了我的一个按钮ViewControllerA
并且我需要在其上按下另一个按钮ViewControllerB
,显然ViewControllerA
会与它交谈PresenterA
并告诉它该按钮已被轻按,现在PresenterA
应该与它交谈RouterA
并告诉它按下ViewControllerB
。
因为路由器可以访问UIKit
我可以轻松地创建一个ViewControllerB
使用故事板实例或从 xib 的新实例,但为了推送该实例,我需要 ViewControllerA 的实例。
但PresenterA
不能持有ViewControllerA
对 in 函数的引用或作为参数传递,PresenterA
因为UIViewController
属于UIKit
和 Presenters 不应该有 UI 语句。
我能想到的可能解决方案:
解决方案1:
在创建路由器实例时,将相应ViewController
的实例作为其初始化(依赖注入阶段)的一部分传递,这样路由器将始终引用它所属的 ViewController
解决方案2:
让路由器声明其协议并在 ViewController 中实现它,并且每当需要对 ViewController 的引用时,都需要使用路由器的委托。但这与 VIPER 的规则相矛盾,即路由器不应该与 View 通信。
我想得直吗?我的假设是否正确?如果是,解决此问题的正确方法是什么,请建议
解决方案
任何关于 VIPER for iOS 应用程序的建议或意见都是值得商榷的,因为 VIPER 并不完全适合 iOS 的 UIKit 设计。但是,如果我可以把我的两分钱放在讨论中:
首先,我认为这UIViewController
完全适合Presenter
VIPER 模式中的角色,因此ViewControllerA
不需要与它自身之间的任何类进行对话,并且Router
- 只需Router
直接进行通信。
其次,应该只有一个Router
对象——因为应用程序只有一个视图/导航堆栈。出于这个原因,最好为 实现一个Singleton
模式Router
,因此ViewControllerA
(或者Presenter
,如果您希望在该模式ViewControllers
中扮演 的角色View
)不需要保留对 . 的引用Router
。
第三,您不需要将引用传递ViewControllerA
给您的Router
-Router
应该已经具有对它的引用,因为Router
应该首先呈现它。像这样的东西:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
{
// ...
window?.rootViewController = Router.shared.rootViewController
// ...
}
class Router
{
static let shared = Router()
let rootViewController = ViewControllerA() // or UINavigationController, or UITabBarController etc.
}
Router
应该跟踪导航堆栈并保持对当前呈现的引用ViewController
但这就是我的看法。
推荐阅读
- java - 使用套接字连接将图像从java传输到c#的问题
- php - 如何修复 laravel 中的 JWT 身份验证错误?
- c# - 具有显式映射表和与流式 API 的显式关系的 EF Core 5 导致迁移中映射表中的附加外键
- c# - Netsuite REST API(无效签名)
- .net - 文本框/数字框过滤 WINUI3
- scriptable - 如何在脚本中更新时间(在小部件中)
- java - 我可以以编程方式调用 Spring Security "/login" 发布方法吗?
- sql-server - 我怎样才能隐藏dbo。表中的架构,查看过程,
- android - 地图应在接受许可时更新谷歌地图上的位置,但它会崩溃而不是更新
- javascript - 有没有办法创建一个嵌套表单输入的 3 级树,每个孩子都有依赖关系?