web-dev-qa-db-fra.com

Comment obtenir la position actuelle avec SwiftUI?

Essayer d'obtenir l'emplacement actuel en utilisant swiftUI. Sous le code, impossible d'initialiser avec le délégué didUpdateLocations.

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

    var location : CLLocation {
        didSet {
            didChange.send(self)
        }
    }
    init() {}
}
9
Görkem Aydın

Ce code ci-dessous fonctionne (pas prêt pour la production). L'implémentation de CLLocationManagerDelegate fonctionne correctement et le lastKnownLocation est mis à jour en conséquence.

N'oubliez pas de définir le NSLocationWhenInUseUsageDescription dans votre Info.plist

class LocationManager: NSObject, CLLocationManagerDelegate, BindableObject {
    private let manager: CLLocationManager
    var didChange = PassthroughSubject<LocationManager, Never>()

    var lastKnownLocation: CLLocation? {
        didSet {
            didChange.send(self)
        }
    }

    init(manager: CLLocationManager = CLLocationManager()) {
        self.manager = manager
        super.init()
    }

    func startUpdating() {
        self.manager.delegate = self
        self.manager.requestWhenInUseAuthorization()
        self.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()
        }
    }
}
5
Viktor Gardart

À partir de Xcode 11 beta 4, vous devrez remplacer didChange par willChange:

var willChange = PassthroughSubject<LocationManager, Never>()

var lastKnownLocation: CLLocation? {
    willSet {
        willChange.send(self)
    }
}
3
MwcsMac

J'ai écrit un fichier unique Swift avec des instructions d'utilisation sur https://github.com/himbeles/LocationProvider . Il fournit un ObservableObject de type wrapper pour CLLocationManager et son délégué. Il existe une propriété publiée location qui peut être directement utilisée dans SwiftUI, ainsi qu'un PassthroughSubject auquel vous pouvez vous abonner via Combine. Les deux sont mis à jour sur chaque didUpdateLocations événement du CLLocationManager.

Il gère également le cas où l'accès à l'emplacement a été précédemment refusé: le comportement par défaut consiste à présenter à l'utilisateur une demande d'activation de l'accès dans les paramètres de l'application et un lien pour y accéder.

Dans SwiftUI, utilisez comme

import SwiftUI
import LocationProvider

struct ContentView: View {
    @ObservedObject var locationProvider : LocationProvider

    init() {
        locationProvider = LocationProvider()
        do {try locationProvider.start()} 
        catch {
            print("No location access.")
            locationProvider.requestAuthorization()
        }
    }

    var body: some View {
        VStack{
        Text("latitude \(locationProvider.location?.coordinate.latitude ?? 0)")
        Text("longitude \(locationProvider.location?.coordinate.longitude ?? 0)")
        }
    }
}
0
lsrggr