首页 > 解决方案 > 为什么我的循环网络请求无法在我的 SwiftUI 代码中下载相同数量的项目?

问题描述

我有一个 SwiftUI 应用程序,它在 for-in 循环中对公共 API 进行网络调用,以按首字母下载鸡尾酒饮料。我已经设置了下载所有带有首字母“a”、“b”、“c”和“d”的鸡尾酒的代码。我打印出我下载的鸡尾酒总数,但每次调用代码时都不同。有时我会下载 18、93、68 或其他数量的鸡尾酒。

这是我的代码;

        case "Ingredients":
            let networkManager = NetworkManager<Drinks>()
            let letters = "abcd".map { String($0) }
            let baseUrl = "https://www.thecocktaildb.com/api/json/v1/1/search.php?f="
            
            // Extract ingredient from the URL
//            var ingredient = urlString.drop { character in
//                return character != "="
//            }
//            ingredient.removeFirst()
//            print(ingredient)
            // Search cocktails for those with the named ingredient
//            if !ingredient.isEmpty {
                
                // Use for-in loop to fetch all the cocktails by first letter
                self.drinks = Drinks(drinks: [Cocktail]())
                for letter in letters {
                    let url = baseUrl + letter
                    networkManager.fetchData(String(url)) { results, error in
                        DispatchQueue.main.async {
                            guard let resultsSafe = results else { return }
                            self.drinks.drinks.append(contentsOf: resultsSafe.drinks)
                            if letter == "d" {
                                print("DEBUG: Number of cocktails = \(self.drinks.drinks.count)")
                            }
                        }
                    }
                    
                }
//            }
            // Return filtered cocktails
class NetworkManager<DataStruct: Decodable> {
        
    func fetchData(_ urlString: String, completion: @escaping (DataStruct?, Bool) -> Void) {
        guard let url = URL(string: urlString) else { return }
        var drinkData: DataStruct?
        let session = URLSession(configuration: .default)
        let task = session.dataTask(with: url) { data, response, error in
            if error == nil {
                let decoder = JSONDecoder()
                guard let safeData = data else { return }
                do {
                    drinkData = try decoder.decode(DataStruct.self, from: safeData)
                        completion(drinkData!, false)
                } catch let error {
                    if error.localizedDescription == "The data couldn’t be read because it is missing." {
                        
                        completion(drinkData, true)
                    } else {
                        print(error.localizedDescription)
                    }
                }
            }
        }
        task.resume()
    }
}

标签: swiftapi

解决方案


推荐阅读