Как получить доступ к свойству ViewController из AppDelegate, если оно есть в TabBarController? - PullRequest
0 голосов
/ 17 марта 2019

У меня 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 ]

2 голосов
/ 17 марта 2019

Я бы рекомендовал не обращаться к контроллеру представления из делегата приложения.Он слишком много знает о том, что нужно контроллеру представления (и его структуре) в делегате приложения.Это хрупкий дизайн.

Лучше было бы определить собственное уведомление NotificationCenter.Отправьте это уведомление от делегата приложения с необходимой полезной нагрузкой (URL).

Добавьте код в соответствующий контроллер представления для прослушивания этого настраиваемого уведомления.Когда уведомление получено в контроллере представления, получите URL и действуйте соответствующим образом.

Этот подход позволяет узнать, кому небезразлично уведомление и как обрабатывать уведомление, к которому оно относится.Это также позволяет нескольким контроллерам представления (или другим классам) действовать на одно и то же уведомление, не добавляя все больше и больше логики в делегат приложения.

1 голос
/ 17 марта 2019

Правильный подход должен иметь "dataSource" / "DBManager", который вы можете вызвать, и он будет отправлять данные каждому запрашивающему объекту.

(я обычно для него синглтон .. даже если синглтоны часто не одобряются .. :))

1 голос
/ 17 марта 2019

Самый простой грязный способ просто найти контроллер представления желаний:

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 подписался на эти изменения
...