Search code examples
iosswiftmodel-view-controllerdelegatesprotocols

Protocol-Delegate pattern not notifying View Controller


My Model saves data to Firestore. Once that data is saved, I'd like it to alert my ViewController so that a function can be called. However, nothing is being passed to my ViewController.

This is my Model:

protocol ProtocolModel {
    func wasDataSavedSuccessfully(dataSavedSuccessfully:Bool)
}

class Model {

    var delegate:ProtocolModel?

    func createUserAddedRecipe(
        docId:String,
        completion: @escaping (Recipe?) -> Void) {

            let db = Firestore.firestore()

                do {
                    try db.collection("userFavourites").document(currentUserId).collection("userRecipes").document(docId).setData(from: recipe) { (error) in

                        print("Data Saved Successfully") // THIS OUTPUTS TO THE CONSOLE
                        
                        // Notify delegate that data was saved to Firestore
                        self.delegate?.wasDataSavedSuccessfully(dataSavedSuccessfully: true)
                     }
                }
                catch {
                    print("Error \(error)")
                }
    }
}

The print("Data Saved Successfully") outputs to the console, but the delegate method right below it doesn't get called.

And this is my ViewController:

class ViewController: UIViewController {
    
    private var model = Model()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        model.delegate = self
    }
}

extension ViewController: ProtocolModel {
    func wasDataSavedSuccessfully(dataSavedSuccessfully: Bool) {
        if dataSavedSuccessfully == true {
            print("Result is true.")
        }
        else {
            print("Result is false.")
        }
        
        print("Protocol-Delegate Pattern Works")
    }
}

Is there something I'm missing from this pattern? I haven't been able to notice anything different in the articles I've reviewed.


Solution

  • So I test your code and simulate something like that

    import UIKit
    
    protocol ProtocolModel {
        func wasDataSavedSuccessfully(dataSavedSuccessfully:Bool)
    }
    
    class Model {
        
        var delegate:ProtocolModel?
        
        // I use this timer for simulate that firebase store data every 3 seconds for example
        var timer: Timer?
        
        func createUserAddedRecipe(
            docId:String) {
                
                timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: true, block: { _ in
                    self.delegate?.wasDataSavedSuccessfully(dataSavedSuccessfully: true)
                })
            }
    }
    
    class NavigationController: UINavigationController {
        
        var model = Model()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            model.delegate = self
            // Call this method to register for network notification
            model.createUserAddedRecipe(docId: "exampleId")
        }
    }
    
    extension NavigationController: ProtocolModel {
        func wasDataSavedSuccessfully(dataSavedSuccessfully: Bool) {
            print(#function)
        }
    }
    

    so you can see the result as image below, my delegate update controller that conform to that protocol.

    enter image description here