1

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
    What do you mean trigger a promise manually? If you declare a function returning a `Promise` correctly, it will act pretty much like a normal synchronous function when using it when `then`, so if the "callbacks" are being called immediately, your function is flawed. Please include the function definition in your question. – Dávid Pásztor Sep 12 '17 at 12:34
  • @DávidPásztor, I added clarification to the `syncFromServer` method. There's a scenario where I will not know the amount of requests ahead of time. So I need to return a promise which will execute after a response says there are zero results. So after I determine there are zero results, I need to tell the promise callbacks to execute, and break out of the while loop. –  Sep 12 '17 at 13:54

1 Answers1

1

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
    }
}
totiDev
  • 5,189
  • 3
  • 30
  • 30
  • Can I also return a promise when the amount of requests are not known ahead of time? Lets say I have a `while(true)` loop which could short-circuit when an expected response is returned. So after a certain condition is met, I break out of the `while` loop and tell the promise listeners to execute. –  Sep 12 '17 at 13:36
  • Yes you could return Promise(value: ()) if true, else return a method that returns a promise, such as methodReturningPromise1() – totiDev Sep 12 '17 at 14:20