NSNotification & NotificationCenter

Nesneler arası iletişim için kullanılabilecek yöntemlerden biri NotificationCenter’dır. Bu yapıda siz bir veriyi post ettiğiniz zaman register olmuş tüm nesnelerin bu veriyi alması sağlanır. Örneğin; bir UITextField nesnesine veri girdiğiniz zaman cihaz üzerinde keyboard görüntülenmektedir. Bu durumda size UIKeyboardWillShowNotification isminde bir notification gönderilmektedir ve nesneleriniz içerisinde UIKeyboardWillShowNotification tanımlaması ile register olmuş tüm nesneler bu notification’ını alabilmektedir. Öncelikle keyboard örneği üzerinden gerekli kodlamayı yapalım.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(keybordShown), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    }
    @objc func keybordShown(notification : NSNotification) {

    }
}

ViewController nesnesi içerisinde UIKeyboardWillShow notification’ı için register olduk. Şu anlama geliyor, artık cihazın keyboard’u açılacağı zaman bu bilgi keyboardShown methoduna gönderilecektir. Bu durumda da örneğin klavyenin altında kalan bir UITextField üzerinde işlem yapıyorsanız, nesnelerinizi keyboard’un altında kalmayacak şekilde yukarı kaydırabilirsiniz. Benzer şekilde klavye tekrar gizlendiğinde de bir notification ile haberdar edilmek istiyorsanız UIKeyboardWillHide notification’ına da register olmanız gerekecektir. Burada önemli olan bir diğer nokta addObserver diyerek register olduğunuz notification siz kaldırmadığınız sürece aktif kalacaktır ve keyboard her açıldığında tüm nesnelerde register olmuş methodlar tetiklenecektir. Buna uygulamanızın çalışma mantığını göz önünde bulundurarak dikkat etmeniz gerekmektedir. Klavyenin kontrol edildiği bu örnekte ViewController nesnesi görüntülendiği zaman notification’ının eklenmesi ve bu ekran değiştiği durumda da notification havuzundan çıkılması gerekmektedir. Bunu doğru yönetmezseniz örneğin başka bir ekrandaki klavye açıldığı durumdada ViewController içerisindeki method tetiklenecek ve aslında gereksiz bir işlem gerçekleşecektir. Bunun için yukardaki viewDidLoad içerisinde yapılan tanımlama aslında viewWillAppear içerisinde yapılması ve viewWillDissapear olduğunda da notificationcenter’dan çıkarılması gerekmektedir. Bunu aşağıdaki şekilde gerçekleştirebilirsiniz.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        NotificationCenter.default.addObserver(self, selector: #selector(keybordShown), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    }
    @objc func keybordShown(notification : NSNotification) {

    }
}

Fakat her durumda bu yapı doğru değildir. Siz ekrandan çıkmış olsanız da Notification’ın aktif kalmasını isteceğiniz durumlarda söz konusudur. Örneğin arka planda müzik çalınmasını sağlayan bir ekranınız var ise ve müziği durdurmak için bir Notification’a sahipse siz ekrandan ayrılsanız bile Notification’ın aktif kalması gerekmektedir ki başka ekranlardan müziğin durdurulması sağlanabilsin. Yani notification’ı ne zaman ekleyeceğinizi ve ne durumda kaldıracağınızı yapacağınız işe göre belirlemelisiniz. Bu şekilde ekranda ayrılsak bile silinmemesi gereken bir notification var ise aşağıdaki şekilde kodlayabiliriz.

let stopPlayerNotification = NSNotification.Name.init("StopPlayer")

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
         NotificationCenter.default.addObserver(self, selector: #selector(stop), name: stopPlayerNotification, object: nil)
    }
    deinit {
     NotificationCenter.default.removeObserver(self, name: stopPlayerNotification, object: nil)
    }
    @objc func stop(notification : NSNotification) {

    }
}

Göreceğiniz gibi bu durumda viewDidLoad içerisinde Notification’ı ekleyip, deinit olduğu durumda da remove etmek yeterli olacaktır. Burada bazı açıklamalar yapmak istiyorum.

  • let stopPlayerNotification = NSNotification.Name.init(“StopPlayer”)
    Siz bir notification tanımlayacağınız zaman yukarıdaki gibi StopPlayer benzeri bir key belirleyip, notification bu key ile eklemeniz, notification herhangi bir ekrandan tetikleneceği zamanda yine bu key’i kullanarak notification’ı göndermeniz gerekmektedir.

Size ait bir notification’ı herhangi bir başka ekrandan aşağıdaki şekilde tetikleyebilirsiniz. Bu işlem sonrasından register olmuş tüm nesneler ve methodlar tetiklenecektir.

NotificationCenter.default.post(name: stopPlayerNotification, object: nil)
Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn
Bu yazıyı beğendiyseniz daha fazla kişiye ulaşmasını sağlamak için paylaşabilirsiniz.