Search code examples
swiftpromisekit

PromiseKit wrapping external closure in Promises


I am using an external library in Swift so I cannot control the return statements. My understanding is that I should wrap these returns in promises in order to use PromiseKit. Is this correct?

Assuming so, I have working code as follows:

private func getChannelImage(for channel: TCHChannel, completion: @escaping (UIImage?, CAProfileError?) -> Void) {
    if let members = channel.members {
        members.members(completion: { (result, paginator) in
            if result.isSuccessful() {
                // ... do something
            }
            else {
                    completion(nil, CAProfileError.UnknownError)
            }
        })
    }
}

This can be difficult to read. I am trying to simplify this using PromiseKit. First, I want to simplify members.members(completion: { (result, paginator) in to a promise that I can call with the firstly { ... } syntax. I thus try and do as follows:

private func asPromise(members: TCHMembers) -> Promise<TCHMemberPaginator> {
    return Promise<TCHMemberPaginator> { fulfill, reject in
        members.members(completion: { (result, paginator) in
            if result.isSuccesful() {
                fulfill(paginator)
            } else {
                reject()
            }
        })
    }
}

But this approach does not work and I get "Unable to infer closure type in the current context". I'm trying to find a good example of this use case done online but am having trouble. Any thoughts on how to properly return promises?


Solution

  • Assuming the TCHMemberPaginator and TCHMembers as below,

    class TCHMemberPaginator {}
    class TCHMembers {
        func members(completion: (Bool, TCHMemberPaginator?) -> Void) {}
    }
    

    Here is the method to return a Promise,

    private func asPromise(members: TCHMembers) -> Promise<TCHMemberPaginator> {
        return Promise { seal in
            members.members(completion: { (result, paginator) in
                if result == true, let p = paginator {
                    seal.fulfill(p)
                } else {
                    seal.reject(NSError())
                }
            })
        }
    }