Sonius
Sonius

Reputation: 1657

How to wait for a function to be finished that is already running

I have a class that will do some network requests. On init() I load some initial data. So the class looks like this:

class NetworkHandler {
    init() {
        loadData()
    }

    func loadData() {
        // Do an asynchronous function to load initial data
    }
}

I pass an object of this class to a ViewController. In this ViewController I want to show a loading indicator until the initial load is finished. Next I want to show a normal screen. So like this:

class viewController: UIViewController {
    var networkHandler: NetworkHandler?

    override func viewDidLoad() {
        super.viewDidLoad()
        if networkHandler.initialLoadIsDone {
            // Show something
        } else {
            // Show a loading indicator
            // Listen on networkHandlers initial load
            // On initial load done: Show somethin
        }
    }
}

So the first step if the initial load is finished or not I could handle with a local variable in networkHandler. But as I do not call the initial load function I cannot use a completionHandler to wait for the initial load to be finished. So I am wondering what's the best way to wait for the initial load to be finished? Also, can I replace the local variable solution by this?

Thanks for any help

Upvotes: 0

Views: 400

Answers (1)

vadian
vadian

Reputation: 285079

Don't wait. Do notify.

For example use protocol / delegate to inform the target class about the stages

protocol NetworkHandlerProtocol {
    func didStartLoading()
    func didFinishInitialLoading(with data: Data)
}

class NetworkHandler {

    var delegate : NetworkHandlerProtocol

    init(delegate : NetworkHandlerProtocol) {
        self.delegate = delegate
    }

    func loadData() {
        delegate.didStartLoading()
        // Do an asynchronous function to load initial data
        let data = // some Data object
        delegate.didFinishInitialLoading(with: data)
    }
}

In the controller adopt the protocol and implement the methods

class ViewController: UIViewController {

    lazy var networkHandler = NetworkHandler(delegate : self)

    override func viewDidLoad() {
        super.viewDidLoad()
        networkHandler.loadData()
    }
}

extension ViewController : NetworkHandlerProtocol {

    func didStartLoading() { }

    func didFinishInitialLoading(with data: Data) { }

}

Upvotes: 2

Related Questions