gpt4 book ai didi

ios - 如何在 VIPER 设计模式中将 ViewController Reference 传递给 Router?

转载 作者:搜寻专家 更新时间:2023-10-30 23:07:41 26 4
gpt4 key购买 nike

附言:这不是一个自以为是的问题。在 VIPER 中连接各种模块是一个合理的怀疑。这是一个理论问题,因此没有附加代码。我只需要知道我们如何在这种特定情况下连接 View-Presenter-Router 而不会破坏 VIPER

的基本规则

我是第一次尝试使用 VIPER。这是我对 VIPER 的基本理解。

View:应该显示 UI 控件并捕获 IBActions 并调用它的 presenter 的委托(delegate)方法来处理事件

Presenter: 将处理所有与 UI 相关的数据并准备渲染数据并将数据移交给 View。每当需要屏幕转换时,它都会调用其路由器并要求路由器执行转换

P.S: Presenter 中不会有任何 UIComponents。所以在 presenter 中没有 import UIKit 语句。

Router: 负责执行屏幕转换,通常在线框的帮助下完成(可选但最好在应用程序中有这样的类)

Interactor:包含所有业务逻辑。Presenter会在需要根据业务逻辑进行处理时调用Interactor。

实体 POJO 类(简单 Swift 对象或核心数据实体)。

问题来了:

如果我的假设是正确的,Presenter 应该是一个普通的 Swift 类,没有 UIKit 访问权限。

如果为真,假设我在我的 ViewControllerA 上按下了一个按钮,我需要将另一个 ViewControllerB 推到它上面,显然 ViewControllerA 会与 PresenterA 对话并告诉它按钮被点击,现在 PresenterA 应该与 RouterA 对话并告诉它推送 ViewControllerB

因为 Router 可以访问 UIKit 我可以使用 Storyboard实例或从 xib 轻松创建 ViewControllerB 的新实例,但为了推送该实例我需要ViewControllerA 的实例。

但是 PresenterA 不能持有对 ViewControllerA 的引用,或者可以在函数中作为参数传递给 PresenterA 因为 UIViewController 属于 UIKit,Presenter 不应该有 UI 语句。

我能想到的可能解决方案:

解决方案一:

在创建 Router 实例时,将相应的 ViewController 实例作为其初始化(依赖注入(inject)阶段)的一部分传递,这样 Router 将始终引用它所属的 ViewController

解决方案 2:

让 Router 声明其协议(protocol)并在 ViewController 中实现它,并且每当需要引用 ViewController 时使用 Router 的委托(delegate)。但这与路由器不应该与 View 通信的 VIPER 规则相矛盾。

我的思路是否清晰?我的假设是否正确?如果是,处理这个问题的正确方法是什么,请提出建议

最佳答案

关于 iOS 应用程序的 VIPER 的任何建议或意见都是值得商榷的,因为 VIPER 并不严格适合 iOS 的 UIKit 设计。但是,如果我可以把我的两分钱放在讨论中:

首先,我认为 UIViewController 非常适合 VIPER 模式中的 Presenter 角色,因此 ViewControllerA 不需要与自身和 Router 之间的任何类对话 - 直接与 Router 通信。

其次,应该只有一个 Router 对象 - 因为应用程序只有一个 View /导航堆栈。出于这个原因,为 Router 实现 Singleton 模式是理想的,所以 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

的引用

但这就是我的看法。

关于ios - 如何在 VIPER 设计模式中将 ViewController Reference 传递给 Router?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51554171/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com