When developers first start iOS development, a problem that will arise pretty quickly is “How do I pass data between my objects?”. Fortunately, there are many solutions for you to choose from, but this causes a problem in itself. Which one to choose for your situation? It is important that you pick the correct solution for what you are trying to achieve. Three techniques are Notifications, Delegates and Closures. To demonstrate these in action, I will demonstrate with a small scenario where we have a LoginViewController and an AuthenticationSession. Our LoginViewController will take the users credentials and pass them to the AuthenticationSession, which will respond with the users’ unique identifier. The big question is, how do we get our userIdentifier back to our LoginViewController?
https://gist.github.com/rtking1993/74c844fa095266f764029ab78f91af20
Notifications:
A common and very flexible approach is using Notifications. To use Notifications we would simply have to add an observer to our LoginViewController object that wants to retrieve the userIdentifier and send a notification from the AuthenticationSession.
https://gist.github.com/rtking1993/af25a8498e1ae347678baff10a623f21
Now you might be thinking, brilliant I can copy this pattern to solve the problem and I don’t even need to read the other two… BUT WAAAAIT! Using notifications for this situation is the worst of the three options, let me explain why. Notifications were designed to be used in one to many relationships, i.e you can set multiple observers anywhere in your app and when you fire one notification every object observing the notification will react. This makes notifications extremely powerful tools, however, they should always be used sparingly. Medium to large sized apps with many notifications firing for different events are a nightmare to debug and maintain. It is very easy to lose context of what objects are interacting with each other. If two objects have a one to one relationship with each other, as they do in our Login case then it is always the best option to use Delegates or Closures.
Delegates:
Delegates are another approach which are a great way of passing data between two loosely coupled objects. Delegates are a lot easier to debug and maintain than notifications. Our LoginViewController simply needs to conform to our AuthenticationSessionDelegate and then will be notified by our AuthenticationSession every time we performLogin.
https://gist.github.com/rtking1993/a3bec3cc9c1a868bcd5c8482cad5f78e
Closures:
Closures are another great option for us to consider in this scenario. Closures require the least amount of boilerplate code and are easy to follow a logical flow. Closures are a very good way of passing data between two objects that have a one to one relationship and only have one flow to handle. Here our LoginViewController waits until AuthenticationSession has finished, inside the completion the userIdentifer is transferred.
https://gist.github.com/rtking1993/3f85d679e015868db61d19c15149d97b
Your situation will determine which one of these three techniques you use. All three are useful in different scenarios, so it is important to be comfortable to use each one. In our Login example, I would choose to use a closure. It is a great solution seeing as we are passing data between two objects in a one to one relationship. We also have only one completion option to handle. If we had more options I would consider using delegates instead. Because this is a one to one relationship, I would not choose to use Notifications.
To sum up, If you are passing data from one object to another, consider using delegates or closures first. However, if neither of those suit your needs, keep notifications open as an option as well.