0

I am currently trying to nest Alamofire requests to use data that I have already successfully received using GET requests.

For this piece of code I have used Rob's answer in this question

How to return value from Alamofire

However, I can not either nest the Alamofire requests or use them by separate.

This is what I am trying to do

override func viewDidLoad() {
    super.viewDidLoad()


    var currentFoodType: String = ""
    var currentFoodList: String = ""

    //debug

    //this is how I get back the token from NSUserDefault
    if let myToken = userDefaults.valueForKey("token"){


        // calling method to get the user info
        getUserInfo(myToken as! String)

        // calling method to get the product type
        func getFoodCategory(completionHandler: (NSDictionary?, NSError?) -> ()) {
            getProductTypes(myToken as! String, completionHandler: completionHandler)
        }
        getFoodCategory() { responseObject, error in
            // use responseObject and error here

            let foodTypesJSON = JSON(responseObject!)
            //to get one single food category
            currentFoodType = (foodTypesJSON["types"][0].stringValue)
            print(currentFoodType)


            /////////////////////////////////////////
            func getFoodsByCategory(completionHandler: (NSDictionary?, NSError?) -> ()) {
                print("getting " + currentFoodType)
                self.getProductsByType(myToken as! String, productType: currentFoodType, completionHandler: completionHandler)
            }

            getFoodsByCategory() { responseObject, error in
                // use responseObject and error here
                print("responseObject = \(responseObject); error = \(error)")

                return
            }

           return
        }

    }

Then the two other functions I am calling from there are very straight forward Alamofire requests with callbacks to the completionHandlers above

    //GET THE PRODUCT TYPES FROM THE SERVER
func getProductTypes(myToken: String, completionHandler: (NSDictionary?, NSError?) -> ())  {

    let requestToken = "Bearer " + myToken
    let headers = ["Authorization": requestToken]
    let getProductTypesEndpoint: String = BASE_URL + PRODUCT_TYPES


    Alamofire.request(.GET, getProductTypesEndpoint, headers: headers)
        .responseJSON{ response in
            switch response.result {
            case .Success(let value):
                completionHandler(value as? NSDictionary, nil)
            case .Failure(let error):
                completionHandler(nil, error)
            }
    }//END ALAMOFIRE GET responseJSON


}

The above function returns a single food like "Desserts" which will be used in the following function to GET all the desserts from the server

//GET THE PRODUCTS FROM THE SERVER GIVEN A CATEGORY
func getProductsByType(myToken: String, productType: String, completionHandler: (NSDictionary?, NSError?) -> ()){

    let requestToken = "Bearer " + myToken
    let headers = ["Authorization": requestToken]
    let getProductTypesEndpoint: String = BASE_URL + PRODUCT_BY_TYPE + productType

    Alamofire.request(.GET, getProductTypesEndpoint, headers: headers)
        .responseJSON { response in
            switch response.result {
            case .Success(let value):
                print("no errors")
                let auth = JSON(value)
                print("The pbt GET description is: " + auth.description)
                completionHandler(value as? NSDictionary, nil)
            case .Failure(let error):
                print("there was an error")

                completionHandler(nil, error)
            }
    }//END ALAMOFIRE GET responseJSON
}

and this works well because when I print within the getProductsByType function

using

print("The pbt GET description is: " + auth.description)

I get the JSON with all the products but the problem is in the viewDidload function where I am nesting the callbacks

getFoodsByCategory() { responseObject, error in
                // use responseObject and error here
                print("responseObject = \(responseObject); error = \(error)")                   
                return
            }

the print within that bit is showing me that something is wrong so I can not parse my response as I desire.

Because I get the following

responseObject = nil; error = nil

So my guess is that there must a be a different method to nest these callbacks?

Community
  • 1
  • 1
Jesus Rodriguez
  • 2,571
  • 2
  • 22
  • 38

1 Answers1

0

Take a look at chained promises from PromiseKit. This also works well with Alamofire:

func loadFoo() -> Promise<Bar> {
    return Promise<Bar> { fulfill, reject in 
        Alamofire.request(.GET, "url")
        .responseJSON { response in
            switch response.result {
                case .Success(let value):
                     let bar = Bar(fromJSON: value)
                     fulfill(bar)
                case .Failure(let error):
                     reject(error)
            }
        }
    }
}


// Usage    
getBar()
.then { bar -> Void in
    // do something with bar
}
.error { error in
    // show error
}

This is very simple example, but you can find more relevant examples in documentation.

Andrey Gershengoren
  • 896
  • 1
  • 5
  • 18