我正在尝试使用Alamofire库快速加载来自GET请求的数据,并且无法追加请求中的数据。我正在尝试填充要加载到UITableView中的订单数组。
我尝试了几种解决此问题的方法,但没有任何工作对我有用。我已注释掉我尝试过的方法,因为对fetchAll...Orders
进行了2次单独的调用,而第二次调用始终会覆盖第一个调用,然后tableView会加载缺少的项。
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()
// }
fetchAllBeerOrders { orders in
self.orders.append(orders)
self.tableView.reloadData()
}
fetchAllCocktailOrders { orders in
self.orders.append(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)
}
}
截至目前,我在上面的代码Cannot convert value of type '[Order]?' to expected argument type 'Order'
中遇到此错误。该代码的理想结果是使从每个GET请求中收集的数据附加到Orders数组中。我已验证GET请求正在正常工作并返回正确的数据。请帮助:]
答案 0 :(得分:1)
您声明了orders
类型的[Order]
,并且您的提取方法编译块返回了[Order]?
。如您所见,您在编写[Order]?
时无法将类型Order
的值转换为期望的参数类型self.orders.append(orders)
。
要解决这些问题,请在获取方法调用中放置一个保护措施。
fetchAllBeerOrders { orders in
guard let _orders = orders else { return }
self.orders.append(_orders)
self.tableView.reloadData()
}
fetchAllCocktailOrders { orders in
guard let _orders = orders else { return }
self.orders.append(_orders)
self.tableView.reloadData()
}
现在,您的代码中可能存在内存泄漏。 fetchAllBeerOrders
和fetchAllCocktailOrders
是带有编译块的异步方法。您不能在此处使用对self
的强引用。使用weak
避免内存泄漏,例如:
fetchAllBeerOrders { [weak self] orders in
guard let _orders = orders else { return }
self?.orders.append(_orders)
self?.tableView.reloadData()
}
fetchAllCocktailOrders { [weak self] orders in
guard let _orders = orders else { return }
self?.orders.append(_orders)
self?.tableView.reloadData()
}