Monday, July 4, 2022
HomeiOS Developmentios - Is that this a finest apply technique to make concurrent...

ios – Is that this a finest apply technique to make concurrent API calls?


I am studying about concurrent API calls, and I am at the moment making use of them to a challenge.

Primarily based on my code beneath, is that this a finest apply technique to make concurrent calls? (Notice: I am purposely not utilizing Alamofire)

I am making my concurrent API calls in fetchMealPlan() to create a mealPlan with a number of meals which have pre-loaded photos. I am utilizing two forms of API calls in fetchMealPlanBasedOn() and loadImageURL().

class MealPlanManager {
    
    static func fetchMealPlan(mealReqs: [MealReq], completion: @escaping (([MealInfo]) -> Void)) {
        
        let dispatchGroup = DispatchGroup()
        var mealPlan = [MealInfo]()
        
        DispatchQueue.world().async {
            
            mealReqs.forEach { req in
                dispatchGroup.enter()
                self.fetchMealBasedOn(req) { end in
                    var mealInfo = outcome
                    self.loadImageURL(for: mealInfo) { picture in
                        mealInfo.picture = picture
                        mealPlan.append(mealInfo)
                        dispatchGroup.go away()
                    }
                }
            }
            
            dispatchGroup.notify(queue: .primary) {
                completion(mealPlan)
            }
        }
    }
    
    static func fetchMealBasedOn(_ req: MealReq, completion: @escaping ((MealInfo) -> Void)) {
        print("fetching meal")
        
        // Validate appId and appKey
        guard let appId = Bundle.primary.infoDictionary?["edamam_app_id"] as? String,
              let appKey = Bundle.primary.infoDictionary?["edamam_app_key"] as? String else { return }
        
        // Create urlPrefix with queryItems
        var urlPrefix = URLComponents(string: "https://api.edamam.com/api/recipes/v2")!
        
        let queryItems = [
            URLQueryItem(name: "type", value: "public"),
            URLQueryItem(name: "q", value: req.type),
            URLQueryItem(name: "app_id", value: appId),
            URLQueryItem(name: "app_key", value: appKey),
            URLQueryItem(name: "mealType", value: req.type),
            URLQueryItem(name: "calories", value: req.macros.calories),
            URLQueryItem(name: "imageSize", value: "REGULAR"),
            URLQueryItem(name: "random", value: "(req.random)"),
            URLQueryItem(name: "nutrients[CHOCDF]", worth: req.macros.carbs),
            URLQueryItem(title: "vitamins[FAT]", worth: req.macros.fats),
            URLQueryItem(title: "vitamins[PROCNT]", worth: req.macros.protein),
            URLQueryItem(title: "subject", worth: "label"),
            URLQueryItem(title: "subject", worth: "picture"),
            URLQueryItem(title: "subject", worth: "photos"),
            URLQueryItem(title: "subject", worth: "url"),
            URLQueryItem(title: "subject", worth: "shareAs"),
            URLQueryItem(title: "subject", worth: "yield"),
            URLQueryItem(title: "subject", worth: "dietLabels"),
            URLQueryItem(title: "subject", worth: "healthLabels"),
            URLQueryItem(title: "subject", worth: "ingredientLines"),
            URLQueryItem(title: "subject", worth: "components"),
            URLQueryItem(title: "subject", worth: "energy"),
            URLQueryItem(title: "subject", worth: req.sort),
            URLQueryItem(title: "subject", worth: "totalNutrients")
        ]
        urlPrefix.queryItems = queryItems
        urlPrefix.percentEncodedQuery = urlPrefix.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
        
        // Create urlRequest
        var urlRequest = URLRequest(url: urlPrefix.url!)
        urlRequest.httpMethod = "GET"
        
        // Create URLSession dataTask with urlRequest
        let process = URLSession.shared.dataTask(with: urlRequest) { information, response, error in
            guard let information = information, error == nil else {
                print("(String(describing: error?.localizedDescription))")
                return
            }
            
            guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
                return
            }
            
            do {
                let outcome = strive JSONDecoder().decode(MealData.self, from: information)
                self.convertToMealInfo(outcome: outcome, req: req) { mealInfo in
                    completion(mealInfo)
                }
            } catch {
                print("Cannot decode JSON information (error.localizedDescription)")
            }
        }
        
        process.resume()
    }
    
    static func loadImageURL(for meal: MealInfo, completion: @escaping ((UIImage) -> Void)) {
        print("fetching picture")
        guard let imageURL = meal.imageURL, let url = URL(string: imageURL) else { return }
        
        let process = URLSession.shared.dataTask(with: url) { information, response, error in
            guard let information = information, error == nil else {
                print("Please test connection (String(describing: error?.localizedDescription))")
                return
            }
            
            guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
                return
            }
            
            let outcome: UIImage
            outcome = UIImage(information: information) ?? Picture.defaultMealImage!
            
            completion(outcome)
        }
        
        process.resume()
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments