Search code examples
swiftsegueprotocols

Sending data using protocols


I have issues with using protocols to send data back to previous controller. I have studied SO questions and guides, but for some reason my data doesn't get transferred back.

In my second class I create data, that is later being sent back to first class:

protocol ImageEditorDelegate {
    func sendImage(image: UIImage, id: String)
}

class PhotoEditorViewController: UIViewController { 

    var delegate: ImageEditorDelegate?

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

@IBAction func didPressSave(_ sender: UIButton) {
        delegate?.sendImage(image: finalImage, id: imageThatWasSelected)
        self.dismiss(animated: true, completion: nil)
    }

}

And in my receiving class I have:

class NewProductViewController: UIViewController, ImageEditorDelegate { 

    var imageEditor: PhotoEditorViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        imageEditor?.delegate = self
    }

func sendImage(image: UIImage, id: String) {
        print("Receiving images", image, id)
        switch id {
        case "1":
            selectedImages[1] = image
            productImage1.image = image
        case "2":
            selectedImages[2] = image
            productImage2.image = image
        case "3":
            selectedImages[3] = image
            productImage3.image = image
        default:
            break
        }
    }
}

But nothing happens, this func never gets called. I think my delegate is nil, or so, but how could I fix this issue? I have Also, I'm using VIPER as architecture with slightly customized segues, may this be the issue? I have tried simple segues, but had same issue.

I understand that this is rather simple question, but I couldn't understand what I doing wrong after I have read articles about protocols.

Thanks for your help!


Solution

  • What you're doing is very wrong. You have two view controllers with property references to one another:

    class PhotoEditorViewController: UIViewController { 
        var delegate: ImageEditorDelegate?
    }
    class NewProductViewController: UIViewController, ImageEditorDelegate { 
        var imageEditor: PhotoEditorViewController?
    }
    

    Those are not weak references, so if you ever do get this to work — that is, if you ever arrange things so that the NewProductViewController's imageEditor is a PhotoEditorViewController whose delegate is that NewProductViewController — you will have a nasty retain cycle and a memory leak.

    This suggests that you have not understood the protocol-and-delegate pattern. Only the presented view controller should have a delegate property pointing back to the presenter, and it should be weak. The presenter does not need any property pointing to the presented view controller, because it presents it.