0

I have MainViewController that is my UIPageViewController. Ther are 2 views FirstDataViewController and SecondDataViewController that i want to show.

I want to execute my request that updates items in MainViewControllre and then pass it to my 2 child views.

getData is my function that contains data from Request and then updates MainViewController's items

extension MainViewController {
    func getData() {
        getBasicData() { [weak self] (basicModel) in
            guard let strongSelf = self else { return }
            strongSelf.getExperienceData() { [weak self] (experienceModel) in
                guard let strongSelf = self else { return }

                let items = RequestItems(basicData: basicModel,
                                         experienceData: experienceModel)

                strongSelf.updateItems(items: items)
            }
        }
    }
}

MainViewController:

class MainViewController: UIPageViewController {

    var items: RequestItems

    let firstDataViewController: FirstDataViewController
    let secondDataViewController: SecondDataViewController

    let basicDataManager: APIManagerProtocol
    let experienceDataManager: APIManagerProtocol

    private(set) lazy var orderedViewControllers: [UIViewController] = {
        return [self.firstDataViewController, self.secondDataViewController]
    }()

    convenience init() {
        self.init(with: RequestItems())
    }

    init(with items: RequestItems) {

        self.items = items

        let apiManager = APIManager()
        basicDataManager = apiManager.createBasicDataManager()
        experienceDataManager = apiManager.createExperienceDataManager()

        self.firstDataViewController = FirstDataViewController(with: items)
        self.secondDataViewController = SecondDataViewController(with: items)

        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)

        self.edgesForExtendedLayout = []
    }

    func updateItems(items: RequestItems) {
        self.items = items
    }
}

How to use getData() function to update MainViewController items first and then pass data to child views? Or maybe there is just better option to do this?

Billy
  • 35
  • 1
  • 8

1 Answers1

0

It's not a good solution. "GetData" method needs some time to execute completely so you should:

  • Execute "getData" before load MainViewController, then pass "request items" to it and update yours views.

But I assume that your MainViewController is first controller in your application so you should:

  1. Add completion block to your "getData" method:

    func getData(_ completion: [RequestItems] -> ()) {
    
        getBasicData() { [weak self] (basicModel) in
    
            guard let strongSelf = self else { return }
    
            strongSelf.getExperienceData() { [weak self] (experienceModel) in
    
                guard let strongSelf = self else { return }
    
                let items = RequestItems(basicData: basicModel,
                                     experienceData: experienceModel)
    
                completion(items)
            }
        }
    }
    
  2. Add "updateItems" method to yours view controllers (instead of passing it in init method)

  3. Call your "getData" method with completion handler but outside of MainViewController init

    init(with items: RequestItems) {
        ...
        self.items = items
    
        self.firstDataViewController = FirstDataViewController()
        self.secondDataViewController = SecondDataViewController()
        ...
    }
    
    func viewDidLoad() {
        super.viewDidLoad()
    
        getBasicData { [weak self] (items) in 
            guard let strongSelf = self else { return }
    
    
            strongSelf.updateItems(items)
            strongSelf.firstDataViewController.updateItems(with: items)
            strongSelf.secondDataViewController.updateItems(with: items)
        }
    }
    
    func updateItems(items: RequestItems) {
        self.items = items
    }
    
  • The problem is that `updateItems` is executed after init of `child ViewControllers`. I cannot pass the data and then use it in `viewDidLoad` in one of the `child ViewController`. – Billy Apr 11 '17 at 00:18
  • What's the logic behind "init" of those view controllers? Why you want to put this logic into "init" so badly? – Dawid Koncewicz Apr 11 '17 at 12:13
  • I do not want it but it seems like getData is updating childViewController too late and i cannot use data in there. I am probably updating it in a wrong way. This is my MainViewController which is first view controller in my app. 1.) https://pastebin.com/mvwmvQkT 2.) Extension: https://pastebin.com/chv4enQ8 And this is one of child ViewController. 2.) https://pastebin.com/CEdyL7kL – Billy Apr 11 '17 at 14:26