在我调用requestWhenInUseAuthorization之前会触发位置权限对话框

问题描述

当我的视图出现时:

struct TurnOnLocation: View {
    
    var body: some View {
        ZStack {
            Color.orange
                .edgesIgnoringSafeArea(.all)
            vstack {
                Spacer()
                Image(systemName: "globe")
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .foregroundColor(.white)
                Spacer()

                Button(action: {
                    let locationManager = LocationManager()
                    locationManager.locationManager.requestWhenInUseAuthorization()
                    locationManager.locationManager.startUpdatingLocation()
                }) {
                    Text("Turn on location")
                }.foregroundColor(Color.black)
                .font(Font.system(size:22))
                .padding(20)
                .background(
                    Rectangle()
                        .fill(Color.white)
                        .border(Color.white,width:1)
                )
                .cornerRadius(50)
                .shadow(radius: 10)
                .padding(50)
            }
        }
    }
}

在点击Button之前,它会询问用户位置。为什么是这样?我在下方添加了要初始化的模型(应该在单击按钮时触发)。

class LocationManager: NSObject,ObservableObject {
    @Published var locationStatus: CLAuthorizationStatus? = CLAuthorizationStatus.notDetermined
    @Published var locationPermissionStatus = PermissionStatus.unkNown
    @Published var location: CLLocation?
    let locationManager = CLLocationManager()
    
    override init(){
        super.init()
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
    }
    
    enum PermissionStatus {
        case unkNown
        case authorizedWhenInUse
        case authorizedAlways
        case restricted
        case denied
    }
    
    func getLocation() -> CLLocationCoordinate2D? {
        return self.location?.coordinate
    }
    
}

您知道我如何确保仅在单击按钮后才显示对话框吗?

编辑:

我已更新代码

Button(action: {
    let locationManager = LocationManager()
    locationManager.requestPermission()
})

模型

class LocationManager: NSObject,ObservableObject,CLLocationManagerDelegate {
    @Published var locationStatus: CLAuthorizationStatus? = CLAuthorizationStatus.notDetermined
    @Published var locationPermissionStatus = PermissionStatus.unkNown
    @Published var location: CLLocation?
    let locationManager = CLLocationManager()
    
    override init(){
        super.init()
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    func requestPermission(){
        self.locationManager.requestWhenInUseAuthorization()
    }
    
    func locationManager(_ manager: CLLocationManager,didChangeAuthorization status: CLAuthorizationStatus) {   switch status {
          case .restricted,.denied:
             // disable your app's location features
            print("restricted")
             break
                
          case .authorizedWhenInUse:
             // Enable your app's location features.
            print("authorizedWhenInUse")
            self.locationManager.startUpdatingLocation()
             break
                
          case .authorizedAlways:
             // Enable or prepare your app's location features that can run any time.
            print("authorizedAlways")
            self.locationManager.startUpdatingLocation()
             break
                
          case .notDetermined:
            print("notDetermined")
             break
       }
    }

但是,当我单击按钮时,询问位置权限的对话框在一秒钟后消失了。知道为什么吗?

解决方法

有两件事要解决:

  1. 您已经在requestWhenInUseAuthorization中调用init,这就是构造按钮时看到警报的原因。您应该在requestWhenInUseAuthorization中删除init

  2. 确定已获得授权后,应在startUpdatingLocation中致电LocationManager

func locationManager(_ manager: CLLocationManager,didChangeAuthorization status: CLAuthorizationStatus) {
    switch status {
    case .authorizedAlways,.authorizedWhenInUse:
        manager.startUpdatingLocation()
    default:
        print("no auth")
    }
}
,

您正在使用LocationManager初始化方法请求授权。 您应该从init中删除该代码。

class LocationManager: NSObject,ObservableObject {
    @Published var locationStatus: CLAuthorizationStatus? = CLAuthorizationStatus.notDetermined
    @Published var locationPermissionStatus = PermissionStatus.unknown
    @Published var location: CLLocation?
    let locationManager = CLLocationManager()
    
    override init(){
        super.init()
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
    }

    func requestAuthorization() {
        self.locationManager.requestWhenInUseAuthorization()
    }

    func startUpdate() {
        self.locationManager.startUpdatingLocation()
    }
    
    enum PermissionStatus {
        case unknown
        case authorizedWhenInUse
        case authorizedAlways
        case restricted
        case denied
    }
    
    func getLocation() -> CLLocationCoordinate2D? {
        return self.location?.coordinate
    }
    
}

并在您看来:

struct TurnOnLocation: View {
    
    var body: some View {
        ZStack {
            Color.orange
                .edgesIgnoringSafeArea(.all)
            VStack {
                Spacer()
                Image(systemName: "globe")
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .foregroundColor(.white)
                Spacer()

                Button(action: {
                    let locationManager = LocationManager()
                    locationManager.requestAuthorization()
                    // you should check for authorization result first
                    locationManager.startUpdatingLocation()
                }) {
                    Text("Turn on location")
                }.foregroundColor(Color.black)
                .font(Font.system(size:22))
                .padding(20)
                .background(
                    Rectangle()
                        .fill(Color.white)
                        .border(Color.white,width:1)
                )
                .cornerRadius(50)
                .shadow(radius: 10)
                .padding(50)
            }
        }
    }
}
,

要解决1秒后消失的问题,请尝试按以下所示初始化位置管理:

struct TurnOnLocation: View {
    let locationManager = LocationManager() <- try to init location manager here

    var body: some View {
        ZStack {
            Color.orange
                .edgesIgnoringSafeArea(.all)
            VStack {
                Spacer()
                Image(systemName: "globe")
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .foregroundColor(.white)
                Spacer()

                Button(action: {   
                 locationManager.locationManager.requestWhenInUseAuthorization()
                    locationManager.locationManager.startUpdatingLocation()
                }) {
                    Text("Turn on location")
                }.foregroundColor(Color.black)
                .font(Font.system(size:22))
                .padding(20)
                .background(
                    Rectangle()
                        .fill(Color.white)
                        .border(Color.white,width:1)
                )
                .cornerRadius(50)
                .shadow(radius: 10)
                .padding(50)
            }
        }
    }
}