ios 不允许从MAP()视图更新中发布更改,这将导致未定义的行为

sqxo8psd  于 2023-01-18  发布在  iOS
关注(0)|答案(1)|浏览(141)

我见过类似的问题,但没有一个是最新的或成功的,我已经遵循了苹果开发者文档,各种视频,和指南如何做到这一点,但它仍然抛出这些警告
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
////            }
////        }
////    }
}
uttx8gqw

uttx8gqw1#

从LocationManager中的区域删除@Published将修复此警告。

相关问题