我正在尝试在加载应用程序(iOS)主视图时显示客户列表。数据是从JSON格式的API请求返回的,我确认我已进入调试器。我在从主视图获取响应时遇到问题,因为在视图加载方法完成后会调用fetch方法。如我所读,我应该在fetch方法中添加一个完成处理程序,并将其作为转义的附件传递,以便main方法等待fetch方法。我遵循此guide并阅读了几次,但仍然无法找到错误所在。我想念什么?
此
struct CustomerList: View {
@State var customerList = searchCustomer(criteria: "jose")
var body: some View {
List(self.customerList, id: \.id){ customer in
CellRow(customer: customer)
}
}
}
func searchCustomer(criteria: String) -> [Customer] {
//API call full url
let fullURL = FTP_API_URL + criteria
var customerList = [Customer]()
if criteria == ""{
return customerList
}
getJsonFromAPI(url: fullURL, fetchCompletionHandler: {customers, error in
if let jsonCustomers = customers{
customerList = jsonCustomers.customers
}
})
return customerList
}
func getJsonFromAPI(url: String, fetchCompletionHandler : @escaping (Customers?, Error?)-> Void){
let username = decryptData(data: FTP_API_USERNAME)
let password = decryptData(data: FTP_API_PASSWORD)
let loginData = String(format: "%@:%@", username, password).data(using: String.Encoding.utf8)!
let base64LoginData = loginData.base64EncodedString()
// create the request
let url = URL(string: url)!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Basic \(base64LoginData)", forHTTPHeaderField: "Authorization")
//making the request
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("\(error)")
return
}
//if let httpStatus = response as? HTTPURLResponse {
// check status code returned by the http server
//print("status code = \(httpStatus.statusCode)")
// process result
// }
let jsonDecoder = JSONDecoder()
do{
let results = try jsonDecoder.decode(Customers.self, from: data)
// for result in results.customers{
// print(result.cedulaOrPassport)
// }
fetchCompletionHandler(results, nil)
}
catch{
print(error)
fetchCompletionHandler(nil, error)
}
}
task.resume()
}
谢谢。
答案 0 :(得分:0)
return customerList
异步获取)尚不可用时,searchCustomer
中的 getJsonFromAPI
同步发生。因此,您正在分配[Customer]
并将其@State var customerList
空数组。
无论如何,您不能直接将异步获取的值分配给属性。
相反,将searchCustomer
更改为也接受完成处理程序,并使用.onAppear
调用它并从完成处理程序中分配值(就像使用getJsonFromAPI
一样):< / p>
func searchCustomer(criteria: String,
completionHandler: @escaping ([Customer]) -> Void) -> Void {
//API call full url
let fullURL = FTP_API_URL + criteria
var customerList = [Customer]()
if criteria == "" {
completionHandler(customerList)
}
getJsonFromAPI(url: fullURL, fetchCompletionHandler: {customers, error in
if let jsonCustomers = customers{
customerList = jsonCustomers.customers
completionHandler(customerList)
}
})
}
struct CustomerList: View {
@State var customerList = []
var body: some View {
List(self.customerList, id: \.id){ customer in
CellRow(customer: customer)
}
.onAppear() {
searchCustomer(criteria: "jose") { customers in
customerList = customers
}
}
}
}