快速展示基于策略的视图控制器

时间:2019-11-27 07:17:59

标签: ios design-patterns

我的应用程序中有一些更改值的策略。例如:

var canGoToPageX

canGoToPageX的值为true时,可以将用户重定向到“ x” 视图控制器

if canGoToPageX {
   present X
}

此View控制器分几页显示,如果开发人员忘记编写if条件,则用户将被重定向到他不允许的页面。

我想做些事情来避免这个错误 有任何设计模式吗?

2 个答案:

答案 0 :(得分:0)

好像canGoToPageX是全局变量,因此您需要限制UIViewController的访问权限,而您只是担心一种情况,开发人员会忘记放置一个条件,那么您可以执行以下操作:

override func viewWillAppear(_ animated: Bool) {
    checkIsControllerAccessible()
}

fileprivate func checkIsControllerAccessible() {
    if !canGoToPageX { //Restrictions
        let alertController = UIAlertController(title: "Error", message: "You are not allowed to access this View", preferredStyle: UIAlertController.Style.alert)
        alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: { (_) in
            self.dismiss(animated: true, completion: nil)
        }))
    }
    self.present(alertController, animated: true, completion: nil)
}

viewWillAppear将始终检查它是否可访问。当您从一个限制访问用户的UIViewControllerUIViewController返回时,这种情况将很有用。

让我知道这对您有帮助吗?

答案 1 :(得分:0)

可以解决此问题的一种方法是创建UIViewController的子类,该子类将覆盖UIViewController所必需的表示功能,并检查将要显示的视图控制器的类型是否为“ x”,以及全局canGoToPageX是否为真。

这种方法将要求开发人员在可能存在“ x”的视图控制器上子类化此新视图控制器类,因此,开发人员仍然容易忘记某些内容,但封装了条件控件。

下面是一些示例代码来演示上述方法:

import UIKit

// Global state holder
class SingletonStateHolder {
    static let shared = SingletonStateHolder()

    var canGoToX = false
}

// View controller that can only be presented if `canGoToX` is true
class XViewController: UIViewController {

}

// View controller subclass that view controllers who can potentially present x can subclass from
class SecureViewController: UIViewController {

    override func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
        if viewControllerToPresent is XViewController && !SingletonStateHolder.shared.canGoToX {
            return
        }

        super.present(viewControllerToPresent, animated: flag, completion: completion)
    }

    override func show(_ vc: UIViewController, sender: Any?) {
        if vc is XViewController && !SingletonStateHolder.shared.canGoToX {
            return
        }

        super.show(vc, sender: sender)
    }
}