【问题标题】:Open SwiftUI view only if location permission granted仅在授予位置权限时打开 SwiftUI 视图
【发布时间】:2020-08-17 04:55:09
【问题描述】:

我有一个视图(比如 V),其中用户回答了几个问题并记录了他们的位置。但是,答案只对用户的位置有意义。

所以我想要的是,当用户点击父视图上的按钮时,它会将他们带到 V 并立即向他们询问位置权限。如果他们接受,他们可以继续回答问题,但如果他们拒绝,他们会导航回父屏幕。

我知道我可以使用self.presentation.wrappedValue.dismiss() 导航回父屏幕。

但是由于requestWhenInUseAuthorization() 是一个异步函数,我怎么知道用户何时接受或拒绝了权限?

我正在关注this 使用 Swift 在 iOS 上获取用户位置的教程。

我的 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
}

【问题讨论】:

    标签: ios swift swiftui


    【解决方案1】:

    CLLocationManagerDelegate还有如下方法:

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

    每次授权状态改变时都会调用该方法。我还想建议您将LocationService 实现为ObservableObject,而不是使用委托方法。

    【讨论】:

    • 为什么ObservableObject 方法会更好?
    • 因为 SwiftUI 中的 View 对象是 struct 并且使用 struct 作为委托不是一个好主意,因为它是值类型。例如,您可以在这里阅读:medium.com/tech-travelstart/…
    猜你喜欢
    • 2010-10-20
    • 2022-11-14
    • 2022-06-28
    • 2017-05-30
    • 2017-03-07
    • 1970-01-01
    • 2019-05-21
    • 2021-05-25
    • 1970-01-01
    相关资源
    最近更新 更多