0

I'm using promisekit 3.0 to help chain alamofire callbacks in a clean way. The objective is to start with a network call, with a promise to return an array of urls.

Then, I'm looking to execute network calls on as many of those urls as needed to find the next link i'm looking for. As soon as this link is found, I can pass it to the next step.

This part is where I'm stuck.

I can pick an arbitrary index in the array that I know has what I want, but I can't figure out the looping to keep it going until the right information is returned.

I tried learning from this obj-c example, but i couldn't get it working in swift.

https://stackoverflow.com/a/30693077/1079379

He's a more tangible example of what i've done.

Network.sharedInstance.makeFirstPromise(.GET, url: NSURL(string: fullSourceLink)! )
.then {  (idArray) -> Promise<AnyObject> in
    let ids = idArray as! [String]

    //how do i do that in swift? (from the example SO answer)
    //PMKPromise *p = [PMKPromise promiseWithValue: nil]; // create empty promise

    //only thing i could do was feed it the first value
    var p:Promise<AnyObject> = Network.sharedInstance.makePromiseRequestHostLink(.POST, id: ids[0])

    //var to hold my eventual promise value, doesn't really work unless i set it to something first
    var goodValue:Promise<AnyObject>

    for item in ids {
        //use continue to offset the promise from before the loop started
        continue

        //hard part
        p = p.then{ returnValue -> Promise<AnyObject> in

            //need a way to check if what i get is what i wanted then we can break the loop and move on
            if returnValue = "whatIwant" {
                goodvalue = returnValue
                break
            //or else we try again with the next on the list
            }else {
                return Network.sharedInstance.makeLoopingPromise(.POST, id: item)
            }
        }
    }
    return goodValue
}.then { (finalLink) -> Void in
    //do stuck with finalLink
}

Can someone show me how to structure this properly, please?

Is nesting promises like that anti-pattern to avoid? In that case, what is the best approach.

Community
  • 1
  • 1
stanley
  • 1,113
  • 1
  • 12
  • 26

2 Answers2

2

I have finally figured this out with a combination of your post and the link you posted. It works, but I'll be glad if anyone has input on a proper solution.

func download(arrayOfObjects: [Object]) -> Promise<AnyObject> {

        // This stopped the compiler from complaining
        var promise : Promise<AnyObject> = Promise<AnyObject>("emptyPromise")

        for object in arrayOfObjects {
            promise = promise.then { _ in
                return Promise { fulfill, reject in
                    Service.getData(stuff: object.stuff completion: { success, data in
                        if success {
                            print("Got the data")
                        }

                        fulfill(successful)
                    })
                }
            }
        }

        return promise
    }

The only thing I'm not doing is showing in this example is retaining the received data, but I'm assuming you can do that with the results array you have now.

Feril
  • 21
  • 4
  • I figured out my thing a while ago by using a when (see my answer). Doesn't require an empty promise and i don't need to personally iterate and create promise objects. instead,i iterate over the resulting array. – stanley Dec 08 '15 at 01:10
0

The key to figuring out my particular issue was using the "when" function. It keeps going until all the calls you inputted are finished. The map makes it easier to look at (and think about in my head)

 }.then {  (idArray) -> Void in

        when(idArray.map({Network.sharedInstance.makePromiseRequest(.POST, params: ["thing":$0])})).then{ link -> Promise<String> in
            return Promise { fulfill, reject in
                let stringLink:[String] = link as! [String]
                for entry in stringLink {
                    if entry != "" {
                        fulfill(entry)
                        break
                    }
                }
            }
        }.then { 
        }
 }
stanley
  • 1,113
  • 1
  • 12
  • 26