使用MVVM模式处理SwiftUI和CoreLocation

问题描述 投票:0回答:1

我正在尝试使用MVVM-Pattern实现SwiftUICoreLocation。我的LocationManager作为助手可以正常工作。但是,如何更改LocationViewModel的属性?我在@ObservedObject中实现了LocationManagerLocationViewModel。这是我的问题。

我不知道要实现它们随时更改的属性。我的LocationView中没有任何更改。通过按一个按钮,任何事情都可以正常工作一次。但是LocationViewModel必须在LocationManager的每次更改中更改其属性。

总而言之,我想显示当前用户位置。

// Location Manager as Helper

import Foundation
import CoreLocation

class LocationManager: NSObject, ObservableObject {

    let locationManager = CLLocationManager()
    let geoCoder = CLGeocoder()

    @Published var location: CLLocation?
    @Published var placemark: CLPlacemark?

    override init() {
        super.init()
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
    }

    func geoCode(with location: CLLocation) {

        geoCoder.reverseGeocodeLocation(location) { (placemark, error) in
            if error != nil {
                print(error!.localizedDescription)
            } else {
                self.placemark = placemark?.first
            }
        }
    }
}

extension LocationManager: CLLocationManagerDelegate {

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

        DispatchQueue.main.async {
            self.location = location
            self.geoCode(with: location)
        }

    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        // TODO
    }
}

// Location Model

import Foundation
import CoreLocation

struct Location {
    var location: CLLocation = CLLocation()
    var placemark: CLPlacemark = CLPlacemark()
}
// Location View Model

import SwiftUI
import CoreLocation

class LocationViewModel: ObservableObject {

    @ObservedObject var locationManager: LocationManager = LocationManager()

    @Published var location: Location

    init() {
        self.location = Location()
    }
}
// Location View

import SwiftUI

struct LocationView: View {

    @ObservedObject var locationViewModel: LocationViewModel = LocationViewModel()

    var body: some View {
        VStack(alignment: .leading) {
            Text("Latitude: \(self.locationViewModel.location.location.coordinate.latitude.description)")
            Text("Longitude: \(self.locationViewModel.location.location.coordinate.longitude.description)")
        }
    }
}

struct LocationView_Previews: PreviewProvider {
    static var previews: some View {
        LocationView()
    }
}
swift xcode mvvm swiftui core-location
1个回答
0
投票

实际上LocationViewModel在这里是多余的。由于LocationManagerObservableObject,因此可以在视图中直接使用它,如下所示:

struct LocationView: View {

    @ObservedObject var locationManager: LocationManager = LocationManager()

    var body: some View {
        VStack(alignment: .leading) {
            Text("Latitude: \(locationManager.location.coordinate.latitude.description)")
            Text("Longitude: \(locationManager.location.coordinate.longitude.description)")
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.