Reputation: 175
Trying to get current location with using swiftUI. Below code, couldn't initialize with didUpdateLocations delegate.
class GetLocation : BindableObject {
var didChange = PassthroughSubject<GetLocation,Never>()
var location : CLLocation {
didSet {
didChange.send(self)
}
}
init() {}
}
Upvotes: 13
Views: 9155
Reputation: 429
I have written a one-file swift package with usage instructions on https://github.com/himbeles/LocationProvider. It provides a ObservableObject
-type wrapper class for CLLocationManager and its delegate.
There is a @Published
property location
which can directly be used in SwiftUI, as well as a PassthroughSubject<CLLocation, Never>
called locationWillChange
that you can subscribe to via Combine. Both update on every didUpdateLocations
event of the CLLocationManager
.
It also handles the case where location access has previously been denied: The default behavior is to present the user with a request to enable access in the app settings and a link to go there.
In SwiftUI (> iOS 14, > macOS 11), use 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()
}
}
}
}
Upvotes: 5
Reputation: 4490
This code below works (Not production ready). Implementing the CLLocationManagerDelegate
works fine and the lastKnownLocation
is updated accordingly.
Don't forget to set the NSLocationWhenInUseUsageDescription
in your 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()
}
}
}
Upvotes: 8
Reputation: 7168
As of Xcode 11 beta 4, you will need to change didChange
to willChange
:
var willChange = PassthroughSubject<LocationManager, Never>()
var lastKnownLocation: CLLocation? {
willSet {
willChange.send(self)
}
}
Upvotes: 3