The following is a guest post by James Lin and originally appeared on his blog. James is currently in the iOS-000 class at The Flatiron School. You can follow him on Twitter here.
Passing objects between views controllers is tricky in iOS.
In this example, I created a OneViewController and a TwoViewController. We are going to call them ONE and TWO for short.
We are going to pass a Person object from ONE to TWO.
The Person class just has a ‘name’ property:
Lets say we create a Person class in ONE and stored it in a property called myPerson. How do we pass it to TWO? We are going to assign a property called otherPerson in TWO to point to ONE’s myPerson.
But how do we get access to a pointer to TWO? Since we are using a Navigation Controller, we can access it in the prepareForSegue method.
Now lets say I want to create a Person object assigned to TWO’s myPerson property. How would I pass it back to ONE?
The bad way is to find a pointer to ONE and set its otherPerson property to TWO’s myPerson:
Although this works, theres a couple of problems. First, it accesses the navigationControllers array to get to ONE. This is clearly pretty hacky. It also forces TWO to have to know about ONE, and can only return the Person it created to ONE. This is the tight coupling situation which we want to avoid. Second, suppose in the future if we wanted the button on TWO to be able to send the Person object to a new view controller called THREE instead? How would it do that?
The recommended solution is to use Delegates to pass the Person object.
We will first need to define a protocol on TWO
Now in ONE’s prepareForSegue method we need to set TWO’s delegate to self (the part I always forget.)
We can erase any reference to ONE from TWO, such as an import that we needed before. The beauty of delegation is that TWO doesn’t have to know who implements it.
We can change the sendButton action to pass the Person object back through the delegate:
Lastly, we implement the delegate method in ONE
tldr:
Using the Delegate pattern for object back-passing in ViewControllers results in a cleaner and more flexible code. This is also the Apple recommended way.