2

I have the following setup :

Storyboard.main

  1. Launch VC performs an asynchronous API request in a closure dataGatheringClosure

  2. The dataGatheringClosure closure's completion handler passes the result to VC1 via delegation using protocol method setData.

  3. Within setData, VC1 passes the result to VC2 using the following code:

    if let vc2 = self.tabBarController?.viewControllers?[1] as? VC2Controller {
        vc2.data = result
    }
    

I'm able to transfer data from the Launch VC to VC2, but now I need to refresh the data by performing the dataGatheringClosure in Launch VC.

My question is: How do I access Launch VC's methods from VC2? And is this approach sound?

As a workaround, I copied the dataGatheringClosure closure code inside TabBar VC and had VC 2 call its self.tabBarController.dataGatheringClosure method. However, it is duplicative, and also I don't know if it's best practice to execute heavy API requests within a TabBarController.

Zoe
  • 23,712
  • 16
  • 99
  • 132
ohBoy
  • 119
  • 1
  • 9
  • 1
    have look this repo simply show how to transfer data back and forth in viewcontrollers https://github.com/shauket/DataViewController – Shauket Sheikh Sep 24 '18 at 02:34

1 Answers1

0

The first step is to separate the data from the ViewControllers. Create a singleton class like below and use it to pass around the data you need.

class Data {

    static let shared = Data()
    // Declare any other data properties you need here...
    var result = [String]()

    private init() {}

    func initialize() {
        // Write code to initialize the data
        refresh()
    }

    func refresh() {
        // Write code to refresh the data
    }
}

Initialize data at app startup or wherever required using the below code:

Data.shared.initialize()

You can now access data from anywhere within your app using the static variable Data.shared. To refresh data you can do the following:

Data.shared.refresh()

Hope this helps.

Felix Marianayagam
  • 1,858
  • 1
  • 6
  • 22
  • 1
    have a look at this question https://stackoverflow.com/q/137975/2299040 – Sahil Manchanda Sep 24 '18 at 04:07
  • @SahilManchanda if I avoid using a singleton, what alternative ways are there to communicate back and forth between my controllers? – ohBoy Sep 24 '18 at 16:45
  • https://stackoverflow.com/q/5210535/2299040 this will give you a great direction :) – Sahil Manchanda Sep 24 '18 at 17:28
  • Delegate and singleton are both great choices. When using singleton just make sure you free the memory when you no longer need them. Just set Data.shared = nil. The declaration should change to: static let shared: Data! = Data(). Use them as you see fit for your current situation. – Felix Marianayagam Sep 24 '18 at 17:53
  • In one of my apps, I used singleton and it worked great for doing an async refresh on the data whenever the app received a notification from iCloud. In my case, many ViewControllers share the same data (for the lifecycle of the application) and it served the purpose. – Felix Marianayagam Sep 24 '18 at 18:00