Search code examples
iosswiftdelegatesprotocols

How to call protocol function correctly?


So, I need to make notification handler class for each notification that my app received from the server. I make class like below for that purpose:

protocol NotificationHandlerDelegate: class {
    func receiveNotification(content: Any)
}

class NotificationHandler{

   var delegate : NotificationHandlerDelegate!

   func handleTransactionNotif(content: Any, rootVC: UIViewController){

       delegate?.receiveNotification(content: content)
       ((rootVC as! UINavigationController).viewControllers[0] as! UITabBarController).selectedIndex = 3

   }


}

And below is how I called it on my view controller:

class TransactionsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, TransactionsCellDelegate, NotificationHandlerDelegate{

   override func viewWillAppear(_ animated: Bool) {
       let nh = NotificationHandler()
       nh.delegate = self

       self.navigationController?.navigationBar.isHidden = true
   }


   func receiveNotification(content: Any) {
       print("called: \(content)")
       let contentJSON = JSON(content)
       goToScreenAccording(to: "\(contentJSON["status"])", selectedData: content as! [String: Any])
   }

}

the problem is that receiveNotification not called whenever I receive notification. Am I doing something wrong?


Solution

  • Use NotificationHandler as singleton, so you can refer to the same instance:

    class NotificationHandler {
    
       weak var delegate: NotificationHandlerDelegate?
    
       static let shared = NotificationHandler()
    
       private init(){}
    
       func handleTransactionNotif(content: Any, rootVC: UIViewController){
    
           delegate?.receiveNotification(content: content)
       ((rootVC as! UINavigationController).viewControllers[0] as! UITabBarController).selectedIndex = 3
    
       }
    }
    
    class TransactionsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, TransactionsCellDelegate, NotificationHandlerDelegate{
    
       override func viewWillAppear(_ animated: Bool) {
           let nh = NotificationHandler.shared
           nh.delegate = self
           self.navigationController?.navigationBar.isHidden = true
       }
       //...
    }
    

    And remember to use NotificationHandler.shared in AppDelegate too.