iosswiftfirebasexlpagertabstrip

Sharing data between tabs using XLPagerTabStrip


I'm using XLPagerTabStrip - https://github.com/xmartlabs/XLPagerTabStrip to have two tabs which share the same dataset.

For the data set, in my main view (which hosts two tabs) I have a call to Firebase to get the data. Once received I make a Notification call to post the data -> N.B. I'm sure this isn't the most elegant way of doing this so if anyone has suggestions on a better way please let me know (albeit thats a separate question in itself).

Anyway - in both tabs I have observers for this notification.

This works great on the initial tab, however it appears the 2nd tab is not initialised until the User taps on the tab -> makes sense for memory reasons :) But this means the post in MainVC gets missed...

How can I get both tabs to essentially use the same dataset from a Firebase call?

My high level code is as follows (I can add more detail if required, let me know whats missing 🙂):

class MainVC: ButtonBarPagerTabStripViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        getData()
    }

    fileprivate func getData() {
        // ... bunch of firebase stuff...

        NotificationCenter.default.post(
            name: NSNotification.Name(rawValue: "dataReceived"),
            object: nil,
            userInfo: ["data": data]
        )
    }

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        let tab_one = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "tab_one")

        let tab_two = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "tab_two")

        return [tab_one, tab_two]
    }
}

class TabOneVC: UIViewController, IndicatorInfoProvider {

    override func viewDidLoad() {
        super.viewDidLoad()

        print("Hello from Tab One")

        NotificationCenter.default.addObserver(
          self,
          selector: #selector(dataReceivedHandler(notfication:)),
          name: NSNotification.Name(rawValue: "dataReceived"),
          object: nil
        )
    }

    @objc func dataReceivedHandler(notfication: NSNotification) {
        // ... process data received
    }
}

class TabTwoVC: UIViewController, IndicatorInfoProvider {

    override func viewDidLoad() {
        super.viewDidLoad()

        print("Hello from Tab Two")

        ... same notification code as per Tab One 
    }
}

I suppose Core Data might be needed instead but I will only go down that route if its the only way (without horrendous hacks)

Thanks in advance!


Solution

  • So I managed to get this working but not entirely sure if this is the best way so will leave this open for a little bit

    What I done is to have MainVC reload the view

    The Tab VCs both shares the same data property in MainVC - which is what I think you were suggesting Ajay...

    class MainVC: ButtonBarPagerTabStripViewController {
    
        var data: [DataModel] = []
    
        fileprivate func getData() {
            // ... bunch of firebase stuff...
    
            // assign the data
            self.data = data
    
            // reload the view now we have data 
            // (doubt this is good practice...)
            self.reloadPagerTabStripView()
        }
    }
    

    Both tabs get the data from MainVC like so...

    class TabOneVC: UIViewController, IndicatorInfoProvider {
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
    
            // Get data in MainVC
            if let mainVC = self.parent as? MainVC {
                data = mainVC.data // woohoo :)
            }
        }
    }