繁体   English   中英

Swift-使用Alamofire进行多个GET请求时出现问题

[英]Swift- Problem making multiple GET requests with Alamofire

我在快速从Alamofire的GET请求中加载数据以将项目加载到UITableView时遇到问题。

我有2种方法fetchAllBeerOrdersfetchAllCocktailOrders都可以正常工作并获取正确的项目。 我遇到的问题是在viewWillAppear方法中,我在这两个方法中调用了这两个提取方法并重新加载tableView。 在订单中,只有fetchAllCocktailOrders方法中的项目正在加载到tableView中,并且我已通过切换订单并从fetchAllBeerOrders获取项目来进行验证。


class DrinkOrdersTableViewController: UITableViewController { 
    var orders: [Order] = [] 
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.title = "Current Orders"

    }

    override func viewWillAppear(_ animated: Bool) {

        fetchAllBeerOrders { orders in
            self.orders = orders!
            //print("Beer fetch: ", self.orders)
            self.tableView.reloadData()
        }

        fetchAllCocktailOrders { orders in
            self.orders = orders!
            //print("Cocktail fetch: ", self.orders)
            self.tableView.reloadData()
        }

    }

    private func fetchAllCocktailOrders(completion: @escaping([Order]?) -> Void) {
        Alamofire.request("http://127.0.0.1:4000/orders", method: .get)
            .validate()
            .responseJSON { response in
                guard response.result.isSuccess else { return completion(nil) }
                guard let rawInventory = response.result.value as? [[String: Any]?] else { return completion(nil) }
                let currentOrders = rawInventory.compactMap { ordersDict -> Order? in
                    guard let orderId = ordersDict!["id"] as? String,
                        let orderStatus = ordersDict!["status"] as? String,
                        var pizza = ordersDict!["cocktail"] as? [String: Any] else { return nil }
                    pizza["image"] = UIImage(named: pizza["image"] as! String)

                    return Order(
                        id: orderId,
                        pizza: Pizza(data: pizza),
                        status: OrderStatus(rawValue: orderStatus)!
                    )

                }
                completion(currentOrders)
        }

    }

    private func fetchAllBeerOrders(completion: @escaping([Order]?) -> Void) {
        Alamofire.request("http://127.0.0.1:4000/orders", method: .get)
            .validate()
            .responseJSON { response in
                guard response.result.isSuccess else { return completion(nil) }
                guard let rawInventory = response.result.value as? [[String: Any]?] else { return completion(nil) }
                let currentOrders = rawInventory.compactMap { ordersDict -> Order? in
                    guard let orderId = ordersDict!["id"] as? String,
                        let orderStatus = ordersDict!["status"] as? String,
                        var pizza = ordersDict!["pizza"] as? [String: Any] else { return nil }
                    pizza["image"] = UIImage(named: pizza["image"] as! String)

                    return Order(
                        id: orderId,
                        pizza: Pizza(data: pizza),
                        status: OrderStatus(rawValue: orderStatus)!
                    )

                }
                completion(currentOrders)
        }
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Debugging ROWS", orders.count)
        return orders.count
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "order", for: indexPath)
        let order = orders[indexPath.row]        
        cell.textLabel?.text = order.pizza.name
        cell.imageView?.image = order.pizza.image
        cell.detailTextLabel?.text = "$\(order.pizza.amount) - \(order.status.rawValue)"

        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "orderSegue", sender: orders[indexPath.row] as Order)
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "orderSegue" {
            guard let vc = segue.destination as? OrderViewController else { return }
            vc.order = sender as? Order
        }
    }
}

我不确定是否需要将GET请求合并到单个请求中,或者我的方法逻辑是否错误,但是我需要tableView从fetchAllBeerOrdersfetchAllCocktailOrders加载订单。 请帮忙

就像Levi Yonder所说的那样,第二个请求替换order的结果确实是一个问题,但是他提供的答案并不是最佳的。

您必须记住,网络请求是异步的。 这意味着fetchAllCocktailOrders可以 fetchAllBeerOrders请求完成之前完成。 在这种情况下,将发生相同的问题:

  1. 同时要求开火
  2. fetchAllCocktailOrders首先完成,将数据追加到订单
  3. fetchAllBeerOrders完成,用此请求的结果替换当前的数据批。

解:

fetchAllBeerOrders { orders in
    self.orders.append(orders)
    self.tableView.reloadData()
}

fetchAllCocktailOrders { orders in
    self.orders.append(orders)
    self.tableView.reloadData()
}

您遇到此问题的原因是, fetchAllCocktailOrders替换了fetchAllBeerOrders最初获取的orders中的所有内容,而不是追加到fetchAllBeerOrders orders中。

因此, viewWillAppear会调用fetchAllBeerOrders (填充orders ,然后fetchAllCocktailOrders将替换orders所有内容,而不是追加到orders所有内容。

要解决此问题,请在调用fetchAllCocktailOrders ,在orders附加函数返回的内容,而不是替换:

override func viewWillAppear(_ animated: Bool) {

        fetchAllBeerOrders { beerOrders in
            self.orders = beerOrders!
            //print("Beer fetch: ", self.orders)
            self.tableView.reloadData()
        }

        fetchAllCocktailOrders { coctailOrders in
          self.orders.append(coctailOrders)
            //print("Cocktail fetch: ", self.orders)
            self.tableView.reloadData()
        }

    }

更新:

为了实现从两个GET请求中加载数据的目标,我需要使用.append(contentsOf: orders!)方法而不是self.orders = orders!将数据追加到orders数组self.orders = orders! 在viewWillAppear方法中,第二次调用fetchCocktailOrders将始终覆盖第一次调用fetchBeerOrders的内容。 显然我是个敏捷的新秀!

        fetchAllBeerOrders { orders in
            //self.orders.append(orders)
            self.orders.append(contentsOf: orders!)
            self.tableView.reloadData()
        }

        fetchAllCocktailOrders { orders in
            //self.orders.append(orders)
            self.orders.append(contentsOf: orders!)
            self.tableView.reloadData()
        }

这是正确的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM