Passing data between view controllers in Swift

This article will show how you can pass data between view controllers in Swift.

Passing data between view controllers is a crucial aspect of iOS app development. There are several ways to achieve this in Swift, and I’ll cover some of the common methods.

For the purpose of this tutorial, I’ll assume you have a basic understanding of Swift and Xcode.

1. Using Segues:

Segues are a convenient way to transition between view controllers. You can use them to pass data from one view controller to another.

Create Segue in Storyboard

  • Open your storyboard in Xcode.
  • Control-drag from the source view controller to the destination view controller.
  • Choose the appropriate segue type (e.g., Push, Present Modally).
  • Select the segue, and in the Attributes inspector, give it an identifier (e.g., “ShowDetail”).

PrepareForSegue Method

In the source view controller, implement the prepare(for:sender:) method.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowDetail" {
        if let destinationVC = segue.destination as? DetailViewController {
            destinationVC.dataToPass = "Hello from the source view controller!"
        }
    }
}

Explanation:

  • This code is part of the source view controller.
  • It overrides the prepare(for:sender:) method, which is called before a segue is performed.
  • It checks the segue identifier to ensure it’s the correct segue (“ShowDetail”).
  • It retrieves the destination view controller (DetailViewController) from the segue and sets the dataToPass property.

Access Data in Destination View Controller

In the destination view controller (DetailViewController), declare a variable to receive the data.

class DetailViewController: UIViewController {
    var dataToPass: String?

    // Rest of your code
}

Explanation:

  • This code is part of the destination view controller.
  • It declares a variable (dataToPass) to receive the data passed from the source view controller.
  • You can use dataToPass in the destination view controller’s code.

2. Using Delegation:

Delegation is a design pattern where one object delegates a task to another. In the context of passing data between view controllers, you can use delegation.

Create a Protocol

Define a protocol in the source view controller.

protocol DataPassingDelegate: AnyObject {
    func passData(data: String)
}

Explanation:

  • This code defines a protocol (DataPassingDelegate) in the source view controller.
  • The protocol declares a method (passData(data:)) that the destination view controller will implement.

Adopt the Protocol

Make the source view controller conform to the protocol.

class SourceViewController: UIViewController, DataPassingDelegate {
    // ...
}

Explanation:

  • The source view controller adopts the DataPassingDelegate protocol.

Implement the Protocol Methods

Implement the protocol method in the source view controller.

func passData(data: String) {
    // Handle the passed data
    print("Data received in source view controller: \(data)")
}

Explanation:

  • It implements the passData(data:) method to handle the passed data.

Set the Delegate in PrepareForSegue

In the prepare(for:sender:) method, set the destination view controller as the delegate.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowDetail" {
        if let destinationVC = segue.destination as? DetailViewController {
            destinationVC.delegate = self
        }
    }
}

Explanation:

  • In the prepare(for:sender:) method, the source view controller sets itself as the delegate of the destination view controller.

Use the Delegate in the Destination View Controller

In the destination view controller, declare a delegate variable.

class DetailViewController: UIViewController {
    weak var delegate: DataPassingDelegate?

    // Rest of your code
}

Explanation:

  • The destination view controller declares a delegate variable (delegate) conforming to the DataPassingDelegate protocol.

Call the delegate method where you want to pass the data.

// Inside some method in DetailViewController
delegate?.passData(data: "Hello from the destination view controller!")

Explanation:

  • It calls the delegate method (passData(data:)) when needed, passing the desired data.

3. Using NotificationCenter:

NotificationCenter allows you to broadcast messages within an app.

Post a Notification

In the source view controller, post a notification with the data.

let dataToPass = "Hello from the source view controller!"
NotificationCenter.default.post(name: Notification.Name("DataNotification"), object: dataToPass)

Explanation:

  • This code in the source view controller posts a notification with a specified name (“DataNotification”) and includes the data as the object.

Observe the Notification

In the destination view controller, observe the notification.

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(handleDataNotification(_:)), name: Notification.Name("DataNotification"), object: nil)
}

@objc func handleDataNotification(_ notification: Notification) {
    if let data = notification.object as? String {
        // Use the passed data
        print("Data received in destination view controller: \(data)")
    }
}

Explanation:

  • In the destination view controller, it observes the notification using addObserver(_:selector:name:object:) in the viewDidLoad method.
  • The handleDataNotification(_:) method is called when the notification is received, extracting the data from the notification object.

Remember to remove observers in deinit or appropriate lifecycle methods to prevent memory leaks.

Choose the method that best fits your app’s architecture and requirements. Each method has its pros and cons, so consider the specific needs of your application when deciding which approach to use.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top