我见过类似的问题,但没有一个是最新的或成功的,我已经遵循了苹果开发者文档,各种视频,和指南如何做到这一点,但它仍然抛出这些警告2023-01-11 11:33:16.044044-0500 Walkman[50986:4824621] [SwiftUI] Publishing changes from within view updates is not allowed, this will cause undefined behavior.
感觉我已经尝试了从onChange()到@StateObject而不是@ObservedObject的所有方法...这是因为如果Map被注解掉,警告就会消失。
导致错误的代码是
struct OrderView: View {
@ObservedObject var cartManager: CartManager
// @ObservedObject var locationManager: LocationManager
@EnvironmentObject var locationManager: LocationManager
@EnvironmentObject var viewModel: AppViewModel
@State private var tracking:MapUserTrackingMode = .follow
@State private var driversIn: Bool = false
var body: some View {
NavigationView {
// Text("Testing")
Map(
coordinateRegion: $locationManager.region,
interactionModes: MapInteractionModes.all,
showsUserLocation: true,
userTrackingMode: $tracking,
annotationItems: locationManager.MapLocations,
annotationContent: { item in
MapMarker(coordinate: item.coordinate, tint: .red)
// MapAnnotation(coordinate: item.location) {
// Rectangle()
// .stroke(Color.purple, lineWidth: 3)
// .frame(width: 10, height: 10)
// }
}
)
.navigationTitle("Orders")
.onAppear {
locationManager.getNearbyDrivers(query: GeoQuery(distance: 400, geo: locationManager.createGeo()))
}
.ignoresSafeArea()
// .onReceive(locationManager.$drivers, perform: { drivers in
//// print("DEBUG: DRIVERS _ \(drivers)")
// for driver in drivers {
// print("DEBUG: DRIVER TEST _ \(driver)")
// locationManager.MapLocations.append(MapLocation(id: driver.id, name: driver.name, latitude: driver.location.coordinates[0], longitude: driver.location.coordinates[1]))
// }
// })
}
}
}
这是我的位置管理器
final class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {
@Published var region = MKCoordinateRegion(center: MapDetails.startingLocation, span: MapDetails.defaultSpan)
@Published var authorizationStatus: CLAuthorizationStatus?
@Published var location: CLLocation?
@Published var MapLocations = [MapLocation]()
@Published var drivers = [Driver]()
var locationManager = CLLocationManager()
override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedWhenInUse:
authorizationStatus = .authorizedWhenInUse
manager.startUpdatingLocation()
break
case .restricted, .denied:
authorizationStatus = .restricted
manager.stopUpdatingLocation()
break
case .notDetermined:
authorizationStatus = .notDetermined
manager.requestWhenInUseAuthorization()
break
default:
break
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
DispatchQueue.main.async {
self.location = location
// self.MapLocations.append(MapLocation(name: "1", latitude: location.coordinate.latitude, longitude: location.coordinate.longitude))
// MARK - API for location calls, send when users location updates
print("DEBUG: Location: \(self.location?.coordinate.longitude ?? 0.00)")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("DEBUG: \(error.localizedDescription)")
}
func createGeo() -> GeoJSON {
return GeoJSON(coordinates: [locationManager.location?.coordinate.latitude ?? 0.00, locationManager.location?.coordinate.longitude ?? 0.00])
}
func getNearbyDrivers(query: GeoQuery) {
guard let url = URL(string: "http://localhost:8000/drivers-nearby") else { fatalError("Missing URL") }
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let payload: [String: Any] = [
"distance": query.distance,
"geo": ["type": "Point", "coordinates": query.geo.coordinates]
]
let data = try! JSONSerialization.data(withJSONObject: payload, options: [])
request.httpBody = data
let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Request error: ", error)
return
}
guard let response = response as? HTTPURLResponse else { return }
if response.statusCode == 200 {
guard let data = data else { return }
DispatchQueue.main.async {
do {
let drivers = try JSONDecoder().decode([Driver].self, from: data)
print("DEBUG: Drivers: \(drivers)")
self.drivers = drivers
for driver in self.drivers {
let location = MapLocation(id: driver.id, name: driver.name, latitude: driver.location.coordinates[0], longitude: driver.location.coordinates[1])
var driverIsVisible: Bool {
return self.MapLocations.contains(where: { annotation in
guard var driverAnno = annotation as? MapLocation else { return false }
print("DEBUG: cast driverAnno | driverAnno \(driverAnno.id) | driver \(driver.id)")
if driverAnno.id == driver.id {
print("DEBUG: Handle update driver position")
driverAnno.latitude = driver.location.coordinates[0]
driverAnno.longitude = driver.location.coordinates[1]
return true
}
return false
})
}
if !driverIsVisible {
print("DEBUG: Inserting map annotation \(location.id)")
self.MapLocations.append(location)
}
}
} catch let error {
print("Error decoding: ", error)
}
}
}
}
dataTask.resume()
}
//// private func geocode() {
//// guard let location = self.location else { return }
//// geocoder.reverseGeocodeLocation(location) { (places, error) in
//// if error == nil {
//// self.placemark = places?[0]
//// } else {
//// self.placemark = nil
//// }
//// }
//// }
}
1条答案
按热度按时间uttx8gqw1#
从LocationManager中的区域删除@Published将修复此警告。