如何使用SwiftUI获取当前位置?

Gör*_*dın 7 cllocation swiftui

尝试使用swiftUI获取当前位置。下面的代码无法使用didUpdateLocations委托初始化。

class GetLocation : BindableObject {
    var didChange = PassthroughSubject<GetLocation,Never>()

    var location : CLLocation {
        didSet {
            didChange.send(self)
        }
    }
    init() {}
}
Run Code Online (Sandbox Code Playgroud)

Vik*_*art 5

下面的代码有效(未准备好生产)。执行CLLocationManagerDelegate工作正常,并相应地lastKnownLocation更新。

不要忘记NSLocationWhenInUseUsageDescription在你的Info.plist

class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    private let manager = CLLocationManager()
    var lastKnownLocation: CLLocation?

    func startUpdating() {
        manager.delegate = self
        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print(locations)
        lastKnownLocation = locations.last
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedWhenInUse {
            manager.startUpdatingLocation()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于任何收到错误的人:使用未解析的标识符“PassthroughSubject”,请确保将“导入组合”添加到文件顶部。 (2认同)

lsr*_*ggr 5

我在https://github.com/himbeles/LocationProvider上编写了一个包含使用说明的单文件 swift 包。它ObservableObject为 CLLocationManager 及其委托提供了一个类型包装类。有一个可以直接在 SwiftUI 中使用的@Published属性location,以及一个可以通过合并订阅的PassthroughSubject<CLLocation, Never>调用。locationWillChange两者都会更新 的每个didUpdateLocations事件CLLocationManager

它还可以处理位置访问先前被拒绝的情况:默认行为是向用户提供在应用程序设置中启用访问的请求以及前往该位置的链接。

在 SwiftUI(> iOS 14、> macOS 11)中,使用 as

import SwiftUI
import LocationProvider

struct ContentView: View {
    @StateObject var locationProvider = LocationProvider()
    
    var body: some View {
        VStack{
            Text("latitude \(locationProvider.location?.coordinate.latitude ?? 0)")
            Text("longitude \(locationProvider.location?.coordinate.longitude ?? 0)")
        }
        .onAppear {
            do {try locationProvider.start()} 
            catch {
                print("No location access.")
                locationProvider.requestAuthorization()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)