Search code examples
iosswiftpromisekit

Odd promiseKit 6 syntax behavior in Xcode


I am getting started with PromiseKit to prevent myself from writing functions with 10 levels of callbacks..

I installed the latest version (6.2.4) using CocoaPods, am running the latest version of xCode, imported PromiseKit in the file I am trying to get it working in, but I get really weird behavior of Xcode, resulting in several errors.

I intend to do something really basic to get started:

the function below creates filters (ProductListComponents) for categories for products in a product overview app I'm working on.

func createCategoryComponents(masterComponent: MasterComponent?) -> Promise<[ProductListComponents]> {
    return Promise { seal in
        //create a bunch of product category components
        seal.resolve([components])
    }
}

All fine here. I then try to get this:

firstly {
    self.createCategoryComponents(masterComponent: masterComponent)
}.then { createdComponents in
    completion.resolve(nil, createdComponents)
}

This refuses to work. firstly, when I try to type the firstly code, Xcode suggests:

firstly(execute: { () -> Guarantee<T> in
    //code
})

and:

firstly(execute: { () -> Thenable in
    //code
})

I have not seen this syntax in ANY of the PromiseKit documentation. It also suggests odd syntax for e.g. the .then calls. When accepting Xcode's suggestions, it obviously displays error as this is not the correct PromiseKit syntax. When ignoring Xcode's suggestion, I get this:

enter image description here

Obviously something is wrong here, my best guess is that something went wrong with the installation of PromiseKit. I have cleaned my project, re-installed the pod, restarted Xcode but it seems that nothing is working.

Question

Does anybody know what kind of issue I'm experiencing here and, even more importantly, how I might get it resolved?

Any helpt would be much appreciated.


Solution

  • According to the release notes:

    • then is fed the previous promise value and requires you return a promise.
    • done is fed the previous promise value and returns a Void promise (which is 80% of chain usage)
    • map is fed the previous promise value and requires you return a non-promise, ie. a value.

    So, then shouldn't work here, because you need to return the promise value. If you just change then to the done it will work.

    Also some suggestions.

    • firstly is really about visual decoration (i believe it was somewhere at PMK docs, but i can't find that right now), so, if this confuses you, try to remove that for the start;
    • The main feature of PMK is the chain. You definitely should write your code according to this principle;
    • Also, don't forget about errors. Use catch at the end of the chain for that.

    Final example of your code:

    firstly {
        self.createCategoryComponents(masterComponent: masterComponent)
    }
    .done { createdComponents in
        completion.resolve(nil, createdComponents)
    }
    .catch { error in
        // don't forget about errors
    }