Toestemming voor locatieservice controleren op iOS

Hoe kan ik controleren of locatieservice is ingeschakeld voor mijn app?

Ik heb twee storyboards en ik wil de locatieservice controleren. Als de locatieservice is ingeschakeld voor mijn app, wil ik een kaart-storyboard met locatie starten. Anders wil ik nog een storyboard lanceren. Hoe kan ik programmatisch doen?


Antwoord 1, autoriteit 100%

Dit is de juiste.

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];
    }
}

Antwoord 2, autoriteit 20%

Getest op iOS 9.2

Voor het verkrijgen van locatie-updates moeten we altijd controleren

  • Locatieservices ingeschakeld op het iOS-apparaat van de gebruiker en
  • Locatieservices ingeschakeld voor bepaalde app

en de gebruiker starten op het juiste instellingenscherm om in te schakelen

Lanceer de pagina met locatie-instellingen voor iOS-apparaten

Stap.1 Ga naar Projectinstellingen –> Info –> URL-typen –> Nieuwe URL-schema’s toevoegen

Stap.2 Gebruik onderstaande code om de locatie-instellingenpagina van de telefoon te openen:
(Opmerking: het URL-schema is anders in iOS 10+, we controleren de versie zoals hier)

#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]];

Lanceer de pagina met locatie-instellingen voor apps

Gebruik onderstaande code om de locatie-instellingenpagina van de directe applicatie te openen

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

Hier is het volledige codevoorbeeld:

#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];
    }
}

Behandel de klik van de gebruiker en start de juiste locatie-instellingen

-(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
    }
}

Antwoord 3, autoriteit 15%

-(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];
        }
    }
 }

Reden hierachter, deze methode zal aanroepen wanneer uw service de locatieservice zal uitschakelen. deze code is nuttig voor mij.


Antwoord 4, autoriteit 9%

Controleer CLLocationManager’s locationServicesEnabledeigenschap om de systeembrede beschikbaarheid te controleren. Gebruik uw CLLocationManagerDelegate’s locationManager: didFailWithError:methode en controleer op een kCLErrorDenied-fout om te zien of de gebruiker locatieservices heeft geweigerd.

BOOL locationAllowed = [CLLocationManager locationServicesEnabled];
 if (!locationAllowed) 
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Service Disabled" 
                                                        message:@"To re-enable, please go to Settings and turn on Location Service for this app." 
                                                       delegate:nil 
                                              cancelButtonTitle:@"OK" 
                                              otherButtonTitles:nil];
        [alert show];
        [alert release];
}

gebruik deze code voor uw app

- (void)viewDidLoad
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    // Set a movement threshold for new events.
    locationManager.distanceFilter = 500;
    [locationManager startUpdatingLocation];
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations {
    // If it's a relatively recent event, turn off updates to save power
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"%@",error);
}

Als de locatieservice voor uw app is uitgeschakeld, krijgt u een foutmelding

Error Domain=kCLErrorDomain Code=1 "The operation couldn’t be completed. (kCLErrorDomain error 1.)"

Antwoord 5, autoriteit 9%

Bijgewerkt in de nieuwste Swift 5.0, Xcode 11.2.1

import UIKit
import CoreLocation

Gebruikersconstanten

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

Locatiemanager afgevaardigde voor het bewaken van locatiewijzigingen

@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
            }
        }
    }

Locatie-updates met autorisatiecontrole

   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()
        }
    }

Locatiewaarschuwing weergeven als toestemming niet is toegestaan

   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)")
    }
}

Voor het testen hierboven, schrijf deze regel code in je controller,

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

LocationManagerDelegate-methoden

extension ViewController: LocationManagerDelegate {
    func getLocation(location: CLLocation) {
        currentLocation = location.coordinate
    }
}

Antwoord 6, autoriteit 8%

Na veel onderzoek. Ik raad aan om dit bericht op een label weer te geven en niet in een waarschuwingsweergave. omdat er veel gevallen zijn om tegen te testen (gebruiker schakelt locatieservice in het algemeen uit of alleen voor app. app verwijderen, opnieuw installeren).

Een van deze gevallen zorgt ervoor dat uw waarschuwing tegelijkertijd uw bericht samen met het waarschuwingsbericht van Apple toont. uw waarschuwing bevindt zich achter de waarschuwing van Apple. wat een verwarrend en onlogisch gedrag is.

Ik raad het volgende aan:

Swift 3:

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    switch status {
        case .notDetermined:
            Log.verbose("User still thinking granting location access!")
            manager.startUpdatingLocation() // this will access location automatically if user granted access manually. and will not show apple's request alert twice. (Tested)
        break
        case .denied:
            Log.verbose("User denied location access request!!")
            // show text on label
            label.text = "To re-enable, please go to Settings and turn on Location Service for this app."
            manager.stopUpdatingLocation()
            loadingView.stopLoading()
        break
        case .authorizedWhenInUse:
            // clear text
            label.text = ""
            manager.startUpdatingLocation() //Will update location immediately
        break
        case .authorizedAlways:
            // clear text
            label.text = ""
            manager.startUpdatingLocation() //Will update location immediately
        break
        default:
            break
    }
}

Objective-c:

- (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    switch (status) {
        case kCLAuthorizationStatusNotDetermined: {
            DDLogVerbose(@"User still thinking granting location access!");
            [locationManager startUpdatingLocation]; // this will access location automatically if user granted access manually. and will not show apple's request alert twice. (Tested)
        } break;
        case kCLAuthorizationStatusDenied: {
            DDLogVerbose(@"User denied location access request!!");
            // show text on label
            label.text = @"To re-enable, please go to Settings and turn on Location Service for this app.";
            [locationManager stopUpdatingLocation];
            [loadingView stopLoading];
        } break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        case kCLAuthorizationStatusAuthorizedAlways: {
            // clear text
            label.text = @"";
            [locationManager startUpdatingLocation]; //Will update location immediately
        } break;
        default:
            break;
    }
}

Antwoord 7, Autoriteit 4%

de beste manier, omgaan met alle cases! – & GT;

//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
}

Antwoord 8, Autoriteit 2%


SWIFT 3.0 & AMP; iOS 10 Oplossing:


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

Other episodes