简体   繁体   中英

iOS Swift How to open Location Permission popup

var locMgr = INTULocationManager.sharedInstance()
    locMgr.requestLocation(withDesiredAccuracy: .city, timeout: 30, delayUntilAuthorized: true,block: {(currentLoc: CLLocation!, achievedAccuracy: INTULocationAccuracy, status: INTULocationStatus) -> Void in
        if status == INTULocationStatus.success {
        }
        else{
        }

Used INTULocationManager , Swift 4.1 , iOS 11.1

if first time run this code pop up Location Permission Request

but If I denied, this is not pop up next time.

how to open Permission Pop up?

i create Button

run this code

let locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.requestWhenInUseAuthorization()

but not worked

There isn't any default functionality which will popup the location permission once the user has denied the permission. You need to show an alert to the user that permission is required, and then redirect the user to Settings screen. Here's the complete code you can use. Define a function which will check the location permission.

    func hasLocationPermission() -> Bool {
        var hasPermission = false
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .notDetermined, .restricted, .denied:
                hasPermission = false
            case .authorizedAlways, .authorizedWhenInUse:
                hasPermission = true
            }
        } else {
            hasPermission = false
        }
        
        return hasPermission
    }

Now check location permission through this function and show alert if needed.

    if !hasLocationPermission() {
            let alertController = UIAlertController(title: "Location Permission Required", message: "Please enable location permissions in settings.", preferredStyle: UIAlertControllerStyle.alert)
            
            let okAction = UIAlertAction(title: "Settings", style: .default, handler: {(cAlertAction) in
                //Redirect to Settings app
                UIApplication.shared.open(URL(string:UIApplicationOpenSettingsURLString)!)
            })
            
            let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel)
            alertController.addAction(cancelAction)
            
            alertController.addAction(okAction)
            
            self.present(alertController, animated: true, completion: nil)
        }

Also don't forget to import CoreLocation .

Swift 5.3 and iOS 14 version

func hasLocationPermission() -> Bool {
    var hasPermission = false
    let manager = CLLocationManager()
    
    if CLLocationManager.locationServicesEnabled() {
        switch manager.authorizationStatus {
        case .notDetermined, .restricted, .denied:
            hasPermission = false
        case .authorizedAlways, .authorizedWhenInUse:
            hasPermission = true
        @unknown default:
                break
        }
    } else {
        hasPermission = false
    }
    
    return hasPermission
}

if !hasLocationPermission() {
    let alertController = UIAlertController(title: "Location Permission Required", message: "Please enable location permissions in settings.", preferredStyle: .alert)
    
    let okAction = UIAlertAction(title: "Settings", style: .default, handler: {(cAlertAction) in
        //Redirect to Settings app
        UIApplication.shared.open(URL(string:UIApplication.openSettingsURLString)!)
    })
    
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
    alertController.addAction(cancelAction)
    
    alertController.addAction(okAction)
    
    self.present(alertController, animated: true, completion: nil)
}

Swift 5

Once the user denies the permission then the alert is disabled for your app and will not show again. You can show popup to the user that permission is required.

Here's the complete code you can use

  if CLLocationManager.locationServicesEnabled() {
        switch CLLocationManager.authorizationStatus() {
        case .notDetermined, .restricted, .denied:
            showPermissionAlert()
        case .authorizedAlways, .authorizedWhenInUse:
            locationManager.startUpdatingLocation()
        }
    } else {
       locationManager.startUpdatingLocation()
    }

Now check location permission through this function and show alert if needed.

   func showPermissionAlert(){
    let alertController = UIAlertController(title: "Location Permission Required", message: "Please enable location permissions in settings.", preferredStyle: UIAlertController.Style.alert)

    let okAction = UIAlertAction(title: "Settings", style: .default, handler: {(cAlertAction) in
        //Redirect to Settings app
        UIApplication.shared.open(URL(string:UIApplication.openSettingsURLString)!)
    })

    let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel)
    alertController.addAction(cancelAction)

    alertController.addAction(okAction)

    self.present(alertController, animated: true, completion: nil)
}

if Permission deny by the user then open Permission PopUp

 /*  func checkLocation() {
    if CLLocationManager.authorizationStatus() != .authorizedWhenInUse
    {
        print("requesting autorization")
        locationManager.requestWhenInUseAuthorization()

    } else {
        print("start updating location")
    }
}*/

func askEnableLocationService() ->String {
    var showAlertSetting = false
    var showInitLocation = false
    if CLLocationManager.locationServicesEnabled() {
        switch CLLocationManager.authorizationStatus() {
        case .denied:
            showAlertSetting = true
            print("HH: kCLAuthorizationStatusDenied")
        case .restricted:
            showAlertSetting = true
            print("HH: kCLAuthorizationStatusRestricted")
        case .authorizedAlways:
            showInitLocation = true
            print("HH: kCLAuthorizationStatusAuthorizedAlways")
        case .authorizedWhenInUse:
            showInitLocation = true
            print("HH: kCLAuthorizationStatusAuthorizedWhenInUse")
        case .notDetermined:
            showInitLocation = true
            print("HH: kCLAuthorizationStatusNotDetermined")
        default:
            break
        }
    }else{
        showAlertSetting = true
        print("HH: locationServicesDisabled")

    }
    if showAlertSetting {
        let alertController = UIAlertController(title: "xxxxxx", message: "Please enable location service in the settings", preferredStyle: .alert)
        let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in



            if let url = URL(string: UIApplicationOpenSettingsURLString) {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            }

        }
        alertController.addAction(OKAction)
        self.window?.rootViewController?.present(alertController, animated: true, completion:nil)

    }
    if showInitLocation {

        return "YES"

    }
    return "NO"

}

That is default behavior. Once the popup is shown for the first time. The subsequent request will be treated as declined or whatever is selected on first select. However you can implement your own alert and send user directly to setting app to grant location access like below:

//check if user has denied the access on first popup
    if !permissionGranted {

        let permissionAlert = UIAlertController(title: "Location Access", message: "Requires location access to take advantage of this feature. Please provide location access from settings", preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
        let settingAction = UIAlertAction(title: "Settings", style: .default) { (action) in
            guard let appSettingURl = URL(string: UIApplicationOpenSettingsURLString) else { return }
            if UIApplication.shared.canOpenURL(appSettingURl) {
                UIApplication.shared.open(appSettingURl, options: [:], completionHandler: nil)
            }
        }
        permissionAlert.addAction(cancelAction)
        permissionAlert.addAction(settingAction)
        present(permissionAlert, animated: true, completion: nil)
    }

Complete Solution : (iOS 14+ and also for prior versions)

1)first get authorization status:-

func locationAuthorizationStatus() -> CLAuthorizationStatus {
        let locationManager = CLLocationManager()
        var locationAuthorizationStatus : CLAuthorizationStatus
        if #available(iOS 14.0, *) {
            locationAuthorizationStatus =  locationManager.authorizationStatus
        } else {
            // Fallback on earlier versions
            locationAuthorizationStatus = CLLocationManager.authorizationStatus()
        }
        return locationAuthorizationStatus
    }

2)Then check for location permission:-

func hasLocationPermission() -> Bool {
        var hasPermission = false
        let manager = self.locationAuthorizationStatus()
        
        if CLLocationManager.locationServicesEnabled() {
            switch manager {
            case .notDetermined, .restricted, .denied:
                hasPermission = false
            case .authorizedAlways, .authorizedWhenInUse:
                hasPermission = true
            @unknown default:
                    break
            }
        } else {
            hasPermission = false
        }
        
        return hasPermission
    }

3)Then show alert

if !hasLocationPermission() {
    let alertController = UIAlertController(title: "Location Permission Required", message: "Please enable location permissions in settings.", preferredStyle: .alert)
    
    let okAction = UIAlertAction(title: "Settings", style: .default, handler: {(cAlertAction) in
        //Redirect to Settings app
        UIApplication.shared.open(URL(string:UIApplication.openSettingsURLString)!)
    })
    
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
    alertController.addAction(cancelAction)
    
    alertController.addAction(okAction)
    
    self.present(alertController, animated: true, completion: nil)
}

CHEERS :) :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM