How do you pass data between view controllers in Swift?

One solution would be to override prepareForSegue(segue:sender:) from within the view controller which contains the data that you wish to pass to the destination view controller.

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == "YourSegueName") {
        //get a reference to the destination view controller
        let destinationVC:ViewControllerClass = segue.destinationViewController as! ViewControllerClass

        //set properties on the destination view controller
        destinationVC.name = viewName
        //etc...
    }
}

For Swift 3.0

final class Shared {
     static let shared = Shared() //lazy init, and it only runs once

     var stringValue : String!
     var boolValue   : Bool!
}

To set stringValue

Shared.shared.stringValue = "Hi there"

to get stringValue

 if let value = Shared.shared.stringValue {
        print(value)
 }

For Swift version below 3.0

You can pass data between views using singleton class. It is easy and efficient way. Here is my class ShareData.swift

import Foundation

class ShareData {
    class var sharedInstance: ShareData {
        struct Static {
            static var instance: ShareData?
            static var token: dispatch_once_t = 0
        }

        dispatch_once(&Static.token) {
            Static.instance = ShareData()
        }

        return Static.instance!
    }


    var someString : String! //Some String

    var selectedTheme : AnyObject! //Some Object

    var someBoolValue : Bool!
}

Now in my ViewControllerOne I can set above variable.

//Declare Class Variable

let shareData = ShareData.sharedInstance

override func viewDidLoad() {
    self.shareData.someString ="Some String Value"
}

And in my ViewControllerTwo I can access someString as

let shareData = ShareData.sharedInstance
override func viewDidLoad() {
    NSLog(self.sharedData.someString) // It will print Some String Value
}

Personally, I prefer ways as follow:

  • If you want to jump forward between two view controllers (from A to B), as -pushViewController:animated: in navigation, you can define a property of model for Controller B and expose it publicly, then set this property explicitly before jumping from Controller A, it's pretty straightforward;

  • In case you want to jump backward from Controller B to A, use Delegate+Protocol mode. Controller B drafts a public protocol and own a "delegate" property, any object who would like to be the delegate of Controller B shall comply and implement its protocol(optionally). then prior to the jumping-backward, Controller B makes its delegate perform certain action(s) listed in protocol, the data could be transferred in this way;

  • Under certain circumstance, you may want to transfer data from a Controller(or controllers) to other multiple Controllers, use Notification mechanism if this is the case.

Apple has detailed instructions about delegate mode, notification mode in official documentation, check them out in XCode, :)


Just need to follow 3 steps, let's assume you want to pass data from ViewControllerA to ViewControllerB:

  1. create a segue between ViewControllerA and ViewControllerB
  2. name the segue with a Identifier in the attributes inspector of it
  3. override the prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) at ViewControllerA

For step#3,:

  • if you are not using swift 2.1, please follow @Scott Mielcarski 's answer at this question
  • for people who are using swift 2.1, or who get error "Cannot convert value of type 'UIViewController' to specified type 'your view Controller class name', After following @Scott Mielcarski 's answer at this question, Please use:let destinationVC:ViewControllerClass = segue.destinationViewController as! ViewControllerClass instead of let destinationVC:ViewControllerClass = segue.destinationViewController

    This is tested on Swift 2.1.1 and it works for me.