Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for closure result for doing the return

I got a book reader coded in Swift, the first chapter is OK, but when I try to load the second from the webservice (the books come from a server chapter by chapter), the data source method of the pageviewcontroller has to return a viewcontroller, and it doesn't wait to the closure which gets the new chapter, it always return nil. I've tried using dispatch_semaphore_t, dispatch_group_t, etc, and I don't get it. The method is the following:

// MARK: - PageViewControllerDataSource

func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    if self.currentPageInSpineIndex! + 1 < self.currentChapterPages {
        self.currentPageInSpineIndex!++
    } else if self.selectedChapter + 1 < self.tale?.chapters.count {
        self.selectedChapter++
        self.currentPageInSpineIndex = 0
    }

    self.pageContentViewControllerAtIndex(self.currentPageInSpineIndex!, onCompletePage: { (let pageContentViewController: PageContentViewController) -> Void in
        return pageContentViewController
    })

    return nil
}

The pageContentViewControllerAtIndex method checks into de DB if it has the text of the chapter, and if not, it asks the server for it, then create a pagecontentviewcontroller with the text in it, and then returns it on the onCompletePage block, the thing is, that it always reachs the return nil line before the closure ends, so it doesn't work. I want to wait for the closure, have the pagecontentviewcontroller, and then return that result. Some ideas?

like image 783
diegomen Avatar asked Dec 13 '25 17:12

diegomen


1 Answers

The pageViewController:viewControllerAfterViewController: method expects a UIViewController (or subclass) to be returned, you won't be able to use asynchronous code within this method to create and return a view controller.

Suggestions based on waiting for the asynchronous method to complete are not appropriate. This is because the UIPageViewController delegate methods are invoked on the main thread and introducing any waiting mechanism will block the UI resulting in an unresponsive feel and potentially causing the system to terminate the app.

What I would recommend doing is creating a view controller, return it, and load the content from that view controller. Most likely you will want to display some kind of loading indicator on that view until the content has been retrieved.

like image 70
Steve Wilford Avatar answered Dec 16 '25 05:12

Steve Wilford



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!