Search code examples
iosjsonswiftapialamofire

Filtering an API Request Response by an object array?


I am making an API call for muscles relating to an exercise, the call looks like this:

    func loadPrimaryMuscleGroups(primaryMuscleIDs: [Int]) {
    print(primaryMuscleIDs)
    let url = "https://wger.de/api/v2/muscle"
    Alamofire.request(url).responseJSON { response in
        let jsonData = JSON(response.result.value!)
        if let resData = jsonData["results"].arrayObject {
            let resData1 = resData as! [[String:AnyObject]]
            if resData1.count == 0 {
                print("no primary muscle groups")
                self.musclesLabel.isHidden = true
            } else {
                print("primary muscles used for this exercise are")
                print(resData)
                self.getMuscleData(muscleUrl: resData1[0]["name"] as! String)
            }
        }
    }
}

This returns me a whole list of all the muscles available, I need it to just return the muscles the exercise requires. This is presented in exercises as an array of muscle id's, which I feed in via the viewDidLoad below

self.loadPrimaryMuscleGroups(primaryMuscleIDs: (exercise?.muscles)!)

So I am feeding the exercises muscle array into the func as an [Int] but at this point im stumped on how to filter the request so that the resulting muscle data are only the ones needed for the exercise.

I was thinking it would be something like using primaryMuscleIDs to filter the id property of a muscle in the jsonData response, but im not sure how to go about that?

Thanks for any clarify here, hopefully I have explained it clearly enough to come across well


Solution

  • You'd want to do something like this in your else block:

    var filteredArray = resData1.filter { item in
        //I'm not exactly sure of the structure of your json object,
        //but you'll need to get the id of the item as an Int
        if let itemId = item["id"] as? Int  {  
            return primaryMuscleIDs.contains(itemId)
        }
        return false
    }
    
    //Here with the filtered array
    

    And since the Alamofire request is asynchronous, you won't be able to return a result synchronously. Your method will need to take a callback that gets executed in the Alamofire response callback with the filtered response.

    Something like (but hopefully with something more descriptive than an array of Any:

    func loadPrimaryMuscleGroups(primaryMuscleIDs: [Int], callback: ([Any]) -> ()) {
        //...
        Alamofire.request(url).responseJSON { response in
            //...
            //once you get the filtered response:
            callback(filteredArray)
        }
    }
    

    Finally, check out How to parse JSON response from Alamofire API in Swift? for the proper way to handle a JSON response from Alamofire.