我有一个UITabBarController作为根视图控制器,我需要访问ProfileViewController中的一个属性。
这是故事板:
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
}
我建议不要从app delegate访问视图控制器。它过多地了解了视图控制器在app委托中需要的内容(及其结构)。这是一个脆弱的设计。
更好的方法是定义自己的NotificationCenter
通知。从app委托发布带有所需有效负载(URL)的通知。
在相应的视图控制器中添加代码以侦听该自定义通知。在视图控制器中收到通知后,获取URL并采取相应措施。
这种方法提供了谁关心通知的知识以及如何处理通知所属的通知。它还允许多个视图控制器(或其他类)对相同的通知执行操作,而无需在应用程序委托中添加越来越多的逻辑。
最容易找到欲望视图控制器的脏方法:
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
OAuthService
有很强的参考价,因为很可能在applicationDidFinishLaunching(_)
中创建它。OAuthService
提供委托/通知/状态流来通知会话状态更改ProfileViewConctoller
订阅了这一变化正确的方法应该是拥有一个“dataSource”/“DBManager”您可以调用它并将数据发送到每个请求对象。
(我通常是一个单身人士..即使单身人士经常气馁...... :))