Mijn app die prima werkte op iOS 7, werkt niet met de iOS 8 SDK.
CLLocationManager
retourneert geen locatie en ik zie mijn app niet onder Instellingen-> Locatieservicesook niet. Ik heb op Google gezocht naar het probleem, maar er kwam niets uit. Wat kan er aan de hand zijn?
Antwoord 1, autoriteit 100%
Ik heb uiteindelijk mijn eigen probleem opgelost.
Blijkbaar in iOS 8 SDK, requestAlwaysAuthorization
(voor achtergrondlocatie) of requestWhenInUseAuthorization
(locatie alleen op voorgrond) is aanroep van CLLocationManager
nodig voordat locatie-updates starten.
Er moet ook NSLocationAlwaysUsageDescription
of NSLocationWhenInUseUsageDescription
-sleutel zijn in Info.plist
met een bericht dat in de prompt moet worden weergegeven. Door deze toe te voegen is mijn probleem opgelost.
Voor meer uitgebreide informatie, kijk op: Core-Location-Manager-Changes-in-ios-8
Antwoord 2, autoriteit 29%
Ik trok mijn haar uit met hetzelfde probleem. Xcode geeft je de fout:
Proberen
MapKit
locatie-updates te starten zonder te vragen om
locatie autorisatie. Moet-[CLLocationManager
of
requestWhenInUseAuthorization]-[CLLocationManager
eerst.
requestAlwaysAuthorization]
Maar zelfs als u een van de bovenstaande methoden implementeert, wordt de gebruiker niet gevraagd tenzij er een vermelding in de info.plist is voor NSLocationAlwaysUsageDescription
of NSLocationWhenInUseUsageDescription
.
Voeg de volgende regels toe aan uw info.plist waarbij de tekenreekswaarden de reden vertegenwoordigen die u nodig heeft om toegang te krijgen tot de gebruikerslocatie
<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>
Ik denk dat deze items mogelijk ontbreken sinds ik dit project in Xcode 5 begon. Ik vermoed dat Xcode 6 standaarditems voor deze sleutels zal toevoegen, maar ik heb dit niet bevestigd.
Meer informatie over deze twee instellingen vindt u hier
Antwoord 3, autoriteit 10%
Om ervoor te zorgen dat dit achterwaarts compatibel is met iOS 7, moet u controleren of de gebruiker iOS 8 of iOS 7 gebruikt. Bijvoorbeeld:
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
//In ViewDidLoad
if(IS_OS_8_OR_LATER) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
Antwoord 4, autoriteit 5%
- (void)startLocationManager
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager requestWhenInUseAuthorization]; // Add This Line
}
En naar uw info.plist-bestand
Antwoord 5, autoriteit 3%
Volgens de Apple-documenten:
- https://developer.apple.com/documentation/corelocation/requesting_permission_to_use_location_services
- https://developer.apple.com/documentation/corelocation/cllocationmanager /1620562-requestwheninuseautorisatie
Vanaf iOS 8 is de aanwezigheid van een NSLocationWhenInUseUsageDescription
– of een NSLocationAlwaysUsageDescription
-sleutelwaarde in het Info.plist-bestand van uw app vereist. Het is dan ook nodig om toestemming van de gebruiker te vragen voordat hij zich registreert voor locatie-updates, hetzij door [self.myLocationManager requestWhenInUseAuthorization]
of [self.myLocationManager requestAlwaysAuthorization]
te bellen, afhankelijk van uw behoefte. De tekenreeks die u in Info.plist heeft ingevoerd, wordt vervolgens weergegeven in het volgende dialoogvenster.
Als de gebruiker toestemming geeft, is het ‘business as usual’. Als ze toestemming weigeren, wordt de gemachtigde niet op de hoogte gebracht van locatie-updates.
Antwoord 6, autoriteit 3%
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
NSUInteger code = [CLLocationManager authorizationStatus];
if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
// choose one request according to your business.
if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
[self.locationManager requestAlwaysAuthorization];
} else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
[self.locationManager requestWhenInUseAuthorization];
} else {
NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
}
}
}
[self.locationManager startUpdatingLocation];
}
> #pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError: %@", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"didUpdateToLocation: %@", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
}
}
In iOS 8 moet je twee extra dingen doen om de locatie werkend te krijgen: Toevoegen
een sleutel tot uw Info.plist en autorisatie aanvragen bij de locatie
manager vraagt om te starten. Er zijn twee Info.plist-sleutels voor de nieuwe
locatie autorisatie. Een of beide van deze sleutels is vereist. Als
geen van de sleutels is aanwezig, u kunt startUpdatingLocation bellen maar
de locatiemanager start niet echt. Het stuurt geen mislukking
bericht aan de afgevaardigde (aangezien het nooit is gestart, kan het niet)
mislukking). Het zal ook mislukken als u een of beide sleutels toevoegt, maar vergeet
uitdrukkelijk toestemming vragen. Dus het eerste wat je moet doen
is om een of beide van de volgende sleutels toe te voegen aan uw Info.plist-bestand:
- NSLocationWhenInUseUsageDescription
- NSLocationAlwaysUsageDescription
Beide toetsen hebben een string
wat een beschrijving is van waarom u locatieservices nodig heeft. Jij kan
voer een string in zoals “Locatie is vereist om te weten waar je bent”
die, net als in iOS 7, kan worden gelokaliseerd in het InfoPlist.strings-bestand.
Antwoord 7, autoriteit 2%
Mijn oplossing die kan worden gecompileerd in Xcode 5:
#ifdef __IPHONE_8_0
NSUInteger code = [CLLocationManager authorizationStatus];
if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
// choose one request according to your business.
if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
[self.locationManager requestAlwaysAuthorization];
} else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
[self.locationManager requestWhenInUseAuthorization];
} else {
NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
}
}
#endif
[self.locationManager startUpdatingLocation];
Antwoord 8, autoriteit 2%
De oude code voor het vragen naar de locatie werkt niet in iOS 8. U kunt deze methode voor locatieautorisatie proberen:
- (void)requestAlwaysAuthorization
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
// If the status is denied or only granted for when in use, display an alert
if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusDenied) {
NSString *title;
title = (status == kCLAuthorizationStatusDenied) ? @"Location services are off" : @"Background location is not enabled";
NSString *message = @"To use background location you must turn on 'Always' in the Location Services Settings";
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Settings", nil];
[alertView show];
}
// The user has not enabled any location services. Request background authorization.
else if (status == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1) {
// Send the user to the Settings for this app
NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:settingsURL];
}
}
Antwoord 9
In iOS 8 moet je twee extra dingen doen om de locatie werkend te krijgen: voeg een sleutel toe aan je Info.plist en vraag autorisatie aan bij de locatiemanager en vraag deze om te starten
info.plist:
<key>NSLocationUsageDescription</key>
<string>I need location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I need location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>I need location</string>
Voeg dit toe aan je code
if (IS_OS_8_OR_LATER)
{
[locationmanager requestWhenInUseAuthorization];
[locationmanager requestAlwaysAuthorization];
}
10
Een veelvoorkomende fout voor Swift ontwikkelaars:
Ten eerste zorg ervoor dat u een waarde toe te voegen aan de plist voor zowel NSLocationWhenInUseUsageDescription
of NSLocationAlwaysUsageDescription
.
Als u nog niet het zien van een pop-up venster te vragen om toestemming, kijk om te zien of u zetten de lijn var locationManager = CLLocationManager()
in uw View Controller’s viewDidLoad
methode. Als je dat doet, dan is zelfs als je belt locationManager.requestWhenInUseAuthorization()
, niets zal verschijnen. Dit komt omdat na viewDidLoad uitvoert, de locationManager variabele deallocated (leeggehaald).
De oplossing is om de lijn te vinden var locationManager = CLLocationManager()
boven de klassenmethode.
11
Oplossing met achterwaartse compatibiliteit die geen Xcode-waarschuwingen produceert:
SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
[self.locationManager respondsToSelector:requestSelector]) {
((void (*)(id, SEL))[self.locationManager methodForSelector:requestSelector])(self.locationManager, requestSelector);
[self.locationManager startUpdatingLocation];
} else {
[self.locationManager startUpdatingLocation];
}
Setup NSLocationWhenInUseUsageDescription
-sleutel in uw Info.plist
.
Voor iOS-versie 11.0+:
Stel de sleutel NSLocationAlwaysAndWhenInUseUsageDescription
in uw Info.plist
in. samen met andere 2 sleutels.
Antwoord 12
Dit is een probleem met ios 8
Voeg dit toe aan je code
if (IS_OS_8_OR_LATER)
{
[locationmanager requestWhenInUseAuthorization];
[locationmanager requestAlwaysAuthorization];
}
en naar info.plist:
<key>NSLocationUsageDescription</key>
<string>I need location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I need location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>I need location</string>
Antwoord 13
Om toegang te krijgen tot de gebruikerslocatie in iOS 8 moet je toevoegen,
NSLocationAlwaysUsageDescription in the Info.plist
Hiermee wordt de gebruiker om toestemming gevraagd om zijn huidige locatie te verkrijgen.
Antwoord 14
Doelstelling-C-procedure
Volg de onderstaande instructies:
Voor iOS-11
Bekijk voor iOS 11 dit antwoord: iOS 11 locatietoegang
Moet twee sleutels aan plist toevoegen en een bericht geven zoals onderstaande afbeelding:
1. NSLocationAlwaysAndWhenInUseUsageDescription
2. NSLocationWhenInUseUsageDescription
3. NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
[locationManager requestWhenInUseAuthorization];
}else{
[locationManager startUpdatingLocation];
}
Methoden delegeren
#pragma mark - Lolcation Update
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError: %@", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
case kCLAuthorizationStatusRestricted:
case kCLAuthorizationStatusDenied:
{
// do some error handling
}
break;
default:{
[locationManager startUpdatingLocation];
}
break;
}
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations lastObject];
userLatitude = [NSString stringWithFormat:@"%f", location.coordinate.latitude] ;
userLongitude = [NSString stringWithFormat:@"%f",location.coordinate.longitude];
[locationManager stopUpdatingLocation];
}
Snelle procedure
Volg de onderstaande instructies:
Voor iOS-11
Bekijk voor iOS 11 dit antwoord: iOS 11 locatietoegang
Moet twee sleutels aan plist toevoegen en een bericht geven zoals onderstaande afbeelding:
1. NSLocationAlwaysAndWhenInUseUsageDescription
2. NSLocationWhenInUseUsageDescription
3. NSLocationAlwaysUsageDescription
import CoreLocation
class ViewController: UIViewController ,CLLocationManagerDelegate {
var locationManager = CLLocationManager()
//MARK- Update Location
func updateMyLocation(){
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){
locationManager.requestWhenInUseAuthorization()
}
else{
locationManager.startUpdatingLocation()
}
}
Delegeermethoden
//MARK: Location Update
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
NSLog("Error to update location :%@",error)
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .NotDetermined: break
case .Restricted: break
case .Denied:
NSLog("do some error handling")
break
default:
locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last! as CLLocation
var latitude = location.coordinate.latitude
var longitude = location.coordinate.longitude
}
Antwoord 15
Voor degenen die Xamaringebruikten, moest ik de sleutel NSLocationWhenInUseUsageDescription
handmatig aan de info.plist toevoegen omdat deze niet beschikbaar was in de vervolgkeuzelijsten in Xamarin 5.5.3 Build 6 of XCode 6.1 – alleen NSLocationUsageDescription
stond in de lijst, en dat zorgde ervoor dat de CLLocationManager
stil bleef mislukken.
Antwoord 16
// ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
// Location Manager Delegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}
Antwoord 17
Een kleine hulp voor iedereen die meer dan één Info.plist-bestand heeft…
find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Add NSLocationWhenInUseUsageDescription string' {}
Het voegt de benodigde tag toe aan alle Info.plist-bestanden in de huidige map (en submappen).
Een andere is:
find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION' {}
Het zal je beschrijving aan alle bestanden toevoegen.
Antwoord 18
Houd informatie over Cocoa Keysaltijd binnen handbereik voor die updates, hier is de link:
Veel plezier.
Antwoord 19
Ik krijg een soortgelijke fout in iOS9 (werkt met Xcode 7 en Swift 2):
Ik probeer MapKit-locatie-updates te starten zonder om locatieautorisatie te vragen. Moet eerst -[CLLocationManager requestWhenInUseAuthorization] of -[CLLocationManager requestAlwaysAuthorization] aanroepen.
Ik volgde een tutorial, maar de tutor gebruikte iOS8 en Swift 1.2. Er zijn enkele wijzigingen in Xcode 7 en Swift 2, ik heb deze code gevonden en het werkt prima voor mij (als iemand hulp nodig heeft):
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
// MARK: Properties
@IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
}
// MARK: - Location Delegate Methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
self.mapView.setRegion(region, animated: true)
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Errors: " + error.localizedDescription)
}
}
Tot slot heb ik dat in info.plist gezet:
Informatie Eigenschappenlijst: NSLocationWhenInUseUsageDescription
Waarde: App heeft locatieservers nodig voor personeel
Antwoord 20
Om toegang te krijgen tot de gebruikerslocatie in iOS. U moet twee sleutels toevoegen
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
in het Info.plist-bestand.
<key>NSLocationWhenInUseUsageDescription</key>
<string>Because I want to know where you are!</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Want to know where you are!</string>
Zie deze afbeelding hieronder.
Antwoord 21
-
Toevoegen sleutel
NSLocationWhenInUseUsageDescription
ofNSLocationAlwaysUsageDescription
(gps-gebruik op de achtergrond) met string die vraagt om gps te gebruiken op elkeInfo.plist
van elk doel. -
Vraag om toestemming door het volgende uit te voeren:
[self initLocationManager:locationManager];
Waar initLocationManager
is:
// asks for GPS authorization on iOS 8
-(void) initLocationManager:(CLLocationManager *) locationManager{
locationManager = [[CLLocationManager alloc]init];
if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
[locationManager requestAlwaysAuthorization];
}
Houd er rekening mee dat als de sleutels niet op elke Info.plist
voor elk doel staan, de app de gebruiker hier niet om zal vragen. De if
biedt compatibiliteit met iOS 7 en de respondsToSelector:
-methode garandeert toekomstige compatibiliteit in plaats van alleen het probleem op te lossen voor iOS 7 en 8.
Antwoord 22
Het probleem voor mij was dat de klasse die de CLLocationManagerDelegate
was, privé was, wat verhinderde dat alle gedelegeerde methoden werden aangeroepen. Ik denk dat het niet een veel voorkomende situatie is, maar ik dacht ik meld het even voor het geval iemand er iets aan heeft.
Antwoord 23
Ik voeg die sleutel toe in InfoPlist.strings
in iOS 8.4, iPad mini 2.Het werkt ook. Ik stel geen enkele sleutel in, zoals NSLocationWhenInUseUsageDescription
, in mijn Info.plist
.
InfoPlist.strings:
"NSLocationWhenInUseUsageDescription" = "I need GPS information....";
Basis op deze thread, zei het, as in iOS 7
, kan worden gelokaliseerd in de InfoPlist.strings. In mijn test kunnen die sleutels direct in het bestand InfoPlist.strings
worden geconfigureerd.
Dus het eerste dat u hoeft te doen, is een of beide > volgende sleutels voor uw Info.plist-bestand:
- NSLocationWhenInUseUsageDescription
- NSLocationAlwaysUsageDescription
Beide toetsen hebben een string die een beschrijving is van waarom je
locatiediensten nodig hebben. U kunt een tekenreeks invoeren zoals “Locatie is
vereist om erachter te komen waar je bent’, wat, zoals in iOS 7, kan zijn
gelokaliseerd in het InfoPlist.strings-bestand.
UPDATE:
Ik denk dat @IOS
‘s methode beter is.Sleutel toevoegen aan Info.plist
met lege waarde en voeg gelokaliseerde tekenreeksen toe aan InfoPlist.strings
.