1

I've read Trying to understand protocol/delegates in Swift, Passing data back from view controllers Xcode, and Pass data when dismiss modal viewController in swift in an attempt to pass some data back and forth. I think I did exactly what the posts described yet, the data is not being passed. I'm missing something and I have no idea what. If you could point out what that is, that would be so awesome. Thank you in advance :)

I should also mentioned that I presented the TaskMessageViewController using a modal segue. And I want to send data back to my TaskListViewController. I am currently using unwindToSegue to go back to the TaskListViewController.

In my Protocols.swift file, I have the following code:

import Foundation

protocol ReceiveMessageDelegate {
    func receiveMessageFromTaskMessageViewController (message: String)
}

And in my inheritance declarations, I have:

class TaskListViewController: UIViewController, ReceiveMessageDelegate

And in my TaskListViewController.swift, I wrote:

override func viewDidLoad() {
    super.viewDidLoad()

    let taskMessageViewController = TaskMessageViewController()
    taskMessageViewController.delegate = self

}

func receiveMessageFromTaskMessageViewController (message: String) {
    print(message)
    print("Protocol works!")
}

And in my TaskMessageViewController.swift, I wrote:

var delegate: ReceiveMessageDelegate?
@IBAction func doneButtonTapped(sender: AnyObject) {
    self.delegate?.receiveMessageFromTaskMessageViewController("message from message View Controller")
}

When I press the done button on the simulator, the doneButtonTapped gets executed. However, print("Protocol Works") never gets executed. Anybody have any suggestions?

Community
  • 1
  • 1
aejhyun
  • 582
  • 1
  • 5
  • 18
  • How do you present the view controller modally? If it is through a segue, you need to intercept the segue's destinationViewController, cast it as TaskMessageViewController and set the delegate on that object – Ian Dec 31 '15 at 08:52
  • I've presented the view controller modally using a segue. But the problem is I used `unwindToSegue` to get rid of the modal view and I'm trying to pass data from the modal view back to my view controller. – aejhyun Dec 31 '15 at 08:55

2 Answers2

1

When you want to pass messages between view controllers in swift, you generally do not need to create your own protocol. If you are trying to pass data when dismissing a modal view controller, you generally can identify the presented view controller and access its properties by identifying the segue's source view controller.

In this instance, the reason that the message is not being printed is because you are assigning self to the delegate of the instance "taskMessageViewController" which is a local constant of the viewDidLoad() method, and taskMessageViewController never escapes viewDidLoad(). You never set the delegate of self.

SwiftMatt
  • 839
  • 1
  • 9
  • 18
  • That's a good point. So I did `let taskMessageViewController = TaskMessageViewController() override func viewDidLoad() { super.viewDidLoad() taskMessageViewController.delegate = self }` However, this is still not causing the print statement to execute :( In other words, I declared `let taskMessageViewController = TaskMessageViewController()` outside the `videwDidLoad` function. – aejhyun Dec 31 '15 at 09:01
  • The reason is because you are calling the method receiveMessageFromTaskMessageViewController on self's delegate, not on your taskMessageViewController's delegate that you had set. You never set the delegate of self. – SwiftMatt Dec 31 '15 at 09:03
0

I read your question again. And I see you are using unwind segue. So you don't need delegate to pass message back. You should do like this:

In TaskMessageViewController.swift, define a variable message, and you override function prepareForSegue:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "identifierUnwind" {
        message = message
    }
}

And your TaskListViewController.swift, you can get it:

@IBAction func unwindToSegue (segue : UIStoryboardSegue) {
      if let taskMessageViewController = segue.sourceViewController as? TaskMessageViewController 
         print(taskMessageViewController.message)
         //OR save and do anything with it here.
      } 
 }
vien vu
  • 4,049
  • 1
  • 15
  • 30
  • I put the following code in my `TaskListViewController.swift`: `@IBAction func unwindToSegue (segue : UIStoryboardSegue) { if let taskMessageViewController = segue.sourceViewController as? TaskMessageViewController { taskMessageViewController.delegate = self } }` – aejhyun Dec 31 '15 at 09:06
  • However, this is still not causing the print statements to execute. – aejhyun Dec 31 '15 at 09:07
  • can you add to `@IBAction func doneButtonTapped(sender: AnyObject)` this line: `print(self.delegate?)` and give me result. – vien vu Dec 31 '15 at 09:12