Search code examples
iosswiftpromisekit

PromiseKit go back one step


I have a series of UIViewControllers (popups) in my app that I use to gather information from the end user. I managed to chain them with promises like this:

firstly {
        return showFirstPopup()
    }
    .then { info1 -> Promise<Info2> in
        dismissFirstPopup()
        //Do sth with info1...
        return showSecondPopup()
    }
    .then { info2 -> Promise<Info3> in
        dismissSecondPopup()
        //Do sth with info2...
        return showThirdPopup()
    }
    .then { info3 -> Promise<Info4> in
        dismissThirdPopup()
        //Do sth with info3...
        return showForthPopup()
    }
    ...
    .catch { error in
        //Handle any error or cancellation...
     }

If, for example, the user presses back in the third popup I need to go back to the previous "then" and not cancel the whole flow.

Basically I need to be able to go back one step, let the user edit the data, then continue the flow.

Is there a way to do this with PromiseKit?


Solution

  • This is what I ended up using. Hope this helps someone else out there as well.

    func myFunc(info: Info) -> Promise<()>
    {
        return Promise { fulfill, reject in
    
            let firstPromise = shouldShowFirstPopup ? showFirstPopup() : Promise(value: info.info1)
    
            firstPromise
            .then { info1 -> Promise<Info2> in
                info.info1 = info1
    
                if (info.shouldShowSecondPopup) {
                    return showSecondPopup()
                }
    
                return Promise(value: info.info2)
            }
            .then { info2 -> Promise<Info3> in
                info.info2 = info2
                info.shouldShowSecondPopup = false
    
                if (info.shouldShowThirdPopup) {
                    return showThirdPopup()
                }
    
                return Promise(value: info.info3)
            }
            .then { info3 -> Promise<()> in
                info.info3 = info3
                info.shouldShowThirdPopup = false
    
                return processEverything()
            }
            .then { _ -> () in
                fulfill(())
            }
            .catch { error in
                switch error {
                    case MyErrors.backPressed(let popupType):
                        switch popupType {
                            case .firstPopup:
                            reject(MyErrors.userCanceled)
                            return
    
                            case .secondPopup:
                            info.shouldShowFirstPopup = true
                            info.shouldShowSecondPopup = true
    
                            case .thirdPopup:
                            info.shouldShowSecondPopup = true
                            info.shouldShowThirdPopup = true
    
                            default:
                            reject(MyErrors.defaultError(message: "Not implemented case exception"))
                            return
                        }
    
                        firstly {
                            return myFunc(info: info)
                        }
                        .then { _ -> () in
                            fulfill(())
                        }
                        .catch { error2 in
                            reject(error2)
                        }
    
                    default:
                    reject(error)
                }
            }
        }
    }