Открывайте вид SwiftUI, только если предоставлено разрешение на местоположение - PullRequest
0 голосов
/ 02 мая 2020

У меня есть представление (скажем, V), в котором пользователь отвечает на несколько вопросов, и его местоположение записывается. Однако ответы имеют смысл только для местоположения пользователя.

Итак, я хочу, чтобы, когда пользователь нажимает кнопку в родительском представлении, он переводил их в V и немедленно запрашивал разрешение на местоположение. Если они соглашаются, они могут продолжать отвечать на вопросы, но если они отказываются, они возвращаются к родительскому экрану.

Я знаю, что могу вернуться к родительскому экрану с помощью self.presentation.wrappedValue.dismiss().

Но как мне узнать, когда пользователь принял или отклонил разрешение, поскольку requestWhenInUseAuthorization() является асинхронной функцией?

Я следую этому руководству по получению местоположения пользователя в iOS со Swift.

Код для моего LocationService:

import CoreLocation

protocol LocationServiceDelegate {
    func didFetchCurrentLocation(_ location: GeoLocation)
    func fetchCurrentLocationFailed(error: Error)
}

class LocationService: NSObject, CLLocationManagerDelegate {
    let locationManager = CLLocationManager()

    var delegate: LocationServiceDelegate

    init(delegate: LocationServiceDelegate) {
        self.delegate = delegate
        super.init()
        self.setupLocationManager()
    }

    private func setupLocationManager() {
        if canUseLocationManager() {
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
        }
    }

    func requestLocation() {
        if canUseLocationManager() {
            print(CLAuthorizationStatus.self)
            locationManager.requestWhenInUseAuthorization()
            locationManager.requestLocation()
        }
    }

    func requestPermission() {
        locationManager.requestWhenInUseAuthorization()
    }

    private func canUseLocationManager() -> Bool {
        return CLLocationManager.locationServicesEnabled()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print(locations)
        if let location = locations.last {
            let geoLocation = GeoLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
            delegate.didFetchCurrentLocation(geoLocation)
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error)
        delegate.fetchCurrentLocationFailed(error: error)
    }

    deinit {
        locationManager.stopUpdatingLocation()
    }
}

struct GeoLocation {
    var latitude: Double
    var longitude: Double
}

1 Ответ

0 голосов
/ 02 мая 2020

CLLocationManagerDelegate также имеет следующий метод:

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

Этот метод вызывается каждый раз, когда изменяется статус авторизации. Я также хотел бы порекомендовать вам реализовать LocationService как ObservableObject вместо использования делегатского подхода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...