Вызов функции из другого класса (Паттерн Наблюдатель) Swift 5

Одна из частых задач при написании приложения на Swift - передача данных из одного VC в другой. На этот раз мне нужно было вызвать функцию и остановить воспроизведение аудиопотока из нового VC.

Имеется два контроллера:

В ViewController есть функция pausePlayback(), останавливающая воспроизведение аудио.

class ViewController: UIViewController {
    //CODE

    override func viewDidLoad() {
        super.viewDidLoad()
        //CODE
    }

    //Pause the playback
    @objc func pausePlayback() {
        radioPlayer.pause()
    }
}

В TimerViewController есть кнопка, при нажатии которой через 2.0 секунды выполняется функция timerButton().

class TimerViewController: UIViewController {

    @IBAction func timerButton(_ sender: Any) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            // Delayed code
            print(“This worked”)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Задача: вызвать функцию `pausePlayback() из первого View Controller:

Есть три основных способа, описанные в этой статье на Medium. Я выбрал первый, с примером из этой статьи. Этот паттерн называется "Наблюдатель". Больше информации на русском здесь.

В первый VC добавляем переменную ncObserver, а в viewDidLoad() добавляем функцию наблюдателя:

class ViewController: UIViewController {

    let ncObserver = NotificationCenter.default  

    override func viewDidLoad() {
        super.viewDidLoad()

        ncObserver.addObserver(self, selector: #selector(self.pausePlayback), name: Notification.Name(“PauseMusic”), object: nil)
    }

    //Pause the playback
    @objc func pausePlayback() {
        radioPlayer.pause()
    }
}

В TimerViewController добавляем переменную notification для оповещений, а в функцию, вызываемую кнопкой, добавляем результат оповещения: self.notification.post().

class TimerViewController: UIViewController {

    let notification = NotificationCenter.default
    @IBAction func timerButton(_ sender: Any) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
            // Code you want to be delayed
            print(“This worked”)
            self.notification.post(name: Notification.Name(“PauseMusic”), object: nil)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Готово! Теперь функция из одного VC вызывается в другом!

August 13, 2019