我正在尝试使用swift中的Alamofire库从GET请求加载数据,并且无法从请求中附加数据。我正在尝试填充一系列订单以加载到UITableView中。
我尝试了几种解决这个问题的方法,但没有什么对我有用。我已经注释了我尝试的方法,因为有两个单独的调用fetchAll...Orders
,第二个调用总是覆盖第一个,然后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请求正在工作并返回正确的数据。请帮忙 :]
你声明了orders
类型的[Order]
,你的fetch方法编译块返回[Order]?
。如您所见,当您编写[Order]?
时,您无法将Order
类型的值转换为预期的参数类型self.orders.append(orders)
。
要解决这些问题,请在fetch方法调用中打开一个防护。
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()
}