Как наблюдать значение глобальной переменной и действовать при изменении внутри ViewController - PullRequest
0 голосов
/ 27 марта 2019

Я использую универсальные ссылки в своем приложении для iOS и могу успешно сохранить значение URL в приложении в качестве глобальной переменной.Это делается в начале приложения делегата.Это работает при запуске и при повторном открытии приложения из фона.

Этот URL затем передается в WKWebView в качестве исходного URL.

Проблема заключается в ViewController для WKWebViewуже загружен и не обнаруживает новый URL до тех пор, пока я не выйду и не вернусь.

Я создал очень уродливый фрагмент кода, который работает, но недостаточно хорош для работы.Он отслеживает изменение переменной из основного потока, но выполняется с циклом повторения и сном 1 секунда, чтобы избежать перегрузки ЦП.

Как правильно выполнить переход в контроллере представлениякогда значение глобальной переменной не равно ее значению по умолчанию?

Я посмотрел willset и didset.Но так как моя переменная определена вне класса контроллера представления, я не могу выполнить переход.

// home made loop to look for a change in universal link
    DispatchQueue.global().async {
     repeat
      {
       sleep(1) // save CPU
      }
     while universalOverrideURL == "none"
     DispatchQueue.main.sync {
     print("S E G U E  I S  N E E D E D !")
   }
}

Есть ли лучший способ, который я могу применить, который уважает процессор?

Ответы [ 2 ]

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

Есть много способов решить эту проблему.Собственный способ iOS состоит в том, чтобы использовать NotificationCenter:

//Make your custom notification
extension Notification.Name {
    static let myCustomValueUpdated = Notification.Name("myCustomValueUpdated")
}

//Post the notification when you the value
NotificationCenter.default.post(Notification(name: .myCustomValueUpdated, object: nil, userInfo: ["value": someNewValue]))

//Subscribe everywhere that needs to be interested in UserDefaults changes
let token = NotificationCenter.default.addObserver(forName: .myCustomValueUpdated, object: nil, queue: .main) { notification in
    if let value = notification.userInfo["value"] {
        //Do stuff with new value here
    }
}

Можно также рассмотреть возможность создания службы для переноса значения в изменяемое вами значение, а затем использовать шаблон наблюдателя, чтобы другие объекты могли подписаться на изменения вэто значение.Я предпочитаю предпочитать это решение, так как оно 1) тестируемое и насмешливое, 2) строго типизированное, 3) убирает вещи из вашего делегата приложения, но если вам все равно, просто используйте NotificationCenter, потому что это наименее эффективная работаи хорошо понятный образец яблока.

0 голосов
/ 27 марта 2019

Вы можете использовать делегата для уведомления вашего ViewController.

Это интерфейс делегата:

@protocol UniversalOverrideURLObserver

func onURLChanged(url: String) -> Void

@end

Ваш ViewController может реализовать этот интерфейс:

class ViewController: UIViewController,  UniversalOverrideURLObserver {

}

Тогда ваш код, который создает экземпляр ViewController, может сделать что-то вроде этого:

func addObserver(observer: UniversalOverrideURLObserver) -> Void {
    self.observer = observer
}

func funcWhereValueChanges() {
    // HERE your url changed    
    self.observer.onURLChanged(url: newURL)
}

func funcWhereViewControllerShown() {
    // HERE you are ready to present ViewController
    let vc = ViewController()
    self.addObserver(vc)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...