正在尝试显示 API 个要查看的结果
Trying to display API results to View
我的 API 调用完成后,正在尝试在视图中显示文本。我想我会在数据加载后将我想要的 API 结果 (foodDescription) 保存到一个变量,然后在视图中显示该变量。
我的猜测是我在 api 调用之前加载视图(或者我可能完全不相信我的猜测)。我也觉得我使用 DispatchQueue 不正确,也很乐意提供反馈。提前谢谢你。
API呼叫
class FoodApiSearch{
var foodDescription = ""
//will search for user Input
func searchFood(userItem: String){
//calls api search
guard let url = URL(string: "https://api.nal.usda.gov/fdc/v1/foods/search?query=\(userItem)&dataType=&pageSize=1&pageNumber=1&api_key=*****") else {return}
URLSession.shared.dataTask(with: url) { (data, _,_) in
let searchResults = try! JSONDecoder().decode(APISearchResults.self, from: data!)
DispatchQueue.main.async {
for item in searchResults.foods{
self.foodDescription = item.foodDescription ?? "food not valid"
print(self.foodDescription)
}
}
}
.resume()
}
}
结构
struct testA: View {
//Textfield
@State var userFoodInput = ""
//will store api var of foodName
@State var foodName = ""
var body: some View {
VStack{
TextField("enter first name", text: $userFoodInput)
Button("click me"){
//action
FoodApiSearch().searchFood(userItem: userFoodInput)
foodName = FoodApiSearch().foodDescription
}
Text("You searched for " + foodName)
}
}
}
因为 searchFood
是异步的,您不能只在后续行上分配 foodName = FoodApiSearch().foodDescription
并期望它 return 得到正确的结果。还有另一个问题:您正在创建 FoodApiSearch
的两个不同实例(每次键入 FoodApiSearch()
都是一个新实例)。
您可能希望将 FoodApiSearch
变成 ObservableObject
和 @Published
属性。看起来像这样:
class FoodApiSearch : ObservableObject {
@Published var foodDescription = ""
func searchFood(userItem: String) {
然后,您在 View
中使用 @StateObject
存储它的 单个实例 ,如果要显示结果,请使用 @Published
变量 -- 不要试图将它分配给本地变量 @State
:
struct TestA: View {
@State private var userFoodInput = ""
@StateObject private var foodApi = FoodApiSearch()
var body: some View {
VStack{
TextField("enter first name", text: $userFoodInput)
Button("click me") {
foodApi.searchFood(userItem: userFoodInput)
}
if !foodApi.foodDescription.isEmpty {
Text(foodApi.foodDescription)
}
}
}
}
我的 API 调用完成后,正在尝试在视图中显示文本。我想我会在数据加载后将我想要的 API 结果 (foodDescription) 保存到一个变量,然后在视图中显示该变量。
我的猜测是我在 api 调用之前加载视图(或者我可能完全不相信我的猜测)。我也觉得我使用 DispatchQueue 不正确,也很乐意提供反馈。提前谢谢你。
API呼叫
class FoodApiSearch{
var foodDescription = ""
//will search for user Input
func searchFood(userItem: String){
//calls api search
guard let url = URL(string: "https://api.nal.usda.gov/fdc/v1/foods/search?query=\(userItem)&dataType=&pageSize=1&pageNumber=1&api_key=*****") else {return}
URLSession.shared.dataTask(with: url) { (data, _,_) in
let searchResults = try! JSONDecoder().decode(APISearchResults.self, from: data!)
DispatchQueue.main.async {
for item in searchResults.foods{
self.foodDescription = item.foodDescription ?? "food not valid"
print(self.foodDescription)
}
}
}
.resume()
}
}
结构
struct testA: View {
//Textfield
@State var userFoodInput = ""
//will store api var of foodName
@State var foodName = ""
var body: some View {
VStack{
TextField("enter first name", text: $userFoodInput)
Button("click me"){
//action
FoodApiSearch().searchFood(userItem: userFoodInput)
foodName = FoodApiSearch().foodDescription
}
Text("You searched for " + foodName)
}
}
}
因为 searchFood
是异步的,您不能只在后续行上分配 foodName = FoodApiSearch().foodDescription
并期望它 return 得到正确的结果。还有另一个问题:您正在创建 FoodApiSearch
的两个不同实例(每次键入 FoodApiSearch()
都是一个新实例)。
您可能希望将 FoodApiSearch
变成 ObservableObject
和 @Published
属性。看起来像这样:
class FoodApiSearch : ObservableObject {
@Published var foodDescription = ""
func searchFood(userItem: String) {
然后,您在 View
中使用 @StateObject
存储它的 单个实例 ,如果要显示结果,请使用 @Published
变量 -- 不要试图将它分配给本地变量 @State
:
struct TestA: View {
@State private var userFoodInput = ""
@StateObject private var foodApi = FoodApiSearch()
var body: some View {
VStack{
TextField("enter first name", text: $userFoodInput)
Button("click me") {
foodApi.searchFood(userItem: userFoodInput)
}
if !foodApi.foodDescription.isEmpty {
Text(foodApi.foodDescription)
}
}
}
}