What you did is probably the best way of doing it from all perspective but amount of code that is being used. Since your parent (page view controller) is responsible for all the work it is best to also channel all data it needs. Currently that is between 2 view controllers and later it might be between 3. You might also simply change these view controllers but preserve the protocols you use to retrieve the data.
But there is a big catch here. If a number of view controllers will grow then you might find yourself in an issue where previous view controllers are being deallocated (if this is not already going on) so at the end there is no way for view controller D
to access view controller A
simply because A
no longer exists.
What the solution to these things is really depends but from your question I can assume you are passing some data from one view controller to another like onboarding where you are collecting user data through multiple screens. In such case it is best to have a class with all the data needed like:
class MyData {
var dataA: DataA?
var dataB: DataB?
var dataC: DataC?
}
Now the page controller is responsible to create such data and pass them to each of these view controllers that will use/modify the data. So in page view controller:
var myData: MyData = MyData()
func prepareViewControllerA() {
let controller: ViewControllerA...
controller.myData = myData
...
}
Now each of the view controllers will have its own property to access the same data object and modify it. You could also add a delegate to your class so page controller may listen to its events:
protocol MyDataDelegate: class {
func myData(_ sender: MyData, updatedA: DataA?)
func myData(_ sender: MyData, updatedB: DataB?)
func myData(_ sender: MyData, updatedC: DataC?)
func myDataAreFinalized(_ sender: MyData)
}
class MyData {
var dataA: DataA? {
didSet {
delegate?.myData(self, updatedA: dataA)
}
}
var dataB: DataB? {
didSet {
delegate?.myData(self, updatedB: dataB)
}
}
var dataC: DataC? {
didSet {
delegate?.myData(self, updatedC: dataC)
}
}
weak var delegate: MyDataDelegate?
func finalize() {
delegate?.myDataAreFinalized(self)
}
}
And now your page controller can use it:
var myData: MyData = {
let data = MyData()
data.delegate = self
return data
}()
and delegates:
func myData(_ sender: MyData, updatedA: DataA?) {
}
func myData(_ sender: MyData, updatedB: DataB?) {
}
func myData(_ sender: MyData, updatedC: DataC?) {
}
func myDataAreFinalized(_ sender: MyData) {
dismiss(animated: true, completion: nil)
}