iOS 8 Map Kit Obj-C无法获取用户位置

我正在使用Obj-C不SWIFT在iOS 8中使用Map Kit。 我不能得到设备的位置,它被设置为0.00,0.00,我得到的错误:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first. 

我已经执行:(我一次只尝试一次,没有运气)

 if(IS_OS_8_OR_LATER) { [self.locationManager requestWhenInUseAuthorization]; [self.locationManager requestAlwaysAuthorization]; } [self.locationManager startUpdatingLocation]; 

并在info.plist

 NSLocationWhenInUseUsageDescription : App would like to use your location. NSLocationAlwaysUsageDescription : App would like to use your location. 

我会得到提示,允许应用程序使用我的位置,但我同意没有任何更改。 位置显示为0.00,0.00。

用于显示用户位置的代码:

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

麦克风。

**编辑:查看下面的答案。

我得到了它的工作。 我已经发布了我的代码,以帮助其他人有问题。

这里是我的完整的代码来获取在iOS 8中的MapKit地图视图。

在你的AppName -Info.plist中添加一个新的行,其中的键名是:

 NSLocationWhenInUseUsageDescription 

要么

 NSLocationAlwaysUsageDescription 

值是要显示的消息的string:

 YourAppName would like to use your location. 

在你的头文件中。 (我使用App名称 -Prefix.pch,但YourViewController.h也可以)

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

请享用!

– 麦克风

它不是写在任何地方,但是如果你的应用程序以MapKit开头,即使在实现了MBarton的答案之后,仍然会收到错误消息“尝试启动MapKit位置更新而不提示位置授权”。 为了避免它,你必须在MapKit之前创build一个新的视图控制器,并在那里实现位置pipe理器委托。 我把它称为AuthorizationController。

所以,在AuthorizationController.h中:

 #import <UIKit/UIKit.h> #import <CoreLocation/CoreLocation.h> @interface MCIAuthorizationController : UIViewController <CLLocationManagerDelegate> @property (strong, nonatomic) CLLocationManager *locationManager; @end 

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

试试这个:

  (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { if (status == kCLAuthorizationStatusAuthorizedWhenInUse) { self.mapView.showsUserLocation = YES; } 

你的代码看起来很好,虽然你不需要调用requestWhenInUseAuthorization和其他requestAlwaysAuthorization,select一个你需要的。

显示位置的代码只是分配locationManager,不要期望立即获取位置数据。

你需要等待委托方法被调用: -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
,那么self.locationManager.location也将被设置。

对于Mikes的回答,我发现同时使用[self.locationManager requestWhenInUseAuthorization];[self.locationManager requestAlwaysAuthorization]; 如他的代码所示,这是行不通的。 你应该只使用一个

我假定一些更新的/稳定版本的API进行了一些更改。

我有同样的问题,但在plist文件中添加这两行解决了我的问题

 NSLocationWhenInUseUsageDescription 

 NSLocationAlwaysUsageDescription 

注:必须提供这两个值的string描述。 你可以在你的控制器文件中使用它们中的任何一个

 self.locationManager= [[CLLocationManager alloc] init]; self.locationManager.delegate=self; [self.locationManager requestAlwaysAuthorization]; 

您必须在控制器中实现CLLOcationManagerDelegate以访问此function

为了扩展已被接受的答案,并且如果您仅使用上述function创build示例项目,除了CoreLocationMapkit框架之外,您可能还需要在Xcode 6手动添加UIKitFoundationCoreGraphics框架。

其实,我正在研究CS193P第16讲,这个讲座是关于位置和地图视图的,我不能让位置pipe理员在iOS 8中工作,应用video中的内容。 看着你的答案,我可以使它工作。

Info.plist被修改为答案中所描述的(我使用NSLocationWhenInUseUsageDescription)。

在AddPhotoViewController.hn添加了定义:

 #define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) 

在AddPhotoViewController.m中,在ViewDidLoad(self.image之后)中添加了以下代码:

 #ifdef __IPHONE_8_0 if(IS_OS_8_OR_LATER) { [self.locationManager requestWhenInUseAuthorization]; } #endif 

第一次启动应用程序时,授权只会被询问一次。

AddPhotoViewController.h还添加了以下内容,因为在第16讲中没有提到:

 @property (nonatomic) NSInteger locationErrorCode; 

shouldPerformSegueWithIdentifier被修改为include else else(!self.location):

 else if (![self.titleTextField.text length]) { [self alert:@"Title required"]; return NO; } else if (!self.location) { switch (self.locationErrorCode) { case kCLErrorLocationUnknown: [self alert:@"Couldn't figure out where this photo was taken (yet)."]; break; case kCLErrorDenied: [self alert:@"Location Services disabled under Privacy in Settings application."]; break; case kCLErrorNetwork: [self alert:@"Can't figure out where this photo is being taken. Verify your connection to the network."]; break; default: [self alert:@"Cant figure out where this photo is being taken, sorry."]; break; } return NO; } else { // should check imageURL too to be sure we could write the file return YES; } 

didFailWithError被添加:

 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { self.locationErrorCode = error.code; }