gpt4 book ai didi

ios - 如何等待分配另一个值来运行.onAppear?

转载 作者:行者123 更新时间:2023-12-01 21:18:25 25 4
gpt4 key购买 nike

我正在学习从头开始为 iOS 开发应用程序。我选择了 SwiftUI 来制作一个获取用户位置的应用程序,通过地理编码获取他所在的城市,并根据获得的信息,从 API 显示属于该城市的项目列表。
因此,我一方面学会了如何获取位置,另一方面学会了如何显示列表。我现在的问题是 w 当您运行 .onAppear(perform: loadData) 显示我的列表时,“城市”结果仍然为空 .显然,在我尝试显示城市列表后,获得了 city 的值。
我必须获得位置的算法和我必须显示列表的算法都单独工作。
所以我的代码是:

import SwiftUI

struct Response: Codable {
var cinemas: [Cinema]
}

struct Cinema: Codable {
var _id: String
var cinemaName: String
var cinemaCategory: String
}

struct HomeScreenView: View {

@State var results = [Cinema]()

@ObservedObject var lm = LocationManager()

var latitude: String {
return("\(lm.location?.latitude ?? 0)") }
var longitude: String { return("\(lm.location?.longitude ?? 0)") }
var placemark: String { return("\(lm.placemark?.description ?? "XXX")") }
var status: String { return("\(lm.status)") }

var city: String {
return("\(lm.placemark?.locality ?? "empty")")
}

var body: some View {
VStack {
List(results, id: \._id) { item in
VStack(alignment: .leading) {
Text(item.cinemaName)
.font(.headline)
Text(item.cinemaCategory)
}
}.onAppear(perform: loadData)
}

}

func loadData() {
guard let url = URL(string: "https://mycinemasapi.com/cinemasbycity/\(self.city)") else {
print("Invalid URL")
return
}

let request = URLRequest(url: url)

URLSession.shared.dataTask(with: request) { data, response, error in

if let data = data {
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
// we have good data – go back to the main thread
DispatchQueue.main.async {
// update our UI
self.results = decodedResponse.cinemas
}

// everything is good, so we can exit
return
}
}

// if we're still here it means there was a problem
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")

}.resume()
}
}
更新 :
位置管理器类
import Foundation
import CoreLocation
import Combine

class LocationManager: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
private let geocoder = CLGeocoder()
let objectWillChange = PassthroughSubject<Void, Never>()

@Published var status: CLAuthorizationStatus? {
willSet { objectWillChange.send() }
}

@Published var location: CLLocation? {
willSet { objectWillChange.send() }
}

override init() {
super.init()

self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}


@Published var placemark: CLPlacemark? {
willSet { objectWillChange.send() }
}

private func geocode() {
guard let location = self.location else { return }
geocoder.reverseGeocodeLocation(location, completionHandler: { (places, error) in
if error == nil {
self.placemark = places?[0]
} else {
self.placemark = nil
}
})
}
}

extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
self.status = status
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.location = location
self.geocode()
}
}

最佳答案

正如您的代码一样,只需在收到的地标上加载数据,例如

        List(results, id: \._id) { item in
VStack(alignment: .leading) {
Text(item.cinemaName)
.font(.headline)
Text(item.cinemaCategory)
}
}.onReceive(lm.$placemark) {
if $0 != nil {
self.loadData()
}
}

关于ios - 如何等待分配另一个值来运行.onAppear?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63964251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com