Say I have multiple view controllers in my Swift app and I want to be able to pass data between them. If I\'m several levels down in a view controller stack, how do I pass d
Instead of creating a data controller singelton I would suggest to create a data controller instance and pass it around. To support dependency injection I would first create a DataController
protocol:
protocol DataController {
var someInt : Int {get set}
var someString : String {get set}
}
Then I would create a SpecificDataController
(or whatever name would currently be appropriate) class:
class SpecificDataController : DataController {
var someInt : Int = 5
var someString : String = "Hello data"
}
The ViewController
class should then have a field to hold the dataController
. Notice that the type of dataController
is the protocol DataController
. This way it's easy to switch out data controller implementations:
class ViewController : UIViewController {
var dataController : DataController?
...
}
In AppDelegate
we can set the viewController's dataController
:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let viewController = self.window?.rootViewController as? ViewController {
viewController.dataController = SpecificDataController()
}
return true
}
When we move to a different viewController we can pass the dataController
on in:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
...
}
Now when we wish to switch out the data controller for a different task we can do this in the AppDelegate
and do not have to change any other code that uses the data controller.
This is of course overkill if we simply want to pass around a single value. In this case it's best to go with nhgrif's answer.
With this approach we can separate view form the logic part.