Thiha Aung
Thiha Aung

Reputation: 5106

Swift Delegates and Protocol

I am learning swift protocol and delegate pattern.But,I really need help with the following problem which return me empty results

At ViewController 1 :

protocol GetAllDataProtocol{
     func didReadInfo(info : [[String:String]])
}
class ViewController1 : {
     var delegate : GetAllDataProtocol?
     var info_data : [[String:String]] = []

     override func viewDidLoad() {

         readData()
     }

     func readData(){
         info_data.append(["ID" :"234FD","ADDRESS":"Maimi","TYPE":"A"])
         delegate?.didReadInfo(info_data)
     }
}

Then at ViewController 2 :

class SubmissionViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate,GetAllDataProtocol{
      var info_data = [[String:String]]()

      @IBAction func submitTapped(sender: AnyObject) {
           print("After : \(info_data)")
      }

      func didReadInfo(info: [[String : String]]) {
           dispatch_async(dispatch_get_main_queue(),{
               self.info_data = info
               print("Before : \(self.info_data)")
           })
      }
}

When it run

After : []

Why it didnt run "before?" and why i can't get the data.

Upvotes: 1

Views: 1193

Answers (2)

JulianM
JulianM

Reputation: 2550

You aren't setting the reference of the delegate as Ahmed Lotfy explained.

Maybe you are missing the point that a protocol only is a kind of a template or commitment. So if you define a protocol with your function

 func didReadInfo(info : [[String:String]])

you are saying "Hey, every class that conforms to the protocol XYZ should have implemented this method." And by declaring a delegate variable on your "ViewController1" class that should be conform to protocol "GetAllDataProtocol", you just ensure that you can call the function "didReadInfo" on that object. But this variable is not set anywhere, thats why your call

delegate?.didReadInfo(info_data)

has no effect. The optional chaining of "delegate?." does not succeeds and the function "didReadInfo" is never called.

Upvotes: 1

Ahmed Lotfy
Ahmed Lotfy

Reputation: 3906

SubmissionViewController should have referenece on ViewController1. In viewDidLoad() method assign viewController.delegate to self.

The code:

class SubmissionViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate,GetAllDataProtocol{
    var info_data = [[String:String]]()
    var viewController1:ViewController1?

    override func viewDidLoad() {
        //You should here load viewController1 or connect it by outlet in above
        let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
        viewController1 = storyboard.instantiateViewControllerWithIdentifier("ViewController1") as? ViewController1
        self.viewController1!.delegate = self
    }
    @IBAction func submitTapped(sender: AnyObject) {
        print("After : \(info_data)")
    }

    func didReadInfo(info : [[String:String]]) {
        dispatch_async(dispatch_get_main_queue(),{
            self.info_data = info
            print("Before : \(self.info_data)")
        })
    }
}

Upvotes: 1

Related Questions