Checking location service permission on iOS

前端 未结 8 1779
有刺的猬
有刺的猬 2020-12-07 12:32

How can I check if location service is enabled for my app?

I have 2 storyboards and I want to check location service. If location service enabled for my app, I want

相关标签:
8条回答
  • 2020-12-07 12:38

    This is the correct.

    if ([CLLocationManager locationServicesEnabled]){
    
        NSLog(@"Location Services Enabled");
    
        if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
            alert = [[UIAlertView alloc] initWithTitle:@"App Permission Denied"     
                                               message:@"To re-enable, please go to Settings and turn on Location Service for this app." 
                                              delegate:nil 
                                     cancelButtonTitle:@"OK" 
                                     otherButtonTitles:nil];
            [alert show];
        }
    }
    
    0 讨论(0)
  • 2020-12-07 12:49

    Tested on iOS 9.2

    For getting location updates we should always check

    • Location services enabled on user's iOS Device and
    • Location services enabled for particular app

    and launching user on correct settings screen to enable

    Launch iOS Device Location Settings page

    Step.1 Go to Project settings --> Info --> URL Types --> Add New URL Schemes

    Step.2 Use below code to launch direct phone's location settings page: (Note: The URL Scheme is different in iOS 10+, we check the version as stated here)

     #define SYSTEM_VERSION_LESS_THAN(v)  ([[[UIDevice 
     currentDevice] systemVersion] compare:v options:NSNumericSearch] == 
     NSOrderedAscending)
    
     //Usage
    NSString* url = SYSTEM_VERSION_LESS_THAN(@"10.0") ? @"prefs:root=LOCATION_SERVICES" : @"App-Prefs:root=Privacy&path=LOCATION";
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
    

    Launch Application Location Settings page

    Use below code to launch direct application's location settings page

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    

    Here is the full code example :

    #define SYSTEM_VERSION_LESS_THAN(v)  ([[[UIDevice 
     currentDevice] systemVersion] compare:v options:NSNumericSearch] == 
     NSOrderedAscending)
    
    
    CLLocationManager *locationManager;
    
    -(void) checkLocationServicesAndStartUpdates
    {
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate = self;
        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    
        if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])
        {
            [locationManager requestWhenInUseAuthorization];
        }
    
        //Checking authorization status
        if (![CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
        {
    
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled!"
                                                                message:@"Please enable Location Based Services for better results! We promise to keep your location private"
                                                               delegate:self
                                                      cancelButtonTitle:@"Settings"
                                                      otherButtonTitles:@"Cancel", nil];
    
            //TODO if user has not given permission to device
            if (![CLLocationManager locationServicesEnabled])
            {
                alertView.tag = 100;
            }
            //TODO if user has not given permission to particular app
            else
            {
                alertView.tag = 200;
            }
    
            [alertView show];
    
            return;
        }
        else
        {
            //Location Services Enabled, let's start location updates
            [locationManager startUpdatingLocation];
        }
    }
    

    Handle the user click respone, and launch correct location settings

    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
    
        if(buttonIndex == 0)//Settings button pressed
        {
            if (alertView.tag == 100)
            {
                //This will open ios devices location settings
                NSString* url = SYSTEM_VERSION_LESS_THAN(@"10.0") ? @"prefs:root=LOCATION_SERVICES" : @"App-Prefs:root=Privacy&path=LOCATION";
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
            }
            else if (alertView.tag == 200)
            {
                //This will opne particular app location settings
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
            }
        }
        else if(buttonIndex == 1)//Cancel button pressed.
        {
            //TODO for cancel
        }
    }
    
    0 讨论(0)
  • 2020-12-07 12:50

    Swift 3.0 & iOS 10 Solution:


    self.locationManager?.requestWhenInUseAuthorization()
    if CLLocationManager.locationServicesEnabled() && CLLocationManager.authorizationStatus() != CLAuthorizationStatus.denied {
                locationManager?.delegate = self
                locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation
                locationManager?.distanceFilter = distanceFiler
                locationManager?.startUpdatingLocation()
            }else{
                let alertView = UIAlertView(title: "Location Services Disabled!", message: "Please enable Location Based Services for better results! We promise to keep your location private", delegate: self, cancelButtonTitle: "Settings", otherButtonTitles: "Cancel")
                alertView.delegate = self
                alertView.show()
                return
            }
    
    
    @objc(alertView:clickedButtonAtIndex:) func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) {
        if buttonIndex == 0 {
                if let url = URL(string: "App-Prefs:root=LOCATION_SERVICES") {
                    UIApplication.shared.open(url, completionHandler: .none)
                }
        }
        else if buttonIndex == 1 {
            //TODO for cancel
        }
    
    }
    
    0 讨论(0)
  • 2020-12-07 12:54

    The best way, handling all cases! ->

    //First, checking if the location services are enabled
    if(![CLLocationManager locationServicesEnabled]){
        [self showMessage:@"Please enable location services to detect location!" withTitle:@"Location not enabled"];
    }
    else if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
        //Now if the location is denied.
        UIAlertController *alertController = [UIAlertController
                                              alertControllerWithTitle:@"Enable location permission"
                                              message:@"To auto detect location, please enable location services for this app"
                                              preferredStyle:UIAlertControllerStyleAlert];
    
        alertController.view.tintColor = AppColor;
        UIAlertAction *cancelAction = [UIAlertAction
                                       actionWithTitle:@"Dismiss"
                                       style:UIAlertActionStyleCancel
                                       handler:^(UIAlertAction *action)
                                       {
                                            NSLog(@"Cancel action");
                                       }];
    
        UIAlertAction *goToSettings = [UIAlertAction
                                    actionWithTitle:@"Settings"
                                    style:UIAlertActionStyleDefault
                                    handler:^(UIAlertAction *action)
                                    {
                                        //Simple way to open settings module
                                        NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                                        [[UIApplication sharedApplication] openURL:url];
                                    }];
    
        [alertController addAction:cancelAction];
        [alertController addAction:goToSettings];
        [self presentViewController:alertController animated:YES completion:^{
            alertController.view.tintColor = AppColor;
        }];
    }
    else{
        //Do whatever you want here
    }
    
    0 讨论(0)
  • 2020-12-07 12:55

    Updated in Latest Swift 5.0, Xcode 11.2.1

    import UIKit
    import CoreLocation
    

    User constants

    struct UserConstants {
        static let latitude = "latitude"
        static let longitude = "longitude"
        static let lastKnownLatitude = "lastKnownLatitude"
        static let lastKnownLongitude = "lastKnownLongitude"
    }
    

    Location Manager Delegate for monitoring location changes

    @objc protocol LocationManagerDelegate {
        @objc optional func getLocation(location: CLLocation)
    }
    
    class LocationHelper: NSObject, CLLocationManagerDelegate {
    
        weak var locationManagerDelegate: LocationManagerDelegate?
        var isLocationfetched: Bool = false
        var lastKnownLocation: CLLocation? {
            get {
                let latitude = UserDefaults.standard.double(forKey: UserConstants.lastKnownLatitude)
                let longitude = UserDefaults.standard.double(forKey: UserConstants.lastKnownLongitude)
    
                if latitude.isZero || longitude.isZero {
                    return nil
                }
                return CLLocation(latitude: latitude, longitude: longitude)
            }
            set {
                UserDefaults.standard.set(newValue?.coordinate.latitude ?? 0, forKey: UserConstants.lastKnownLatitude)
                UserDefaults.standard.set(newValue?.coordinate.longitude ?? 0, forKey: UserConstants.lastKnownLongitude)
                UserDefaults.standard.synchronize()
            }
        }
    
        struct SharedInstance {
            static let instance = LocationHelper()
        }
    
        class var shared: LocationHelper {
            return SharedInstance.instance
        }
    
        enum Request {
            case requestWhenInUseAuthorization
            case requestAlwaysAuthorization
        }
    
        var clLocationManager = CLLocationManager()
    
        func setAccuracy(clLocationAccuracy: CLLocationAccuracy) {
            clLocationManager.desiredAccuracy = clLocationAccuracy
        }
    
        var isLocationEnable: Bool = false {
            didSet {
                if !isLocationEnable {
                    lastKnownLocation = nil
                }
            }
        }
    

    Location updates with authorization check

        func startUpdatingLocation() {
            isLocationfetched = false
            if CLLocationManager.locationServicesEnabled() {
                switch CLLocationManager.authorizationStatus() {
                case .notDetermined:
                    clLocationManager.delegate = self
                    clLocationManager.requestWhenInUseAuthorization()
                    clLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
                    clLocationManager.startUpdatingLocation()
                    isLocationEnable = true
                case .restricted, .denied:
                    showLocationAccessAlert()
                    isLocationEnable = false
                case .authorizedAlways, .authorizedWhenInUse:
                    self.clLocationManager.delegate = self
                    self.clLocationManager.startUpdatingLocation()
                    isLocationEnable = true
                default:
                    print("Invalid AuthorizationStatus")
                }
            } else {
                isLocationEnable = false
                showLocationAccessAlert()
            }
        }
    

    Show location alert if permission is not allowed

        func showLocationAccessAlert() {
            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
                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
            })
            let cancelAction = UIAlertAction(title: "cancel", style: UIAlertAction.Style.cancel)
            alertController.addAction(cancelAction)
            alertController.addAction(okAction)
            let appdelegate = UIApplication.shared.delegate as? AppDelegate
            appdelegate?.window?.rootViewController?.present(alertController, animated: true, completion: nil)
        }
    
        func stopUpdatingLocation() {
            self.clLocationManager.stopUpdatingLocation()
        }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            if !isLocationfetched {
                isLocationfetched = true
                clLocationManager.startMonitoringSignificantLocationChanges()
                NotificationCenter.default.post(name: NSNotification.Name.updateLocationNotification, object: nil)
            }
            let userLocation = locations[0] as CLLocation
            self.lastKnownLocation = userLocation
            if let delegate = self.locationManagerDelegate {
                delegate.getLocation!(location: userLocation)
            }
        }
    
        func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
            if (status == CLAuthorizationStatus.denied) {
                // The user denied authorization
                isLocationEnable = false
            } else if (status == CLAuthorizationStatus.authorizedWhenInUse) {
                // The user accepted authorization
                self.clLocationManager.delegate = self
                self.clLocationManager.startUpdatingLocation()
                isLocationEnable = true
            }
        }
    
        func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
            print("\n error description for location updation:- \(error.localizedDescription)")
        }
    
    }
    

    For testing above, just write these line of code in your controller,

    LocationHelper.shared.locationManagerDelegate = self
    LocationHelper.shared.startUpdatingLocation()
    

    LocationManagerDelegate Methods

    extension ViewController: LocationManagerDelegate {
    
        func getLocation(location: CLLocation) {
            currentLocation = location.coordinate
        }
    
    }
    
    0 讨论(0)
  • 2020-12-07 12:57
    -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    
        NSLog(@"%@",error.userInfo);
        if([CLLocationManager locationServicesEnabled]){
    
            NSLog(@"Location Services Enabled");
    
            if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
             UIAlertView    *alert = [[UIAlertView alloc] initWithTitle:@"App Permission Denied"
                                                   message:@"To re-enable, please go to Settings and turn on Location Service for this app."
                                                  delegate:nil
                                         cancelButtonTitle:@"OK"
                                         otherButtonTitles:nil];
                [alert show];
            }
        }
     }
    

    Reason behind this, this method will call when your service will be disable the location service. this code is useful for me.

    0 讨论(0)
提交回复
热议问题