How to manually trigger Promise in Swift 3 with PromiseKit

642 views Asked by At

I'm looking to develop a sync service which is trigger when a user pulls to refresh. This sync service will perform multiple requests to the server. How can I manually trigger a PromiseKit promise after every API call has been completed? The promise's callbacks are being called immediately.

//MyViewController.swift
func refresh(sender: AnyObject){
    var promise = syncService.syncFromServer()
    promise.then{ response
        //This is called immediately, and I need it to wait until the sync is complete
        refreshControl?.endRefreshing()
        tableView.reloadData()
    }
}

//SyncService.swift
func syncFromServer() -> Promise<AsyncResult>{
    let promise = Promise(value: AsyncResult)
     var page = 1

    //Multiple API calls
    //let request1 = ...
    //let request2 = ...
    //let request3 = ...
    //How do I tell the returned promise to trigger the associated callbacks after the last API requests has been completed?

    //Another scenario I need to handle is when the amount of requests is not known ahead of time.
    while(true){
        var response = makeAnApiCall(page)

        //if the response body says no more data is available, break out of the while loop, and tell any promise callbacks to execute.
        //if(noMoreData){
        // how do I perform something like
        // promise.complete //This line needs to tell the `then` statement in `MyViewController` to execute.
        // break
        //}else{
        //  do something with response data
        //}
        page = page + 1
    }

    return promise
}
1

There are 1 answers

2
totiDev On BEST ANSWER

Below I have provided an example of what you should do to end refreshing and update your tableView after all the syncService calls have run. Look at the PromiseKit docs about using 'when'.

func refresh(sender: AnyObject){
    syncService.syncFromServer().then { response in
        refreshControl?.endRefreshing()
        tableView.reloadData()
    }
}

//SyncService.swift
func syncFromServer() -> Promise<Void> {
    let request1 = methodReturningPromise1()
    let request2 = methodReturningPromise2()
    return when(fulfilled: [request1, request2])
}

private func methodReturningPromise1() -> Promise<Void> {
    return syncService.someDataCall().then { response -> Void in
        //do something here
    }
}