iOS development
view controller communication
Swift programming
app development
iOS tutorial

Passing data between view controllers

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

When developing iOS applications, one common task is to navigate between different screens or views, often encapsulated by view controllers. Passing data between these view controllers is crucial for maintaining a fluid and responsive user experience within an app. This article dives into several methods available in iOS development to transfer data between view controllers, with detailed technical explanations and examples where relevant.

Methods for Passing Data Between View Controllers

Whether you're using storyboards or programmatically managing view controllers, there are several methods for passing data:

  1. Segues (Storyboards)
  2. Delegate Pattern
  3. Callbacks/Closures
  4. NotificationCenter
  5. Singletons
  6. Property Injection

Let's delve into each of these methods.

1. Segues (Storyboards)

In iOS, segues define a transition between two view controllers. Using segues with storyboards, you can pass data by overriding the prepare(for:sender:) method. This method is called just before a segue is executed.

swift
1override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
2    if let destinationVC = segue.destination as? DetailViewController {
3        destinationVC.data = self.data
4    }
5}

2. Delegate Pattern

The delegate pattern is a design pattern where one object in a program acts on behalf of, or in coordination with, another object. It is a powerful way to adopt single responsibility and separation of concerns principles in your app's architecture.

swift
1protocol DataPassingDelegate: AnyObject {
2    func passData(_ data: String)
3}
4
5class FirstViewController: UIViewController {
6    weak var delegate: DataPassingDelegate?
7    
8    func pushToNextVC() {
9        let secondVC = SecondViewController()
10        self.delegate = secondVC
11        delegate?.passData("Hello, Second VC!")
12        navigationController?.pushViewController(secondVC, animated: true)
13    }
14}
15
16class SecondViewController: UIViewController, DataPassingDelegate {
17    func passData(_ data: String) {
18        print(data)
19    }
20}

3. Callbacks/Closures

Closures in Swift are similar to blocks in C and Objective-C or lambdas in other languages. They can be used to pass data back to a previous screen.

swift
1class FirstViewController: UIViewController {
2    func pushToNextVC() {
3        let secondVC = SecondViewController()
4        secondVC.completionHandler = { data in
5            print("Data received: \(data)")
6        }
7        navigationController?.pushViewController(secondVC, animated: true)
8    }
9}
10
11class SecondViewController: UIViewController {
12    var completionHandler: ((String) -> Void)?
13    
14    func sendDataBack() {
15        completionHandler?("Hello from Second VC!")
16    }
17}

4. NotificationCenter

NotificationCenter is a powerful way to broadcast information within your app. It enables you to send messages across the app without directly linking the sender and receiver.

swift
1class FirstViewController: UIViewController {
2    override func viewDidLoad() {
3        super.viewDidLoad()
4        NotificationCenter.default.addObserver(self, selector: #selector(receiveData), name: .dataPassed, object: nil)
5    }
6    
7    @objc func receiveData(notification: Notification) {
8        if let data = notification.userInfo?["data"] as? String {
9            print("Data received: \(data)")
10        }
11    }
12}
13
14class SecondViewController: UIViewController {
15    func sendData() {
16        NotificationCenter.default.post(name: .dataPassed, object: nil, userInfo: ["data": "Hello, First VC!"])
17    }
18}
19
20extension Notification.Name {
21    static let dataPassed = Notification.Name("dataPassed")
22}

5. Singletons

Singletons ensure that a class has only one instance and provide a global point of access to it. While considered an anti-pattern by some due to its potential for misuse and difficult testing, it is a simple way to share data.

swift
1class DataManager {
2    static let shared = DataManager()
3    var data: String?
4    
5    private init() {}
6}
7
8class FirstViewController: UIViewController {
9    func updateData() {
10        DataManager.shared.data = "Updated Data"
11    }
12}
13
14class SecondViewController: UIViewController {
15    func fetchData() {
16        if let data = DataManager.shared.data {
17            print("Shared Data: \(data)")
18        }
19    }
20}

6. Property Injection

Property injection involves setting properties directly on a view controller before navigation. This is a straightforward way to pass data.

swift
1class FirstViewController: UIViewController {
2    func pushToNextVC() {
3        let secondVC = SecondViewController()
4        secondVC.data = "Passing Data"
5        navigationController?.pushViewController(secondVC, animated: true)
6    }
7}
8
9class SecondViewController: UIViewController {
10    var data: String?
11    
12    override func viewDidLoad() {
13        super.viewDidLoad()
14        if let dataReceived = data {
15            print("Received Data: \(dataReceived)")
16        }
17    }
18}

Summary

Here's a summary of the different methods for passing data between view controllers:

MethodCode SimplicityUse CaseNotes
SeguesMediumUse with storyboards. For simple data passing between two controllers.Integrated with storyboards.
Delegate PatternAdvancedWhen a child view controller needs to send data back to its parent.Promotes loose coupling.
Callbacks/ClosuresMediumFor callbacks after an action has occurred, e.g., completion handlers.Powerful and concise but may cause retain cycles.
NotificationCenterAdvancedBroadcasts data to multiple view controllers.Suitable for global notifications.
SingletonsEasySharing global application state/data.Can lead to tightly coupled code.
Property InjectionEasySimple direct data passing during navigation.Best for direct property setting.

Each method has its merits and is suitable for different scenarios in app development. Understanding these concepts will help you to make informed decisions when architecting interactions between view controllers in your iOS applications.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.