Je travaille avec Map Kit sous iOS 8 avec Obj-C NOT Swift. Je ne parviens pas à obtenir l'emplacement de l'appareil; il est défini sur 0.00, 0.00 et j'obtiens l'erreur suivante:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
J'ai implémenté: (j'ai essayé un à la fois et pas de chance)
if(IS_OS_8_OR_LATER) {
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
Et dans info.plist
NSLocationWhenInUseUsageDescription : App would like to use your location.
NSLocationAlwaysUsageDescription : App would like to use your location.
Je suis invité à autoriser l'application à utiliser ma position, mais une fois que je suis d'accord, rien ne change. L'emplacement est indiqué comme étant 0.00, 0.00.
Code pour afficher l'emplacement des utilisateurs:
//Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
Mike.
** EDIT: Voir la réponse ci-dessous.
Je l'ai fait travailler. J'ai posté mon code ci-dessous pour aider quiconque ayant des problèmes.
Voici mon code complet pour que la vue Carte de MapKit fonctionne dans iOS 8.
Dans votre AppName - Info.plist Ajoutez une nouvelle ligne avec le nom de la clé étant:
NSLocationWhenInUseUsageDescription
Ou
NSLocationAlwaysUsageDescription
La valeur étant une chaîne du message que vous souhaitez afficher:
YourAppName would like to use your location.
Dans votre fichier d'en-tête. (J'utilise Nom de l'application - Prefix.pch mais YourViewController.h fonctionnera aussi)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
YourViewController.h
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
@interface YourViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
}
@property(nonatomic, retain) IBOutlet MKMapView *mapView;
@property(nonatomic, retain) CLLocationManager *locationManager;
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(@"%@", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:@"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:@"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:@"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:@"%f", self.locationManager.location.altitude];
}
Prendre plaisir!
--Mike
Il n'est écrit nulle part, mais si votre application démarre avec MapKit, vous recevrez toujours le message d'erreur "Essayer de démarrer les mises à jour d'emplacement MapKit sans demander l'autorisation d'emplacement", même après avoir implémenté la réponse de MBarton. Pour l'éviter, vous devez créer un nouveau contrôleur de vue avant MapKit et y implémenter les délégués du gestionnaire d'emplacement. Je l'ai appelé AuthorizationController.
Donc, dans AuthorizationController.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface MCIAuthorizationController : UIViewController <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
Et dans AuthorizationController.m:
- (void)viewDidLoad {
[super viewDidLoad];
// Location manager
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];
}
}
#pragma mark - Location Manager delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSLog(@"didUpdateLocations: %@", [locations lastObject]);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"Location manager error: %@", error.localizedDescription);
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
[self performSegueWithIdentifier:@"startSegue" sender:self];
} else if (status == kCLAuthorizationStatusDenied) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location services not authorized"
message:@"This app needs you to authorize locations services to work."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
} else
NSLog(@"Wrong location status");
}
Essaye celui-là:
(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
self.mapView.showsUserLocation = YES;
}
J'ai eu le même problème mais l'ajout de ces deux lignes dans le fichier plist a résolu mes problèmes
NSLocationWhenInUseUsageDescription
Et
NSLocationAlwaysUsageDescription
REMARQUE: Doit fournir une description de chaîne de ces deux valeurs. Vous pouvez utiliser n'importe lequel d'entre eux dans votre fichier de contrôleur comme ci-dessous
self.locationManager= [[CLLocationManager alloc] init];
self.locationManager.delegate=self;
[self.locationManager requestAlwaysAuthorization];
Vous devez implémenter CLLOcationManagerDelegate
dans votre contrôleur pour accéder à cette fonctionnalité.
Votre code semble correct, bien qu'il ne soit pas nécessaire d'appeler requestWhenInUseAuthorization et l'autre requestAlwaysAuthorization, choisissez celui dont vous avez besoin.
Le code pour l’affichage des localisations est en train d’attribuer locationManager, ne vous attendez pas à obtenir des données de localisation instantanément.
vous devez attendre que la méthode déléguée soit appelée: -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
, alors self.locationManager.location sera également défini.
Suite à la réponse de Mikes, j’ai trouvé que l’utilisation de à la fois [self.locationManager requestWhenInUseAuthorization];
et [self.locationManager requestAlwaysAuthorization];
comme démontré dans son code ne fonctionne pas. Vous ne devriez utiliser que UN .
Je suppose que d'autres modifications ont été apportées à une version plus récente/stable de l'API.
Pour étendre la réponse acceptée et si vous créez un exemple de projet avec uniquement les fonctionnalités ci-dessus, mis à part les frameworks CoreLocation
et Mapkit
, vous devrez peut-être ajouter UIKit
, Foundation
et CoreGraphics
framework manuellement aussi dans Xcode 6
.