Упрощение быстрого уведомления центра событий и наблюдателей - PullRequest
0 голосов
/ 26 апреля 2018

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

Событие, класс, который отправляет событие в центр уведомлений

import Foundation

enum EventName: String {
    case ProfileUpdate
    case ApplicationDidPreload
}

class Event {

    static let shared: Event = Event()

    /// Post event to notification center
    /// - Parameter event: event name to post
    /// - Parameter object: data you're going to pass
    /// - Parameter userInfo: user info
    func post(event: EventName, object: Any? = nil, userInfo: [AnyHashable : Any]? = nil) {
        let notification: Notification = Notification(name: Notification.Name(rawValue: event.rawValue), object: object, userInfo: userInfo)
        NotificationCenter.default.post(notification)
    }
}

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

import Foundation

class EventListener {

    typealias callback = () -> ()
    typealias callbackWithData = (_ data: Any) -> ()

    static let shared: EventListener = EventListener()
    private var callback: callback?
    private var callbackWithData: callbackWithData?

    /// Listen event which not return any data in callback closure
    /// Parameter event: event name to listen
    /// Parameter callback: callback closure
    func listenEvent(event: EventName, callback: @escaping callback) {
        self.callback = callback
        self.addObserver(event: event)
    }

    /// Listen event which returns data in callback closure
    /// Parameter event: event name to listen
    /// Parameter callback: callback closure
    func listenEvent(event: EventName, callbackWithData: @escaping callbackWithData) {
        self.callbackWithData = callbackWithData
        self.addObserver(event: event)
    }

    /// Add and setup observer to notification center
    private func addObserver(event: EventName) {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.handler),
                                               name: NSNotification.Name(rawValue: event.rawValue),
                                               object: nil)
    }

    /// Handle notification observer
    @objc private func handler(notification: Notification) {
        guard let data = notification.object else {
            self.callback?()
            return
        }

        self.callbackWithData?(data)
    }
}

Пример использования

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            Event.shared.post(event: .ApplicationDidPreload)
            Event.shared.post(event: .ProfileUpdate, object: 1)
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        EventListener.shared.listenEvent(event: .ApplicationDidPreload, callback: self.test1)
        EventListener.shared.listenEvent(event: .ProfileUpdate, callbackWithData: self.test2)
    }

    private func test1() {
        print("preloaded")
    }

    private func test2(data: Any) {
        print("profile id")
        let Id: Int? = data as? Int
        print(Id)
    }
}

1 Ответ

0 голосов
/ 26 апреля 2018

ИМХО Класс Event для отправки в центр уведомлений не нужен, лучше расширить Notification.Name вроде

extension Notification.Name {
  static let MyNotificationName = Notification.Name("MyNotificationName")
}

, что позволяет просто использовать .MyNotificationName в качестве имени уведомления.

Для использования блока при прослушивании уведомления вы также можете использовать существующую блочную версию наблюдателя:

func addObserver(forName name: NSNotification.Name?, 
                   object obj: Any?, 
                        queue: OperationQueue?, 
                  using block: @escaping (Notification) -> Void) -> NSObjectProtocol
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...