【问题标题】:Presenting a view controller based on a policy in swift快速呈现基于策略的视图控制器
【发布时间】:2019-11-27 07:17:59
【问题描述】:

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

var canGoToPageX

canGoToPageX的值为真时,用户可以被重定向到"x"视图控制器

if canGoToPageX {
   present X
}

这个视图控制器在多个页面中呈现,如果开发者忘记写 if 条件,用户将被重定向到他不允许的页面。

我想做点什么来避免这个错误 这有什么设计模式吗?

【问题讨论】:

  • canGoToPageX 是全局的或附加到每个控制器,您将如何更改每个控制器的值?
  • @SohilR.Memon 谢谢,canGoToPageX 是一个仅用于 x 视图控制器的全局变量。我想避免开发人员在不检查此政策的情况下展示此视图控制器

标签: ios design-patterns


【解决方案1】:

好像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 将始终检查它是否可访问。当您从一个UIViewController 和您限制用户访问的UIViewController 返回时,此案例将很有用。

让我知道这有没有帮助?

【讨论】:

    【解决方案2】:

    可以解决此问题的一种方法是创建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)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-09-11
      • 2016-11-28
      • 2021-10-18
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多