最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

swift - CoreLocation .notDetermined how to trigger location permission request manually? - Stack Overflow

programmeradmin1浏览0评论

CoreLocation returns .notDetermined on Simulator even though Location Services are enabled, how can I manually trigger the authorization dialog?

In my Info.plist, I have added the necessary keys for location permissions.

eg: details about the questions ..........................................................................

import Foundation
import CoreLocation

@Observable
final class LocationManager: NSObject, CLLocationManagerDelegate {
   
   var locationManager = CLLocationManager()
   var authorizationStatus: CLAuthorizationStatus?
   var currentLocation: CLLocationCoordinate2D?
   
   override init() {
      super.init()
      locationManager.delegate = self
      locationManager.requestAlwaysAuthorization()
   }
   
   func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
      switch manager.authorizationStatus {
      case .authorizedWhenInUse:
         authorizationStatus = .authorizedWhenInUse
         locationManager.requestLocation()
         break
         
      case .restricted:
         authorizationStatus = .restricted
         break
         
      case .denied:
         authorizationStatus = .denied
         break
         
      case .notDetermined:
         print("location Manager: notDetermined")
         authorizationStatus = .notDetermined
         manager.requestAlwaysAuthorization()
         break
         
      default:
         break
      }
      
      print("location Manager: \(locationManager.authorizationStatus)")
   }
   
   func requestLocationPermission() {
      print("location Manager: \(locationManager.authorizationStatus)")
      locationManager.requestAlwaysAuthorization()
   }
   
   func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
      guard let newLocation = locations.first else { return }
      self.currentLocation = newLocation.coordinate
   }
   
   func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
      print("error: \(error.localizedDescription)")
   }
   
   func stopLocation() {
      locationManager.stopUpdatingLocation()
   }
   
}


VStack {
            switch appStateManager.locationManager.authorizationStatus {
            case .authorizedWhenInUse:
               Text("Your current location is:")
               Text("Latitude: \(appStateManager.locationManager.currentLocation?.latitude.description ?? "Error loading")")
               Text("Longitude: \(appStateManager.locationManager.currentLocation?.longitude.description ?? "Error loading")")
               
            case .restricted, .denied:
               Text("Current location data was restricted or denied.")
               Button("Open Settings") {
                  if let appSettings = URL(string: UIApplication.openSettingsURLString) {
                     UIApplication.shared.open(appSettings, options: [:], completionHandler: nil)
                  }
               }
            case .notDetermined:
               Text("Finding your location...")
               Button("Request Location Permission") {
                  appStateManager.locationManager.requestLocationPermission()
               }
               Button("Open Settings") {
                  if let appSettings = URL(string: UIApplication.openSettingsURLString) {
                     UIApplication.shared.open(appSettings, options: [:], completionHandler: nil)
                  }
               }
            default:
               ProgressView()
            }
         }


@main
struct SupartApp: App {
   @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
   @State private var appStateManager = AppStateManager()
   
   var body: some Scene {
      WindowGroup {
         RootView()
            .environment(appStateManager)
      }
   }
}

@Observable
class AppStateManager {
   var popupManager = PopupManager()
   var locationManager = LocationManager()
}

CoreLocation returns .notDetermined on Simulator even though Location Services are enabled, how can I manually trigger the authorization dialog?

In my Info.plist, I have added the necessary keys for location permissions.

eg: details about the questions ..........................................................................

import Foundation
import CoreLocation

@Observable
final class LocationManager: NSObject, CLLocationManagerDelegate {
   
   var locationManager = CLLocationManager()
   var authorizationStatus: CLAuthorizationStatus?
   var currentLocation: CLLocationCoordinate2D?
   
   override init() {
      super.init()
      locationManager.delegate = self
      locationManager.requestAlwaysAuthorization()
   }
   
   func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
      switch manager.authorizationStatus {
      case .authorizedWhenInUse:
         authorizationStatus = .authorizedWhenInUse
         locationManager.requestLocation()
         break
         
      case .restricted:
         authorizationStatus = .restricted
         break
         
      case .denied:
         authorizationStatus = .denied
         break
         
      case .notDetermined:
         print("location Manager: notDetermined")
         authorizationStatus = .notDetermined
         manager.requestAlwaysAuthorization()
         break
         
      default:
         break
      }
      
      print("location Manager: \(locationManager.authorizationStatus)")
   }
   
   func requestLocationPermission() {
      print("location Manager: \(locationManager.authorizationStatus)")
      locationManager.requestAlwaysAuthorization()
   }
   
   func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
      guard let newLocation = locations.first else { return }
      self.currentLocation = newLocation.coordinate
   }
   
   func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
      print("error: \(error.localizedDescription)")
   }
   
   func stopLocation() {
      locationManager.stopUpdatingLocation()
   }
   
}


VStack {
            switch appStateManager.locationManager.authorizationStatus {
            case .authorizedWhenInUse:
               Text("Your current location is:")
               Text("Latitude: \(appStateManager.locationManager.currentLocation?.latitude.description ?? "Error loading")")
               Text("Longitude: \(appStateManager.locationManager.currentLocation?.longitude.description ?? "Error loading")")
               
            case .restricted, .denied:
               Text("Current location data was restricted or denied.")
               Button("Open Settings") {
                  if let appSettings = URL(string: UIApplication.openSettingsURLString) {
                     UIApplication.shared.open(appSettings, options: [:], completionHandler: nil)
                  }
               }
            case .notDetermined:
               Text("Finding your location...")
               Button("Request Location Permission") {
                  appStateManager.locationManager.requestLocationPermission()
               }
               Button("Open Settings") {
                  if let appSettings = URL(string: UIApplication.openSettingsURLString) {
                     UIApplication.shared.open(appSettings, options: [:], completionHandler: nil)
                  }
               }
            default:
               ProgressView()
            }
         }


@main
struct SupartApp: App {
   @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
   @State private var appStateManager = AppStateManager()
   
   var body: some Scene {
      WindowGroup {
         RootView()
            .environment(appStateManager)
      }
   }
}

@Observable
class AppStateManager {
   var popupManager = PopupManager()
   var locationManager = LocationManager()
}
Share Improve this question edited Feb 21 at 7:59 Ehz uiq asked Feb 21 at 5:41 Ehz uiqEhz uiq 515 bronze badges 4
  • can you show what your appStateManager is, and how you pass it to the view – workingdog support Ukraine Commented Feb 21 at 6:57
  • Thanks for your response! I've added the relevant details about appStateManager and how it's passed to the view. – Ehz uiq Commented Feb 21 at 8:03
  • I recommend doing authorization and location updates from separate View structs, thus 2 managers and 2 delegate objects. – malhal Commented Feb 21 at 12:18
  • AFAIK, you don't have to do anything special to ask for permissions, they will appear by themself when you launch the App. – workingdog support Ukraine Commented Feb 22 at 8:14
Add a comment  | 

1 Answer 1

Reset to default 0

You have to request when in use before always

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
  switch manager.authorizationStatus {
  case .authorizedWhenInUse:
     authorizationStatus = .authorizedWhenInUse
              manager.requestAlwaysAuthorization()
     locationManager.requestLocation()
     break
     
  case .restricted:
     authorizationStatus = .restricted
     break
     
  case .denied:
     authorizationStatus = .denied
     break
     
  case .notDetermined:
     print("location Manager: notDetermined")
     authorizationStatus = .notDetermined
              manager.requestWhenInUseAuthorization()
     break
     
  default:
     break
  }
  
  print("location Manager: \(locationManager.authorizationStatus)")

}

Also init is too early so request authorization it us better to use onAppear or task, sometimes you need to add a small delay.

                  manager.requestWhenInUseAuthorization()
发布评论

评论列表(0)

  1. 暂无评论