如果它位于TabBarController中,如何从AppDelegate访问ViewController的属性?

时间:2019-03-17 04:02:15

标签: ios swift uitabbarcontroller appdelegate

我有一个UITabBarController作为根视图控制器,我需要访问ProfileViewController中的一个属性。

这是情节提要:

enter image description here

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    let rootVC = self.window?.rootViewController

    if "com.spbpu.csse" == url.scheme {
        //I need here to get VC property and do something like vc.oauth2.handleRedirectURL(url)

        return true
    }
    return false
}

3 个答案:

答案 0 :(得分:2)

我建议您不要从应用程序委托访问视图控制器。它在应用程序委托中过多地了解了视图控制器的需求(及其结构)。这是一个脆弱的设计。

更好的方法是定义自己的NotificationCenter通知。使用所需的有效负载(URL)从应用程序委托中发布该通知。

在适当的视图控制器中添加代码以侦听该自定义通知。在视图控制器中收到通知后,获取URL并采取相应措施。

这种方法使人们知道谁在乎通知以及如何处理通知所属的通知。它还允许多个视图控制器(或其他类)对同一通知进行操作,而无需在应用程序委托中添加越来越多的逻辑。

答案 1 :(得分:1)

找到欲望视图控制器的最简单的肮脏方式:

let profile = (rootVC as? UITabBarController)?.viewControllers?
    .first { $0 is ProfileViewController }
    .map { $0 as! ProfileViewController } // this unwrap is safe since we filtered by first
profile?.doSomething()

更干净的方式将是:

  • 具有某种OAuthService,负责OAuth身份验证,令牌等
  • appDelegate在OAuthService上有很强的引用,因为最有可能在applicationDidFinishLaunching(_)中创建它。
  • OAuthService提供委托/通知/状态流以通知会话状态更改
  • ProfileViewConctoller订阅了此更改

答案 2 :(得分:1)

正确的方法应该是拥有一个“数据源” /“ DBManager”,您可以调用它并将数据发送到每个请求的对象。

(我通常是单身。.即使经常不鼓励单身。.:))